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: v14.2.11~8^2~5 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=08c9101d363b3b5e6724e55d0801a4408bfc424f;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 304581a6e055..8d7149203769 100644 --- a/src/msg/async/ProtocolV2.cc +++ b/src/msg/async/ProtocolV2.cc @@ -1139,9 +1139,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)); @@ -1167,11 +1170,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(); @@ -1275,7 +1284,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 07ce03733703..052174a6f5e2 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();