TCP write buffering: Fix an error in the trim logic

This commit is contained in:
Gregory Nutt
2014-06-22 16:25:26 -06:00
parent 579935bfc1
commit d642616c5b
22 changed files with 164 additions and 21 deletions
+3 -1
View File
@@ -134,7 +134,9 @@
# define WRB_IOB(wrb) ((wrb)->wb_iob) # define WRB_IOB(wrb) ((wrb)->wb_iob)
# define WRB_COPYOUT(wrb,dest,n) (iob_copyout(dest,(wrb)->wb_iob,(n),0)) # define WRB_COPYOUT(wrb,dest,n) (iob_copyout(dest,(wrb)->wb_iob,(n),0))
# define WRB_COPYIN(wrb,src,n) (iob_copyin((wrb)->wb_iob,src,(n),0)) # define WRB_COPYIN(wrb,src,n) (iob_copyin((wrb)->wb_iob,src,(n),0))
# define WRB_TRIM(wrb,n) (iob_trimhead((wrb)->wb_iob,(n)))
# define WRB_TRIM(wrb,n) \
do { (wrb)->wb_iob = iob_trimhead((wrb)->wb_iob,(n)); } while (0)
#ifdef CONFIG_DEBUG #ifdef CONFIG_DEBUG
# define WRB_DUMP(msg,wrb) tcp_writebuffer_dump(msg,wrb) # define WRB_DUMP(msg,wrb) tcp_writebuffer_dump(msg,wrb)
+11
View File
@@ -42,4 +42,15 @@ config IOB_NCHAINS
I/O buffer chain containers that also carry a payload of usage I/O buffer chain containers that also carry a payload of usage
specific information. specific information.
config NET_IOB_DEBUG
bool "Force I/O buffer debug"
default n
depends on DEBUG
---help---
This option will force debug output from I/O buffer logic,
even without network debug output. This is not normally something
that would want to do but is convenient if you are debugging the
I/O buffer logic and do not want to get overloaded with other
network-related debug output.
endif # NET_IOB endif # NET_IOB
+7
View File
@@ -39,6 +39,13 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#if defined(CONFIG_DEBUG) && defined(CONFIG_NET_IOB_DEBUG)
/* Force debug output (from this file only) */
# undef CONFIG_DEBUG_NET
# define CONFIG_DEBUG_NET 1
#endif
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <debug.h> #include <debug.h>
+7
View File
@@ -39,6 +39,13 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#if defined(CONFIG_DEBUG) && defined(CONFIG_NET_IOB_DEBUG)
/* Force debug output (from this file only) */
# undef CONFIG_DEBUG_NET
# define CONFIG_DEBUG_NET 1
#endif
#include <semaphore.h> #include <semaphore.h>
#include <assert.h> #include <assert.h>
+7
View File
@@ -39,6 +39,13 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#if defined(CONFIG_DEBUG) && defined(CONFIG_NET_IOB_DEBUG)
/* Force debug output (from this file only) */
# undef CONFIG_DEBUG_NET
# define CONFIG_DEBUG_NET 1
#endif
#include <semaphore.h> #include <semaphore.h>
#include <assert.h> #include <assert.h>
+7
View File
@@ -39,6 +39,13 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#if defined(CONFIG_DEBUG) && defined(CONFIG_NET_IOB_DEBUG)
/* Force debug output (from this file only) */
# undef CONFIG_DEBUG_NET
# define CONFIG_DEBUG_NET 1
#endif
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
+7
View File
@@ -39,6 +39,13 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#if defined(CONFIG_DEBUG) && defined(CONFIG_NET_IOB_DEBUG)
/* Force debug output (from this file only) */
# undef CONFIG_DEBUG_NET
# define CONFIG_DEBUG_NET 1
#endif
#include <string.h> #include <string.h>
#include <nuttx/net/iob.h> #include <nuttx/net/iob.h>
+7
View File
@@ -39,6 +39,13 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#if defined(CONFIG_DEBUG) && defined(CONFIG_NET_IOB_DEBUG)
/* Force debug output (from this file only) */
# undef CONFIG_DEBUG_NET
# define CONFIG_DEBUG_NET 1
#endif
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
+15 -2
View File
@@ -39,6 +39,13 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#if defined(CONFIG_DEBUG) && defined(CONFIG_NET_IOB_DEBUG)
/* Force debug output (from this file only) */
# undef CONFIG_DEBUG_NET
# define CONFIG_DEBUG_NET 1
#endif
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
@@ -91,13 +98,14 @@ int iob_copyin(FAR struct iob_s *iob, FAR const uint8_t *src,
unsigned int ncopy; unsigned int ncopy;
unsigned int avail; unsigned int avail;
nllvdbg("iob=%p len=%u offset=%u\n", iob, len, offset);
DEBUGASSERT(iob && src); DEBUGASSERT(iob && src);
/* The offset must applied to data that is already in the I/O buffer chain */ /* The offset must applied to data that is already in the I/O buffer chain */
if (offset > iob->io_pktlen) if (offset > iob->io_pktlen)
{ {
ndbg("ERROR: offset is past the end of data: %d > %d\n", ndbg("ERROR: offset is past the end of data: %u > %u\n",
offset, iob->io_pktlen); offset, iob->io_pktlen);
return -ESPIPE; return -ESPIPE;
} }
@@ -123,6 +131,8 @@ int iob_copyin(FAR struct iob_s *iob, FAR const uint8_t *src,
dest = &iob->io_data[iob->io_offset + offset]; dest = &iob->io_data[iob->io_offset + offset];
avail = iob->io_len - offset; avail = iob->io_len - offset;
nllvdbg("iob=%p avail=%u len=%u next=%p\n", iob, avail, len, next);
/* Will the rest of the copy fit into this buffer, overwriting /* Will the rest of the copy fit into this buffer, overwriting
* existing data. * existing data.
*/ */
@@ -146,7 +156,7 @@ int iob_copyin(FAR struct iob_s *iob, FAR const uint8_t *src,
/* Yes.. We can extend this buffer to the up to the very end. */ /* Yes.. We can extend this buffer to the up to the very end. */
maxlen = CONFIG_IOB_BUFSIZE - iob->io_offset; maxlen = CONFIG_IOB_BUFSIZE - iob->io_offset;
/* This is the new buffer length that we need. Of course, /* This is the new buffer length that we need. Of course,
* clipped to the maximum possible size in this buffer. * clipped to the maximum possible size in this buffer.
@@ -178,6 +188,8 @@ int iob_copyin(FAR struct iob_s *iob, FAR const uint8_t *src,
/* Copy from the user buffer to the I/O buffer. */ /* Copy from the user buffer to the I/O buffer. */
memcpy(dest, src, ncopy); memcpy(dest, src, ncopy);
nllvdbg("iob=%p, Copy %u bytes, new len=%u\n",
iob, ncopy, iob->io_len);
/* Adjust the total length of the copy and the destination address in /* Adjust the total length of the copy and the destination address in
* the user buffer. * the user buffer.
@@ -204,6 +216,7 @@ int iob_copyin(FAR struct iob_s *iob, FAR const uint8_t *src,
/* Add the new, empty I/O buffer to the end of the buffer chain. */ /* Add the new, empty I/O buffer to the end of the buffer chain. */
iob->io_flink = next; iob->io_flink = next;
nllvdbg("iob=%p added to the chain\n", iob);
} }
iob = next; iob = next;
+7
View File
@@ -39,6 +39,13 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#if defined(CONFIG_DEBUG) && defined(CONFIG_NET_IOB_DEBUG)
/* Force debug output (from this file only) */
# undef CONFIG_DEBUG_NET
# define CONFIG_DEBUG_NET 1
#endif
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
+7
View File
@@ -39,6 +39,13 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#if defined(CONFIG_DEBUG) && defined(CONFIG_NET_IOB_DEBUG)
/* Force debug output (from this file only) */
# undef CONFIG_DEBUG_NET
# define CONFIG_DEBUG_NET 1
#endif
#include <semaphore.h> #include <semaphore.h>
#include <assert.h> #include <assert.h>
+7
View File
@@ -39,6 +39,13 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#if defined(CONFIG_DEBUG) && defined(CONFIG_NET_IOB_DEBUG)
/* Force debug output (from this file only) */
# undef CONFIG_DEBUG_NET
# define CONFIG_DEBUG_NET 1
#endif
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include <nuttx/net/iob.h> #include <nuttx/net/iob.h>
+7
View File
@@ -39,6 +39,13 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#if defined(CONFIG_DEBUG) && defined(CONFIG_NET_IOB_DEBUG)
/* Force debug output (from this file only) */
# undef CONFIG_DEBUG_NET
# define CONFIG_DEBUG_NET 1
#endif
#include <semaphore.h> #include <semaphore.h>
#include <assert.h> #include <assert.h>
+7
View File
@@ -39,6 +39,13 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#if defined(CONFIG_DEBUG) && defined(CONFIG_NET_IOB_DEBUG)
/* Force debug output (from this file only) */
# undef CONFIG_DEBUG_NET
# define CONFIG_DEBUG_NET 1
#endif
#include <assert.h> #include <assert.h>
#include <nuttx/net/iob.h> #include <nuttx/net/iob.h>
+7
View File
@@ -39,6 +39,13 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#if defined(CONFIG_DEBUG) && defined(CONFIG_NET_IOB_DEBUG)
/* Force debug output (from this file only) */
# undef CONFIG_DEBUG_NET
# define CONFIG_DEBUG_NET 1
#endif
#include <stdbool.h> #include <stdbool.h>
#include <semaphore.h> #include <semaphore.h>
+7
View File
@@ -39,6 +39,13 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#if defined(CONFIG_DEBUG) && defined(CONFIG_NET_IOB_DEBUG)
/* Force debug output (from this file only) */
# undef CONFIG_DEBUG_NET
# define CONFIG_DEBUG_NET 1
#endif
#include <string.h> #include <string.h>
#include <nuttx/net/iob.h> #include <nuttx/net/iob.h>
+7
View File
@@ -39,6 +39,13 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#if defined(CONFIG_DEBUG) && defined(CONFIG_NET_IOB_DEBUG)
/* Force debug output (from this file only) */
# undef CONFIG_DEBUG_NET
# define CONFIG_DEBUG_NET 1
#endif
#include <debug.h> #include <debug.h>
#include <nuttx/net/iob.h> #include <nuttx/net/iob.h>
+20 -13
View File
@@ -39,6 +39,13 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#if defined(CONFIG_DEBUG) && defined(CONFIG_NET_IOB_DEBUG)
/* Force debug output (from this file only) */
# undef CONFIG_DEBUG_NET
# define CONFIG_DEBUG_NET 1
#endif
#include <assert.h> #include <assert.h>
#include <debug.h> #include <debug.h>
@@ -82,23 +89,22 @@
FAR struct iob_s *iob_trimhead(FAR struct iob_s *iob, unsigned int trimlen) FAR struct iob_s *iob_trimhead(FAR struct iob_s *iob, unsigned int trimlen)
{ {
uint16_t pktlen; uint16_t pktlen;
unsigned int len;
nllvdbg("iob=%p pktlen=%d trimlen=%d\n", iob, iob->io_pktlen, trimlen); nllvdbg("iob=%p trimlen=%d\n", iob, trimlen);
if (iob && trimlen > 0) if (iob && trimlen > 0)
{ {
/* Trim from the head of the I/IO buffer chain */ /* Trim from the head of the I/IO buffer chain */
pktlen = iob->io_pktlen; pktlen = iob->io_pktlen;
len = trimlen; while (trimlen > 0 && iob != NULL)
while (len > 0 && iob != NULL)
{ {
/* Do we trim this entire I/O buffer away? */ /* Do we trim this entire I/O buffer away? */
nllvdbg("iob=%p len=%d vs %d\n", iob, iob->io_len, len); nllvdbg("iob=%p io_len=%d pktlen=%d trimlen=%d\n",
if (iob->io_len <= len) iob, iob->io_len, pktlen, trimlen);
if (iob->io_len <= trimlen)
{ {
FAR struct iob_s *next; FAR struct iob_s *next;
@@ -107,7 +113,7 @@ FAR struct iob_s *iob_trimhead(FAR struct iob_s *iob, unsigned int trimlen)
*/ */
pktlen -= iob->io_len; pktlen -= iob->io_len;
len -= iob->io_len; trimlen -= iob->io_len;
iob->io_len = 0; iob->io_len = 0;
iob->io_offset = 0; iob->io_offset = 0;
@@ -126,8 +132,9 @@ FAR struct iob_s *iob_trimhead(FAR struct iob_s *iob, unsigned int trimlen)
/* Free this entry and set the next I/O buffer as the head */ /* Free this entry and set the next I/O buffer as the head */
nllvdbg("iob=%p: Freeing\n", iob);
(void)iob_free(iob); (void)iob_free(iob);
iob = next; iob = next;
} }
else else
{ {
@@ -135,10 +142,10 @@ FAR struct iob_s *iob_trimhead(FAR struct iob_s *iob, unsigned int trimlen)
* stop the trim. * stop the trim.
*/ */
pktlen -= len; pktlen -= trimlen;
iob->io_len -= len; iob->io_len -= trimlen;
iob->io_offset += len; iob->io_offset += trimlen;
len = 0; trimlen = 0;
} }
} }
+7
View File
@@ -39,6 +39,13 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#if defined(CONFIG_DEBUG) && defined(CONFIG_NET_IOB_DEBUG)
/* Force debug output (from this file only) */
# undef CONFIG_DEBUG_NET
# define CONFIG_DEBUG_NET 1
#endif
#include <string.h> #include <string.h>
#include <debug.h> #include <debug.h>
+6 -3
View File
@@ -548,18 +548,21 @@ static uint16_t send_interrupt(FAR struct uip_driver_s *dev, FAR void *pvconn,
conn->sent += sndlen; conn->sent += sndlen;
} }
nllvdbg("SEND: nrtx=%d unacked=%d sent=%d\n", nllvdbg("SEND: wrb=%p nrtx=%d unacked=%d sent=%d\n",
WRB_NRTX(wrb), conn->unacked, conn->sent); wrb, WRB_NRTX(wrb), conn->unacked, conn->sent);
/* Increment the count of bytes sent from this write buffer */ /* Increment the count of bytes sent from this write buffer */
WRB_SENT(wrb) += sndlen; WRB_SENT(wrb) += sndlen;
DEBUGASSERT(WRB_SENT(wrb) <= WRB_PKTLEN(wrb));
nllvdbg("SEND: wrb=%p sent=%d pktlen=%d\n",
wrb, WRB_SENT(wrb), WRB_PKTLEN(wrb));
/* Remove the write buffer from the write queue if the /* Remove the write buffer from the write queue if the
* last of the data has been sent from the buffer. * last of the data has been sent from the buffer.
*/ */
DEBUGASSERT(WRB_SENT(wrb) <= WRB_PKTLEN(wrb));
if (WRB_SENT(wrb) >= WRB_PKTLEN(wrb)) if (WRB_SENT(wrb) >= WRB_PKTLEN(wrb))
{ {
FAR struct tcp_wrbuffer_s *tmp; FAR struct tcp_wrbuffer_s *tmp;
+2 -1
View File
@@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* net/net_sockets.c * net/net_sockets.c
* *
* Copyright (C) 2007-2009, 2011-2013 Gregory Nutt. All rights reserved. * Copyright (C) 2007-2009, 2011-2014 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
@@ -47,6 +47,7 @@
#include <errno.h> #include <errno.h>
#include <debug.h> #include <debug.h>
#include <nuttx/net/iob.h>
#include <nuttx/net/arp.h> #include <nuttx/net/arp.h>
#include <nuttx/net/uip/uip.h> #include <nuttx/net/uip/uip.h>
#include <nuttx/net/net.h> #include <nuttx/net/net.h>
+2 -1
View File
@@ -106,9 +106,10 @@ config NET_TCP_WRBUFFER_DEBUG
bool "Force write buffer debug" bool "Force write buffer debug"
default n default n
depends on DEBUG depends on DEBUG
select NET_IOB_DEBUG
---help--- ---help---
This option will force debug output from TCP write buffer logic, This option will force debug output from TCP write buffer logic,
even with network debug output. This is not normally something even without network debug output. This is not normally something
that would want to do but is convenient if you are debugging the that would want to do but is convenient if you are debugging the
write buffer logic and do not want to get overloaded with other write buffer logic and do not want to get overloaded with other
network-related debug output. network-related debug output.