mirror of
https://github.com/apache/nuttx.git
synced 2026-05-19 20:06:24 +08:00
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 <zhanghongyu@xiaomi.com>
This commit is contained in:
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user