From fa652f9c2467f6a95b45aad9f6d3952038077f23 Mon Sep 17 00:00:00 2001 From: zhanghongyu Date: Mon, 19 Jan 2026 15:51:04 +0800 Subject: [PATCH] net: limit TCP and UDP send/recv buffer usage with throttled IOB The main content of this submission is to limit both the TX/RX buffers of TCP/UDP to throttled IOBs, avoiding impacts on the sending and receiving of control-type messages. Signed-off-by: zhanghongyu --- net/bluetooth/bluetooth_sendmsg.c | 2 +- net/devif/devif_filesend.c | 10 +++++----- net/icmp/icmp_input.c | 2 +- net/icmpv6/icmpv6_input.c | 2 +- net/netdev/netdev_iob.c | 6 +----- net/pkt/pkt_netpoll.c | 2 +- net/pkt/pkt_sendmsg_buffered.c | 8 ++++---- net/sixlowpan/sixlowpan_framelist.c | 4 ++-- net/tcp/tcp_recvwindow.c | 19 ------------------- net/tcp/tcp_send_buffered.c | 2 +- net/udp/udp_callback.c | 3 ++- net/udp/udp_sendto_buffered.c | 8 ++++---- net/udp/udp_wrbuffer.c | 4 ++-- 13 files changed, 25 insertions(+), 47 deletions(-) diff --git a/net/bluetooth/bluetooth_sendmsg.c b/net/bluetooth/bluetooth_sendmsg.c index 8259d590018..d1a076d27a2 100644 --- a/net/bluetooth/bluetooth_sendmsg.c +++ b/net/bluetooth/bluetooth_sendmsg.c @@ -146,7 +146,7 @@ static uint32_t bluetooth_sendto_eventhandler(FAR struct net_driver_s *dev, /* Allocate an IOB to hold the frame data */ - iob = net_ioballoc(false); + iob = net_ioballoc(true); if (iob == NULL) { nwarn("WARNING: Failed to allocate IOB\n"); diff --git a/net/devif/devif_filesend.c b/net/devif/devif_filesend.c index 68f714968ac..bc4a443efa3 100644 --- a/net/devif/devif_filesend.c +++ b/net/devif/devif_filesend.c @@ -87,14 +87,14 @@ int devif_file_send(FAR struct net_driver_s *dev, FAR struct file *file, /* Append the send buffer after device buffer */ - if (len > iob_navail(false) * CONFIG_IOB_BUFSIZE || - netdev_iob_prepare(dev, false, 0) != OK) + if (len > iob_navail(true) * CONFIG_IOB_BUFSIZE || + netdev_iob_prepare(dev, true, 0) != OK) { ret = -ENOMEM; goto errout; } - iob_update_pktlen(dev->d_iob, target_offset, false); + iob_update_pktlen(dev->d_iob, target_offset, true); ret = file_seek(file, offset, SEEK_SET); if (ret < 0) @@ -111,7 +111,7 @@ int devif_file_send(FAR struct net_driver_s *dev, FAR struct file *file, { if (iob->io_flink == NULL) { - iob->io_flink = iob_tryalloc(false); + iob->io_flink = iob_tryalloc(true); if (iob->io_flink == NULL) { ret = -ENOMEM; @@ -144,7 +144,7 @@ int devif_file_send(FAR struct net_driver_s *dev, FAR struct file *file, } } - iob_update_pktlen(dev->d_iob, target_offset + len, false); + iob_update_pktlen(dev->d_iob, target_offset + len, true); dev->d_sndlen = len; return len; diff --git a/net/icmp/icmp_input.c b/net/icmp/icmp_input.c index 69b5e76ff8a..ac9d641159c 100644 --- a/net/icmp/icmp_input.c +++ b/net/icmp/icmp_input.c @@ -153,7 +153,7 @@ static uint16_t icmp_datahandler(FAR struct net_driver_s *dev, /* Copy the ICMP message into the I/O buffer chain (without waiting) */ ret = iob_clone_partial(dev->d_iob, dev->d_iob->io_pktlen, - 0, iob, 0, true, false); + 0, iob, 0, false, false); if (ret < 0) { iob_free_chain(iob); diff --git a/net/icmpv6/icmpv6_input.c b/net/icmpv6/icmpv6_input.c index 0855d1b9b11..5704375cd7d 100644 --- a/net/icmpv6/icmpv6_input.c +++ b/net/icmpv6/icmpv6_input.c @@ -144,7 +144,7 @@ static uint16_t icmpv6_datahandler(FAR struct net_driver_s *dev, /* Copy the ICMPv6 message into the I/O buffer chain (without waiting) */ ret = iob_clone_partial(dev->d_iob, dev->d_iob->io_pktlen, - iplen, iob, 0, true, false); + iplen, iob, 0, false, false); if (ret < 0) { iob_free_chain(iob); diff --git a/net/netdev/netdev_iob.c b/net/netdev/netdev_iob.c index 67cc57f088b..3cc40f4118c 100644 --- a/net/netdev/netdev_iob.c +++ b/net/netdev/netdev_iob.c @@ -62,11 +62,7 @@ int netdev_iob_prepare(FAR struct net_driver_s *dev, bool throttled, if (dev->d_iob == NULL) { - dev->d_iob = net_iobtimedalloc(false, timeout); - if (dev->d_iob == NULL && throttled) - { - dev->d_iob = net_iobtimedalloc(true, timeout); - } + dev->d_iob = net_iobtimedalloc(throttled, timeout); } if (dev->d_iob == NULL) diff --git a/net/pkt/pkt_netpoll.c b/net/pkt/pkt_netpoll.c index 2644f212ab3..5273ff9f3ab 100644 --- a/net/pkt/pkt_netpoll.c +++ b/net/pkt/pkt_netpoll.c @@ -66,7 +66,7 @@ static int psock_pkt_cansend(FAR struct pkt_conn_s *conn) { - if (iob_navail(false) <= 0 + if (iob_navail(true) <= 0 #if defined(CONFIG_NET_PKT_WRITE_BUFFERS) && CONFIG_NET_SEND_BUFSIZE > 0 || iob_get_queue_size(&conn->write_q) >= conn->sndbufs #endif diff --git a/net/pkt/pkt_sendmsg_buffered.c b/net/pkt/pkt_sendmsg_buffered.c index e511a0a11c2..5641e6096f7 100644 --- a/net/pkt/pkt_sendmsg_buffered.c +++ b/net/pkt/pkt_sendmsg_buffered.c @@ -266,7 +266,7 @@ ssize_t pkt_sendmsg(FAR struct socket *psock, FAR const struct msghdr *msg, if (nonblock) { - iob = iob_tryalloc(false); + iob = iob_tryalloc(true); } else { @@ -292,7 +292,7 @@ ssize_t pkt_sendmsg(FAR struct socket *psock, FAR const struct msghdr *msg, } iob_reserve(iob, CONFIG_NET_LL_GUARDSIZE); - iob_update_pktlen(iob, 0, false); + iob_update_pktlen(iob, 0, true); /* Copy the user data into the write buffer. We cannot wait for * buffer space if the socket was opened non-blocking. @@ -305,7 +305,7 @@ ssize_t pkt_sendmsg(FAR struct socket *psock, FAR const struct msghdr *msg, if (nonblock) { - ret = iob_trycopyin(iob, buf, len, offset, false); + ret = iob_trycopyin(iob, buf, len, offset, true); } else { @@ -315,7 +315,7 @@ ssize_t pkt_sendmsg(FAR struct socket *psock, FAR const struct msghdr *msg, */ conn_dev_unlock(&conn->sconn, dev); - ret = iob_copyin(iob, buf, len, offset, false); + ret = iob_copyin(iob, buf, len, offset, true); conn_dev_lock(&conn->sconn, dev); } diff --git a/net/sixlowpan/sixlowpan_framelist.c b/net/sixlowpan/sixlowpan_framelist.c index 63542610870..ee2438160dc 100644 --- a/net/sixlowpan/sixlowpan_framelist.c +++ b/net/sixlowpan/sixlowpan_framelist.c @@ -412,7 +412,7 @@ int sixlowpan_queue_frames(FAR struct radio_driver_s *radio, * necessary. */ - iob = net_ioballoc(false); + iob = net_ioballoc(true); DEBUGASSERT(iob != NULL); fptr = iob->io_data; @@ -630,7 +630,7 @@ int sixlowpan_queue_frames(FAR struct radio_driver_s *radio, * necessary. */ - iob = net_ioballoc(false); + iob = net_ioballoc(true); DEBUGASSERT(iob != NULL); /* Initialize the IOB */ diff --git a/net/tcp/tcp_recvwindow.c b/net/tcp/tcp_recvwindow.c index 382e9624e66..3d406af17e9 100644 --- a/net/tcp/tcp_recvwindow.c +++ b/net/tcp/tcp_recvwindow.c @@ -188,25 +188,6 @@ uint32_t tcp_get_recvwindow(FAR struct net_driver_s *dev, recvwndo = tailroom + (niob_avail * CONFIG_IOB_BUFSIZE); } -#if CONFIG_IOB_THROTTLE > 0 - else if (conn->readahead == NULL) - { - /* Advertise maximum segment size for window edge if here is no - * available iobs on current "free" connection. - * - * Note: hopefully, a single mss-sized packet can be queued by - * the throttled=false case in tcp_datahandler(). - */ - - int niob_avail_no_throttle = iob_navail(false); - - recvwndo = tcp_rx_mss(dev); - if (recvwndo > niob_avail_no_throttle * CONFIG_IOB_BUFSIZE) - { - recvwndo = niob_avail_no_throttle * CONFIG_IOB_BUFSIZE; - } - } -#endif else /* niob_avail == 0 */ { /* No IOBs are available. diff --git a/net/tcp/tcp_send_buffered.c b/net/tcp/tcp_send_buffered.c index 35b510e77db..6915fcd5474 100644 --- a/net/tcp/tcp_send_buffered.c +++ b/net/tcp/tcp_send_buffered.c @@ -1083,7 +1083,7 @@ static uint32_t psock_send_eventhandler(FAR struct net_driver_s *dev, * the maximum size packet that would fit. */ - if (sndlen > iob_navail(false) * CONFIG_IOB_BUFSIZE) + if (sndlen > iob_navail(true) * CONFIG_IOB_BUFSIZE) { nwarn("Running low on iobs, limiting packet size\n"); sndlen = CONFIG_IOB_BUFSIZE; diff --git a/net/udp/udp_callback.c b/net/udp/udp_callback.c index 7b363e3acd4..ae1233ef848 100644 --- a/net/udp/udp_callback.c +++ b/net/udp/udp_callback.c @@ -80,7 +80,8 @@ static uint16_t udp_datahandler(FAR struct net_driver_s *dev, conn_lock(&conn->sconn); #if CONFIG_NET_RECV_BUFSIZE > 0 - if (conn->readahead && conn->readahead->io_pktlen > conn->rcvbufs) + if (conn->readahead && conn->readahead->io_pktlen > conn->rcvbufs && + iob_navail(true) == 0) { conn_unlock(&conn->sconn); netdev_iob_release(dev); diff --git a/net/udp/udp_sendto_buffered.c b/net/udp/udp_sendto_buffered.c index 3ca2f142e39..556e9bb3a43 100644 --- a/net/udp/udp_sendto_buffered.c +++ b/net/udp/udp_sendto_buffered.c @@ -832,7 +832,7 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf, udpiplen = udpip_hdrsize(conn); iob_reserve(wrb->wb_iob, CONFIG_NET_LL_GUARDSIZE); - iob_update_pktlen(wrb->wb_iob, udpiplen, false); + iob_update_pktlen(wrb->wb_iob, udpiplen, true); /* Copy the user data into the write buffer. We cannot wait for * buffer space if the socket was opened non-blocking. @@ -843,12 +843,12 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf, if (nonblock) { ret = iob_trycopyin(wrb->wb_iob, (FAR uint8_t *)buf, - len, udpiplen, false); + len, udpiplen, true); } else { ret = iob_copyin(wrb->wb_iob, (FAR uint8_t *)buf, - len, udpiplen, false); + len, udpiplen, true); } if (ret < 0) @@ -951,7 +951,7 @@ int psock_udp_cansend(FAR struct udp_conn_s *conn) * many more. */ - if (udp_wrbuffer_test() < 0 || iob_navail(false) <= 0 + if (udp_wrbuffer_test() < 0 || iob_navail(true) <= 0 #if CONFIG_NET_SEND_BUFSIZE > 0 || udp_wrbuffer_inqueue_size(conn) >= conn->sndbufs #endif diff --git a/net/udp/udp_wrbuffer.c b/net/udp/udp_wrbuffer.c index 176f99142bb..eaf41c0a1db 100644 --- a/net/udp/udp_wrbuffer.c +++ b/net/udp/udp_wrbuffer.c @@ -94,7 +94,7 @@ FAR struct udp_wrbuffer_s *udp_wrbuffer_alloc(void) /* Now get the first I/O buffer for the write buffer structure */ - wrb->wb_iob = net_ioballoc(false); + wrb->wb_iob = net_ioballoc(true); if (!wrb->wb_iob) { nerr("ERROR: Failed to allocate I/O buffer\n"); @@ -205,7 +205,7 @@ FAR struct udp_wrbuffer_s *udp_wrbuffer_tryalloc(void) #ifdef CONFIG_NET_JUMBO_FRAME iob_alloc_dynamic(len); #else - iob_tryalloc(false); + iob_tryalloc(true); #endif if (!wrb->wb_iob) {