net/tcp: Re-think CONFIG_NET_TCP_RWND_CONTROL TCP windowing controls.
This commit is contained in:
parent
433f29eea2
commit
0786b5d053
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* 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>
|
||||
*
|
||||
* 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);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: iob_navail
|
||||
*
|
||||
* Description:
|
||||
* Return the number of of available IOBs.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int iob_navail(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: iob_free
|
||||
*
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
############################################################################
|
||||
# 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>
|
||||
#
|
||||
# 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_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_navail.c
|
||||
|
||||
ifeq ($(CONFIG_DEBUG_FEATURES),y)
|
||||
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;
|
||||
}
|
|
@ -61,12 +61,17 @@ config NET_ETH_TCP_RECVWNDO
|
|||
default 1220 if NET_IPv6
|
||||
default 536 if !NET_IPv6
|
||||
depends on NET_ETHERNET && NET_TCP
|
||||
range 536 65535
|
||||
---help---
|
||||
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
|
||||
incoming data, or high (32768 bytes) if the application processes
|
||||
incoming data, or high (65,535 bytes) if the application processes
|
||||
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
|
||||
int # "SLIP packet buffer size (MTU)"
|
||||
default 296
|
||||
|
|
|
@ -178,9 +178,12 @@ endif # NET_TCP && !NET_TCP_NO_STACK
|
|||
config NET_TCP_RWND_CONTROL
|
||||
bool "Receive window control based on IOBuffer"
|
||||
default n
|
||||
depends on MM_IOB
|
||||
depends on NET_READAHEAD
|
||||
---help---
|
||||
Support receive window control based on I/O buffer. This feature
|
||||
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
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
/****************************************************************************
|
||||
* 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>
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
#ifdef CONFIG_NET_TCP_RWND_CONTROL
|
||||
extern sem_t g_qentry_sem;
|
||||
int qentry_sem_count;
|
||||
uint32_t rwnd;
|
||||
uint16_t iplen;
|
||||
uint16_t overhead;
|
||||
int navail;
|
||||
#endif
|
||||
|
||||
/* Copy the IP address into the IPv6 header */
|
||||
|
@ -327,8 +329,13 @@ static void tcp_sendcommon(FAR struct net_driver_s *dev,
|
|||
#endif
|
||||
{
|
||||
FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
|
||||
|
||||
net_ipv6addr_hdrcopy(ipv6->srcipaddr, dev->d_ipv6addr);
|
||||
net_ipv6addr_hdrcopy(ipv6->destipaddr, conn->u.ipv6.raddr);
|
||||
|
||||
#ifdef CONFIG_NET_TCP_RWND_CONTROL
|
||||
iplen = IPv6_HDRLEN;
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_NET_IPv6 */
|
||||
|
||||
|
@ -338,8 +345,13 @@ static void tcp_sendcommon(FAR struct net_driver_s *dev,
|
|||
#endif
|
||||
{
|
||||
FAR struct ipv4_hdr_s *ipv4 = IPv4BUF;
|
||||
|
||||
net_ipv4addr_hdrcopy(ipv4->srcipaddr, &dev->d_ipaddr);
|
||||
net_ipv4addr_hdrcopy(ipv4->destipaddr, &conn->u.ipv4.raddr);
|
||||
|
||||
#ifdef CONFIG_NET_TCP_RWND_CONTROL
|
||||
iplen = IPv4_HDRLEN;
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_NET_IPv4 */
|
||||
|
||||
|
@ -352,16 +364,64 @@ static void tcp_sendcommon(FAR struct net_driver_s *dev,
|
|||
tcp->destport = conn->rport;
|
||||
|
||||
#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 */
|
||||
|
||||
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)
|
||||
/ CONFIG_IOB_NCHAINS;
|
||||
/* The optimal TCP window size is the amount of TCP data that we can
|
||||
* 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;
|
||||
}
|
||||
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
|
||||
|
||||
/* Set the TCP window */
|
||||
|
|
Loading…
Reference in New Issue