Skip to content

Commit

Permalink
tcp: Recover from iob shortage with TCP_WRITE_BUFFERS
Browse files Browse the repository at this point in the history
When CONFIG_NET_TCP_WRITE_BUFFERS is enabled, iobs are used for
both queuing data from application, and for assembling packets
for sending. If there is a system-wide shortage of iobs, it could
happen that there is not enough free space to form any packets
to send. The buffers allocated for TCP data also can't be released
until the packet is sent.

Normally this should be avoided by setting suitable values for
CONFIG_IOB_NBUFFERS and CONFIG_IOB_THROTTLE. The default values
are ok for light usage, but can run out when using multiple
simultaneous TCP streams.

Before this commit, iob shortage would cause TCP connections to
get stuck and eventually timeout. With this change, TCP stack
sends smaller packets, eventually freeing some buffers from the
write queue.
  • Loading branch information
PetteriAimonen authored and xiaoxiang781216 committed Dec 16, 2023
1 parent 87c1b81 commit 06e5b66
Showing 1 changed file with 16 additions and 0 deletions.
16 changes: 16 additions & 0 deletions net/tcp/tcp_send_buffered.c
Original file line number Diff line number Diff line change
Expand Up @@ -1022,6 +1022,22 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev,
sndlen = remaining_snd_wnd;
}

/* Normally CONFIG_IOB_THROTTLE should ensure that we have enough
* iob space available for copying the data to a packet buffer.
* If it doesn't, a deadlock could happen where the iobs are used
* by queued TX data and cannot be released because a full-sized
* packet gets refused by devif_iob_send(). Detect this situation
* and send tiny TCP packets until we manage to free up some space.
* We do not want to exhaust all of the remaining iobs by sending
* the maximum size packet that would fit.
*/

if (sndlen > iob_navail(false) * CONFIG_IOB_BUFSIZE)
{
nwarn("Running low on iobs, limiting packet size\n");
sndlen = CONFIG_IOB_BUFSIZE;
}

ninfo("SEND: wrb=%p seq=%" PRIu32 " pktlen=%u sent=%u sndlen=%zu "
"mss=%u snd_wnd=%u seq=%" PRIu32
" remaining_snd_wnd=%" PRIu32 "\n",
Expand Down

0 comments on commit 06e5b66

Please sign in to comment.