Skip to content

Commit ebca7d0

Browse files
issue: 4082058 Fixing return from rx_wait_helper without data
In case poll_and_process_element_rx polled packets without draining the CQ but m_n_rx_pkt_ready_list_count==0, meaning no data bytes were received, we need to return positive return code, to make the caller call us again. Returning EAGAIN without draining the CQ will make the caller return EGAIAN as well, and so up to the application, although packets are still available in the CQ. This can happen, for example, if the polling received only ACK packets. Returning EAGAIN in this case is incorrect. Callers may decide falsly to go to sleep. Signed-off-by: Alexander Grissik <[email protected]>
1 parent 43a8115 commit ebca7d0

File tree

1 file changed

+4
-3
lines changed

1 file changed

+4
-3
lines changed

src/core/sock/sockinfo_tcp.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5096,8 +5096,9 @@ int sockinfo_tcp::rx_wait_helper(int &poll_count, bool blocking)
50965096
// It can be too expansive for the application to get nothing just because of lock contention.
50975097
// In this case it will be better to have a lock() version of poll_and_process_element_rx.
50985098
// And then we should continue polling untill we have ready packets or we drained the CQ.
5099+
bool all_drained = true;
50995100
if (likely(m_p_rx_ring)) {
5100-
m_p_rx_ring->poll_and_process_element_rx(&poll_sn);
5101+
all_drained = m_p_rx_ring->poll_and_process_element_rx(&poll_sn);
51015102
} else { // There's more than one CQ, go over each one
51025103
for (rx_ring_iter = m_rx_ring_map.begin(); rx_ring_iter != m_rx_ring_map.end();
51035104
rx_ring_iter++) {
@@ -5106,13 +5107,13 @@ int sockinfo_tcp::rx_wait_helper(int &poll_count, bool blocking)
51065107
continue;
51075108
}
51085109

5109-
rx_ring_iter->first->poll_and_process_element_rx(&poll_sn);
5110+
all_drained &= rx_ring_iter->first->poll_and_process_element_rx(&poll_sn);
51105111
}
51115112
}
51125113
m_rx_ring_map_lock.unlock();
51135114
lock_tcp_con(); // We must take a lock before checking m_n_rx_pkt_ready_list_count
51145115

5115-
if (likely(m_n_rx_pkt_ready_list_count)) { // got completions from CQ
5116+
if (likely(m_n_rx_pkt_ready_list_count || !all_drained)) { // Got completions from CQ
51165117
__log_entry_funcall("Ready %d packets. sn=%llu", m_n_rx_pkt_ready_list_count,
51175118
(unsigned long long)poll_sn);
51185119
IF_STATS(m_p_socket_stats->counters.n_rx_poll_hit++);

0 commit comments

Comments
 (0)