This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 06e5b661ed tcp: Recover from iob shortage with TCP_WRITE_BUFFERS
06e5b661ed is described below

commit 06e5b661ed6b1d7480b9c30a27be502a08924bce
Author: Petteri Aimonen <j...@git.mail.kapsi.fi>
AuthorDate: Fri Dec 15 20:24:23 2023 +0200

    tcp: Recover from iob shortage with TCP_WRITE_BUFFERS
    
    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.
---
 net/tcp/tcp_send_buffered.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/net/tcp/tcp_send_buffered.c b/net/tcp/tcp_send_buffered.c
index cf940d82f6..874b8d5c0e 100644
--- a/net/tcp/tcp_send_buffered.c
+++ b/net/tcp/tcp_send_buffered.c
@@ -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",

Reply via email to