From: Ilya Dryomov Date: Mon, 11 May 2020 12:06:44 +0000 (+0200) Subject: msg/async/ProtocolV2: short circuit empty segments and epilogue X-Git-Tag: v15.2.5~164^2~5 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=64f7ad7e20192f6546b717bcb76a6f502effdcdd;p=ceph.git msg/async/ProtocolV2: short circuit empty segments and epilogue In both msgr2.0 and msgr2.1, segments can be empty. In msgr2.1, epilogue can be empty as well. Handle both by calling the respective handler function directly instead of allocating a buffer::ptr_node for an empty buffer and passing that through READ[_RXBUF]. Signed-off-by: Ilya Dryomov (cherry picked from commit e6e3563d07181da043c0f8a7417c7a592af0c298) --- diff --git a/src/msg/async/ProtocolV2.cc b/src/msg/async/ProtocolV2.cc index 3aa75f6dbbea..7dad64510dea 100644 --- a/src/msg/async/ProtocolV2.cc +++ b/src/msg/async/ProtocolV2.cc @@ -1148,9 +1148,12 @@ CtPtr ProtocolV2::read_frame_segment() { rx_segments_data.emplace_back(); uint32_t onwire_len = rx_frame_asm.get_segment_onwire_len(seg_idx); - uint16_t align = rx_frame_asm.get_segment_align(seg_idx); + if (onwire_len == 0) { + return _handle_read_frame_segment(); + } rx_buffer_t rx_buffer; + uint16_t align = rx_frame_asm.get_segment_align(seg_idx); try { rx_buffer = buffer::ptr_node::create(buffer::create_aligned( onwire_len, align)); @@ -1176,11 +1179,17 @@ CtPtr ProtocolV2::handle_read_frame_segment(rx_buffer_t &&rx_buffer, int r) { } rx_segments_data.back().push_back(std::move(rx_buffer)); + return _handle_read_frame_segment(); +} +CtPtr ProtocolV2::_handle_read_frame_segment() { if (rx_segments_data.size() == rx_frame_asm.get_num_segments()) { // OK, all segments planned to read are read. Can go with epilogue. - return READ(rx_frame_asm.get_epilogue_onwire_len(), - handle_read_frame_epilogue_main); + uint32_t epilogue_onwire_len = rx_frame_asm.get_epilogue_onwire_len(); + if (epilogue_onwire_len == 0) { + return _handle_read_frame_epilogue_main(); + } + return READ(epilogue_onwire_len, handle_read_frame_epilogue_main); } // TODO: for makeshift only. This will be more generic and throttled return read_frame_segment(); @@ -1284,7 +1293,10 @@ CtPtr ProtocolV2::handle_read_frame_epilogue_main(rx_buffer_t &&buffer, int r) } rx_epilogue.push_back(std::move(buffer)); + return _handle_read_frame_epilogue_main(); +} +CtPtr ProtocolV2::_handle_read_frame_epilogue_main() { bool aborted; try { rx_frame_asm.disassemble_first_segment(rx_preamble, rx_segments_data[0]); diff --git a/src/msg/async/ProtocolV2.h b/src/msg/async/ProtocolV2.h index c4aa6b9c5b60..3a6792451060 100644 --- a/src/msg/async/ProtocolV2.h +++ b/src/msg/async/ProtocolV2.h @@ -169,7 +169,9 @@ private: Ct *handle_read_frame_preamble_main(rx_buffer_t &&buffer, int r); Ct *read_frame_segment(); Ct *handle_read_frame_segment(rx_buffer_t &&rx_buffer, int r); + Ct *_handle_read_frame_segment(); Ct *handle_read_frame_epilogue_main(rx_buffer_t &&buffer, int r); + Ct *_handle_read_frame_epilogue_main(); Ct *handle_read_frame_dispatch(); Ct *handle_frame_payload();