From 08c9101d363b3b5e6724e55d0801a4408bfc424f Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Mon, 11 May 2020 14:06:44 +0200 Subject: [PATCH] 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) --- src/msg/async/ProtocolV2.cc | 18 +++++++++++++++--- src/msg/async/ProtocolV2.h | 2 ++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/msg/async/ProtocolV2.cc b/src/msg/async/ProtocolV2.cc index 304581a6e0551..8d7149203769a 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 07ce037337032..052174a6f5e2e 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(); -- 2.39.5