mirror of
https://github.com/apache/nuttx.git
synced 2026-06-02 01:21:26 +08:00
net/tcp: Re-think CONFIG_NET_TCP_RWND_CONTROL TCP windowing controls.
This commit is contained in:
+11
-1
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* include/nuttx/mm/iob.h
|
* include/nuttx/mm/iob.h
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2014, 2018 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -183,6 +183,16 @@ FAR struct iob_s *iob_alloc(bool throttled);
|
|||||||
|
|
||||||
FAR struct iob_s *iob_tryalloc(bool throttled);
|
FAR struct iob_s *iob_tryalloc(bool throttled);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: iob_navail
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Return the number of of available IOBs.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int iob_navail(void);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: iob_free
|
* Name: iob_free
|
||||||
*
|
*
|
||||||
|
|||||||
+2
-1
@@ -1,7 +1,7 @@
|
|||||||
############################################################################
|
############################################################################
|
||||||
# mm/iob/Make.defs
|
# mm/iob/Make.defs
|
||||||
#
|
#
|
||||||
# Copyright (C) 2014, 2017 Gregory Nutt. All rights reserved.
|
# Copyright (C) 2014, 2017-2018 Gregory Nutt. All rights reserved.
|
||||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
@@ -42,6 +42,7 @@ CSRCS += iob_concat.c iob_copyin.c iob_copyout.c iob_contig.c iob_free.c
|
|||||||
CSRCS += iob_free_chain.c iob_free_qentry.c iob_free_queue.c
|
CSRCS += iob_free_chain.c iob_free_qentry.c iob_free_queue.c
|
||||||
CSRCS += iob_initialize.c iob_pack.c iob_peek_queue.c iob_remove_queue.c
|
CSRCS += iob_initialize.c iob_pack.c iob_peek_queue.c iob_remove_queue.c
|
||||||
CSRCS += iob_trimhead.c iob_trimhead_queue.c iob_trimtail.c
|
CSRCS += iob_trimhead.c iob_trimhead_queue.c iob_trimtail.c
|
||||||
|
CSRCS += iob_navail.c
|
||||||
|
|
||||||
ifeq ($(CONFIG_DEBUG_FEATURES),y)
|
ifeq ($(CONFIG_DEBUG_FEATURES),y)
|
||||||
CSRCS += iob_dump.c
|
CSRCS += iob_dump.c
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* mm/iob/iob_navail.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <nuttx/semaphore.h>
|
||||||
|
#include <nuttx/mm/iob.h>
|
||||||
|
|
||||||
|
#include "iob.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: iob_navail
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Return the number of of available IOBs.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int iob_navail(void)
|
||||||
|
{
|
||||||
|
int navail = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = nxsem_getvalue(&g_qentry_sem, &navail);
|
||||||
|
if (ret >= 0)
|
||||||
|
{
|
||||||
|
ret = navail;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
+6
-1
@@ -61,12 +61,17 @@ config NET_ETH_TCP_RECVWNDO
|
|||||||
default 1220 if NET_IPv6
|
default 1220 if NET_IPv6
|
||||||
default 536 if !NET_IPv6
|
default 536 if !NET_IPv6
|
||||||
depends on NET_ETHERNET && NET_TCP
|
depends on NET_ETHERNET && NET_TCP
|
||||||
|
range 536 65535
|
||||||
---help---
|
---help---
|
||||||
The size of the advertised receiver's window. Should be set low
|
The size of the advertised receiver's window. Should be set low
|
||||||
(i.e., to the size of the MSS) if the application is slow to process
|
(i.e., to the size of the MSS) if the application is slow to process
|
||||||
incoming data, or high (32768 bytes) if the application processes
|
incoming data, or high (65,535 bytes) if the application processes
|
||||||
data quickly.
|
data quickly.
|
||||||
|
|
||||||
|
This value does not account for buffering provided for read-ahead
|
||||||
|
buffering via IOBs. To include IOB aware windowing logic also
|
||||||
|
enable CONFIG_NET_TCP_RWND_CONTROL.
|
||||||
|
|
||||||
config NET_SLIP_MTU
|
config NET_SLIP_MTU
|
||||||
int # "SLIP packet buffer size (MTU)"
|
int # "SLIP packet buffer size (MTU)"
|
||||||
default 296
|
default 296
|
||||||
|
|||||||
+4
-1
@@ -178,9 +178,12 @@ endif # NET_TCP && !NET_TCP_NO_STACK
|
|||||||
config NET_TCP_RWND_CONTROL
|
config NET_TCP_RWND_CONTROL
|
||||||
bool "Receive window control based on IOBuffer"
|
bool "Receive window control based on IOBuffer"
|
||||||
default n
|
default n
|
||||||
depends on MM_IOB
|
depends on NET_READAHEAD
|
||||||
---help---
|
---help---
|
||||||
Support receive window control based on I/O buffer. This feature
|
Support receive window control based on I/O buffer. This feature
|
||||||
is still experimental.
|
is still experimental.
|
||||||
|
|
||||||
|
This feature, if enabled, will assume that the every IOB is
|
||||||
|
available for read-ahead storage of TCP packets.
|
||||||
|
|
||||||
endmenu # TCP/IP Networking
|
endmenu # TCP/IP Networking
|
||||||
|
|||||||
+67
-7
@@ -1,7 +1,8 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* net/tcp/tcp_send.c
|
* net/tcp/tcp_send.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2010, 2012, 2015 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2010, 2012, 2015, 2018 Gregory Nutt. All rights
|
||||||
|
* reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Adapted for NuttX from logic in uIP which also has a BSD-like license:
|
* Adapted for NuttX from logic in uIP which also has a BSD-like license:
|
||||||
@@ -314,9 +315,10 @@ static void tcp_sendcommon(FAR struct net_driver_s *dev,
|
|||||||
FAR struct tcp_hdr_s *tcp)
|
FAR struct tcp_hdr_s *tcp)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_NET_TCP_RWND_CONTROL
|
#ifdef CONFIG_NET_TCP_RWND_CONTROL
|
||||||
extern sem_t g_qentry_sem;
|
|
||||||
int qentry_sem_count;
|
|
||||||
uint32_t rwnd;
|
uint32_t rwnd;
|
||||||
|
uint16_t iplen;
|
||||||
|
uint16_t overhead;
|
||||||
|
int navail;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Copy the IP address into the IPv6 header */
|
/* Copy the IP address into the IPv6 header */
|
||||||
@@ -327,8 +329,13 @@ static void tcp_sendcommon(FAR struct net_driver_s *dev,
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
|
FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
|
||||||
|
|
||||||
net_ipv6addr_hdrcopy(ipv6->srcipaddr, dev->d_ipv6addr);
|
net_ipv6addr_hdrcopy(ipv6->srcipaddr, dev->d_ipv6addr);
|
||||||
net_ipv6addr_hdrcopy(ipv6->destipaddr, conn->u.ipv6.raddr);
|
net_ipv6addr_hdrcopy(ipv6->destipaddr, conn->u.ipv6.raddr);
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_TCP_RWND_CONTROL
|
||||||
|
iplen = IPv6_HDRLEN;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_IPv6 */
|
#endif /* CONFIG_NET_IPv6 */
|
||||||
|
|
||||||
@@ -338,8 +345,13 @@ static void tcp_sendcommon(FAR struct net_driver_s *dev,
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
FAR struct ipv4_hdr_s *ipv4 = IPv4BUF;
|
FAR struct ipv4_hdr_s *ipv4 = IPv4BUF;
|
||||||
|
|
||||||
net_ipv4addr_hdrcopy(ipv4->srcipaddr, &dev->d_ipaddr);
|
net_ipv4addr_hdrcopy(ipv4->srcipaddr, &dev->d_ipaddr);
|
||||||
net_ipv4addr_hdrcopy(ipv4->destipaddr, &conn->u.ipv4.raddr);
|
net_ipv4addr_hdrcopy(ipv4->destipaddr, &conn->u.ipv4.raddr);
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_TCP_RWND_CONTROL
|
||||||
|
iplen = IPv4_HDRLEN;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_IPv4 */
|
#endif /* CONFIG_NET_IPv4 */
|
||||||
|
|
||||||
@@ -352,16 +364,64 @@ static void tcp_sendcommon(FAR struct net_driver_s *dev,
|
|||||||
tcp->destport = conn->rport;
|
tcp->destport = conn->rport;
|
||||||
|
|
||||||
#ifdef CONFIG_NET_TCP_RWND_CONTROL
|
#ifdef CONFIG_NET_TCP_RWND_CONTROL
|
||||||
/* Update the TCP received window based on I/O buffer */
|
/* Update the TCP received window based on I/O buffer availability */
|
||||||
/* NOTE: This algorithm is still experimental */
|
/* NOTE: This algorithm is still experimental */
|
||||||
|
|
||||||
if (OK == nxsem_getvalue(&g_qentry_sem, &qentry_sem_count))
|
overhead = NET_LL_HDRLEN(dev) + iplen + TCP_HDRLEN;
|
||||||
|
navail = iob_navail();
|
||||||
|
if (navail > 0)
|
||||||
{
|
{
|
||||||
rwnd = (qentry_sem_count * CONFIG_NET_ETH_TCP_RECVWNDO)
|
/* The optimal TCP window size is the amount of TCP data that we can
|
||||||
/ CONFIG_IOB_NCHAINS;
|
* currently buffer via TCP read-ahead buffering minus overhead for the
|
||||||
|
* link-layer, IP, and TCP headers. This logic here assumes that
|
||||||
|
* all IOBs are available for TCP buffering.
|
||||||
|
*
|
||||||
|
* REVISIT: In an environment with mutliple, active read-ahead TCP
|
||||||
|
* sockets (and perhaps multiple network devices) or if there are
|
||||||
|
* other consumers of IOBs (such as for TCP write buffering) then the
|
||||||
|
* total number of IOBs will all not be available for read-ahead
|
||||||
|
* buffering for this connection.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* REVISIT: (1)CONFIG_NET_ETH_TCP_RECVWNDO will typically be larger
|
||||||
|
* than the IOB payload size. (2) Why divide by CONFIG_IOB_NCHAINS?
|
||||||
|
* (3) CONFIG_NET_ETH_TCP_RECVWNDO includes the header overhead
|
||||||
|
* penalty. But we only have to pay the header overhead penalty
|
||||||
|
* once. (4) This logic needs to work even if Ethernet is not
|
||||||
|
* enabled (and hence CONFIG_NET_ETH_TCP_RECVWNDO is not defined).
|
||||||
|
*/
|
||||||
|
|
||||||
|
rwnd = (navail * CONFIG_NET_ETH_TCP_RECVWNDO) / CONFIG_IOB_NCHAINS;
|
||||||
|
#else
|
||||||
|
/* Assume that all of the available IOBs are can be used for buffering
|
||||||
|
* on this connection.
|
||||||
|
*/
|
||||||
|
|
||||||
|
rwnd = (navail * CONFIG_IOB_BUFSIZE) - overhead;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Save the new receive window size */
|
||||||
|
|
||||||
|
if (rwnd > UINT16_MAX)
|
||||||
|
{
|
||||||
|
rwnd = UINT16_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
NET_DEV_RCVWNDO(dev) = (uint16_t)rwnd;
|
NET_DEV_RCVWNDO(dev) = (uint16_t)rwnd;
|
||||||
}
|
}
|
||||||
|
else /* (navail == 0) */
|
||||||
|
{
|
||||||
|
/* No IOBs are available... fall back to the configured default
|
||||||
|
* which assumes no write buffering. The only buffering available
|
||||||
|
* is the packet itself.
|
||||||
|
*
|
||||||
|
* NOTE: If no IOBs are available, then the next packet will be
|
||||||
|
* lost will be be lost if there is no listener on the connection.
|
||||||
|
*/
|
||||||
|
|
||||||
|
NET_DEV_RCVWNDO(dev) = dev->d_mtu - overhead;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Set the TCP window */
|
/* Set the TCP window */
|
||||||
|
|||||||
Reference in New Issue
Block a user