diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-06-24 15:38:00 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-06-24 15:38:00 -0600 |
commit | f8f6318244f391e250428ecacae6a0b66feb0bea (patch) | |
tree | 306aaa03910542027396fd219512d61e21d48975 /nuttx/net | |
parent | d8d6c72e3b71b7b7324d301432c194c712411df6 (diff) | |
download | px4-nuttx-f8f6318244f391e250428ecacae6a0b66feb0bea.tar.gz px4-nuttx-f8f6318244f391e250428ecacae6a0b66feb0bea.tar.bz2 px4-nuttx-f8f6318244f391e250428ecacae6a0b66feb0bea.zip |
TCP Read-Ahead: Convert to use I/O buffer chains
Diffstat (limited to 'nuttx/net')
-rw-r--r-- | nuttx/net/iob/Kconfig | 4 | ||||
-rw-r--r-- | nuttx/net/iob/Make.defs | 4 | ||||
-rw-r--r-- | nuttx/net/iob/iob_alloc.c | 10 | ||||
-rw-r--r-- | nuttx/net/iob/iob_alloc_qentry.c | 32 | ||||
-rw-r--r-- | nuttx/net/iob/iob_copyin.c | 2 | ||||
-rw-r--r-- | nuttx/net/iob/iob_free.c | 3 | ||||
-rw-r--r-- | nuttx/net/iob/iob_initialize.c | 4 | ||||
-rw-r--r-- | nuttx/net/iob/iob_remove_queue.c | 7 | ||||
-rw-r--r-- | nuttx/net/net_poll.c | 4 | ||||
-rw-r--r-- | nuttx/net/recvfrom.c | 96 | ||||
-rw-r--r-- | nuttx/net/tcp/Kconfig | 39 | ||||
-rw-r--r-- | nuttx/net/tcp/Make.defs | 6 | ||||
-rw-r--r-- | nuttx/net/tcp/tcp_callback.c | 131 | ||||
-rw-r--r-- | nuttx/net/tcp/tcp_conn.c | 12 | ||||
-rw-r--r-- | nuttx/net/tcp/tcp_readahead.c | 143 | ||||
-rw-r--r-- | nuttx/net/tcp/tcp_send_buffered.c | 2 | ||||
-rw-r--r-- | nuttx/net/uip/uip.h | 11 | ||||
-rw-r--r-- | nuttx/net/uip/uip_initialize.c | 8 |
18 files changed, 129 insertions, 389 deletions
diff --git a/nuttx/net/iob/Kconfig b/nuttx/net/iob/Kconfig index b8481ab9e..5bb6e4c6b 100644 --- a/nuttx/net/iob/Kconfig +++ b/nuttx/net/iob/Kconfig @@ -48,8 +48,8 @@ config IOB_NCHAINS config IOB_THROTTLE int "I/O buffer throttle value" default 0 if !NET_TCP_WRITE_BUFFERS || !NET_TCP_READAHEAD - default 8 if NET_TCP_WRITE_BUFFERS && !NET_TCP_READAHEAD - depends on NET_TCP_WRITE_BUFFERS && !NET_TCP_READAHEAD + default 8 if NET_TCP_WRITE_BUFFERS && NET_TCP_READAHEAD + depends on NET_TCP_WRITE_BUFFERS && NET_TCP_READAHEAD ---help--- TCP write buffering and read-ahead buffer use the same pool of free I/O buffers. In order to prevent uncontrolled incoming TCP packets diff --git a/nuttx/net/iob/Make.defs b/nuttx/net/iob/Make.defs index 205ef72ea..0eb2e0f9b 100644 --- a/nuttx/net/iob/Make.defs +++ b/nuttx/net/iob/Make.defs @@ -40,8 +40,8 @@ ifeq ($(CONFIG_NET_IOB),y) NET_CSRCS += iob_add_queue.c iob_alloc.c iob_alloc_qentry.c iob_clone.c NET_CSRCS += iob_concat.c iob_copyin.c iob_copyout.c iob_contig.c iob_free.c NET_CSRCS += iob_free_chain.c iob_free_qentry.c iob_free_queue.c -NET_CSRCS += iob_initialize.c iob_pack.c iob_remove_queue.c iob_trimhead.c -NET_CSRCS += iob_trimtail.c +NET_CSRCS += iob_initialize.c iob_pack.c iob_peek_queue.c iob_remove_queue.c +NET_CSRCS += iob_trimhead.c iob_trimtail.c ifeq ($(CONFIG_DEBUG),y) NET_CSRCS += iob_dump.c diff --git a/nuttx/net/iob/iob_alloc.c b/nuttx/net/iob/iob_alloc.c index 672d1e2e7..179908d46 100644 --- a/nuttx/net/iob/iob_alloc.c +++ b/nuttx/net/iob/iob_alloc.c @@ -95,7 +95,7 @@ static FAR struct iob_s *iob_tryalloc(bool throttled) #if CONFIG_IOB_THROTTLE > 0 /* Select the semaphore count to check. */ - sem = (throttled ? : &g_throttled_sem, &g_iob_sem); + sem = (throttled ? &g_throttle_sem : &g_iob_sem); #endif /* We don't know what context we are called from so we use extreme measures @@ -107,7 +107,7 @@ static FAR struct iob_s *iob_tryalloc(bool throttled) #if CONFIG_IOB_THROTTLE > 0 /* If there are free I/O buffers for this allocation */ - DEBUGVERIFY(sem_getvalue(sem, semcount)); + DEBUGVERIFY(sem_getvalue(sem, &semcount)); if (semcount > 0) #endif { @@ -124,7 +124,9 @@ static FAR struct iob_s *iob_tryalloc(bool throttled) g_iob_freelist = iob->io_flink; DEBUGVERIFY(sem_trywait(&g_iob_sem)); #if CONFIG_IOB_THROTTLE > 0 - DEBUGVERIFY(sem_trywait(&g_throttle_sem)); + //DEBUGVERIFY(sem_trywait(&g_throttle_sem)); + g_throttle_sem.semcount--; + DEBUGASSERT(g_throttle_sem.semcount >= -CONFIG_IOB_THROTTLE); #endif irqrestore(flags); @@ -161,7 +163,7 @@ static FAR struct iob_s *iob_allocwait(bool throttled) #if CONFIG_IOB_THROTTLE > 0 /* Select the semaphore count to check. */ - sem = (throttled ? : &g_throttled_sem, &g_iob_sem); + sem = (throttled ? &g_throttle_sem : &g_iob_sem); #else sem = &g_iob_sem; #endif diff --git a/nuttx/net/iob/iob_alloc_qentry.c b/nuttx/net/iob/iob_alloc_qentry.c index f75d21009..8f425adb0 100644 --- a/nuttx/net/iob/iob_alloc_qentry.c +++ b/nuttx/net/iob/iob_alloc_qentry.c @@ -105,7 +105,7 @@ static FAR struct iob_qentry_s *iob_tryalloc_qentry(void) */ g_iob_freeqlist = iobq->qe_flink; - DEBVERIFY(sem_trywait(&g_qentry_sem)); + DEBUGVERIFY(sem_trywait(&g_qentry_sem)); /* Put the I/O buffer in a known state */ @@ -186,32 +186,20 @@ static FAR struct iob_qentry_s *iob_allocwait_qentry(void) FAR struct iob_qentry_s *iob_alloc_qentry(void) { - FAR struct iob_qentry_s *iobq; - irqstate_t flags; - - /* We don't know what context we are called from so we use extreme measures - * to protect the free list: We disable interrupts very briefly. - */ + /* Were we called from the interrupt level? */ - flags = irqsave(); - iobq = g_iob_freeqlist; - if (iobq) + if (up_interrupt_context()) { - /* Remove the I/O buffer chain container from the free list and - * decrement the counting semaphore that tracks the number of free - * containers. - */ - - g_iob_freeqlist = iobq->qe_flink; - DEBVERIFY(sem_trywait(&g_qentry_sem)); - - /* Put the I/O buffer in a known state */ + /* Yes, then try to allocate an I/O buffer without waiting */ - iobq->qe_head = NULL; /* Nothing is contained */ + return iob_tryalloc_qentry(); } + else + { + /* Then allocate an I/O buffer, waiting as necessary */ - irqrestore(flags); - return iobq; + return iob_allocwait_qentry(); + } } #endif /* CONFIG_IOB_NCHAINS > 0 */ diff --git a/nuttx/net/iob/iob_copyin.c b/nuttx/net/iob/iob_copyin.c index 1cfd1f697..75d82023c 100644 --- a/nuttx/net/iob/iob_copyin.c +++ b/nuttx/net/iob/iob_copyin.c @@ -223,5 +223,5 @@ int iob_copyin(FAR struct iob_s *iob, FAR const uint8_t *src, offset = 0; } - return 0; + return OK; } diff --git a/nuttx/net/iob/iob_free.c b/nuttx/net/iob/iob_free.c index ada8a7fe6..984287600 100644 --- a/nuttx/net/iob/iob_free.c +++ b/nuttx/net/iob/iob_free.c @@ -135,6 +135,9 @@ FAR struct iob_s *iob_free(FAR struct iob_s *iob) /* Signal that an IOB is available */ sem_post(&g_iob_sem); +#if CONFIG_IOB_THROTTLE > 0 + sem_post(&g_throttle_sem); +#endif irqrestore(flags); /* And return the I/O buffer after the one that was freed */ diff --git a/nuttx/net/iob/iob_initialize.c b/nuttx/net/iob/iob_initialize.c index 8971f8d63..647eb0649 100644 --- a/nuttx/net/iob/iob_initialize.c +++ b/nuttx/net/iob/iob_initialize.c @@ -131,6 +131,10 @@ void iob_initialize(void) sem_init(&g_iob_sem, 0, CONFIG_IOB_NBUFFERS); +#if CONFIG_IOB_THROTTLE > 0 + sem_init(&g_throttle_sem, 0, CONFIG_IOB_NBUFFERS - CONFIG_IOB_THROTTLE); +#endif + #if CONFIG_IOB_NCHAINS > 0 /* Add each I/O buffer chain queue container to the free list */ diff --git a/nuttx/net/iob/iob_remove_queue.c b/nuttx/net/iob/iob_remove_queue.c index f516ad047..e134bcd01 100644 --- a/nuttx/net/iob/iob_remove_queue.c +++ b/nuttx/net/iob/iob_remove_queue.c @@ -67,10 +67,13 @@ ****************************************************************************/ /**************************************************************************** - * Name: iob_add_queue + * Name: iob_remove_queue * * Description: - * Remove one I/O buffer chain from the heaqd of a queue. + * Remove and return one I/O buffer chain from the head of a queue. + * + * Returned Value: + * Returns a reference to the I/O buffer chain at the head of the queue. * ****************************************************************************/ diff --git a/nuttx/net/net_poll.c b/nuttx/net/net_poll.c index 00900919a..a8f873ea7 100644 --- a/nuttx/net/net_poll.c +++ b/nuttx/net/net_poll.c @@ -243,11 +243,11 @@ static inline int net_pollsetup(FAR struct socket *psock, #ifdef CONFIG_NET_TCPBACKLOG /* Check for read data or backlogged connection availability now */ - if (!sq_empty(&conn->readahead) || uip_backlogavailable(conn)) + if (!IOB_QEMPTY(&conn->readahead) || uip_backlogavailable(conn)) #else /* Check for read data availability now */ - if (!sq_empty(&conn->readahead)) + if (!IOB_QEMPTY(&conn->readahead)) #endif { /* Normal data may be read without blocking. */ diff --git a/nuttx/net/recvfrom.c b/nuttx/net/recvfrom.c index 79e1e339b..5c6a5aa07 100644 --- a/nuttx/net/recvfrom.c +++ b/nuttx/net/recvfrom.c @@ -80,7 +80,7 @@ struct recvfrom_s FAR struct uip_callback_s *rf_cb; /* Reference to callback instance */ sem_t rf_sem; /* Semaphore signals recv completion */ size_t rf_buflen; /* Length of receive buffer */ - char *rf_buffer; /* Pointer to receive buffer */ + uint8_t *rf_buffer; /* Pointer to receive buffer */ #ifdef CONFIG_NET_IPv6 FAR struct sockaddr_in6 *rf_from; /* Address of sender */ #else @@ -316,69 +316,63 @@ static inline void recvfrom_newudpdata(FAR struct uip_driver_s *dev, #if defined(CONFIG_NET_TCP) && defined(CONFIG_NET_TCP_READAHEAD) static inline void recvfrom_readahead(struct recvfrom_s *pstate) { - FAR struct uip_conn *conn = (FAR struct uip_conn *)pstate->rf_sock->s_conn; - FAR struct uip_readahead_s *readahead; - size_t recvlen; + FAR struct uip_conn *conn = (FAR struct uip_conn *)pstate->rf_sock->s_conn; + FAR struct iob_s *iob; + int recvlen; /* Check there is any TCP data already buffered in a read-ahead * buffer. */ - do + while ((iob = iob_peek_queue(&conn->readahead)) != NULL && + pstate->rf_buflen > 0) { - /* Get the read-ahead buffer at the head of the list (if any) */ + DEBUGASSERT(iob->io_pktlen > 0); - readahead = (struct uip_readahead_s *)sq_remfirst(&conn->readahead); - if (readahead) - { - /* We have a new buffer... transfer that buffered data into - * the user buffer. - * - * First, get the length of the data to transfer. - */ + /* Transfer that buffered data from the I/O buffer chain into + * the user buffer. + */ - if (readahead->rh_nbytes > pstate->rf_buflen) - { - recvlen = pstate->rf_buflen; - } - else - { - recvlen = readahead->rh_nbytes; - } + recvlen = iob_copyout(pstate->rf_buffer, iob, pstate->rf_buflen, 0); + nllvdbg("Received %d bytes (of %d)\n", recvlen, iob->io_pktlen); - if (recvlen > 0) - { - /* Copy the read-ahead data into the user buffer */ + /* Update the accumulated size of the data read */ - memcpy(pstate->rf_buffer, readahead->rh_buffer, recvlen); - nllvdbg("Received %d bytes (of %d)\n", recvlen, readahead->rh_nbytes); + pstate->rf_recvlen += recvlen; + pstate->rf_buffer += recvlen; + pstate->rf_buflen -= recvlen; - /* Update the accumulated size of the data read */ + /* If we took all of the ata from the I/O buffer chain is empty, then + * release it. If there is still data available in the I/O buffer + * chain, then just trim the data that we have taken from the + * beginning of the I/O buffer chain. + */ - pstate->rf_recvlen += recvlen; - pstate->rf_buffer += recvlen; - pstate->rf_buflen -= recvlen; - } + if (recvlen >= iob->io_pktlen) + { + FAR struct iob_s *tmp; - /* If the read-ahead buffer is empty, then release it. If not, then - * we will have to move the data down and return the buffer to the - * front of the list. + /* Remove the I/O buffer chain from the head of the read-ahead + * buffer queue. */ - if (recvlen < readahead->rh_nbytes) - { - readahead->rh_nbytes -= recvlen; - memcpy(readahead->rh_buffer, &readahead->rh_buffer[recvlen], - readahead->rh_nbytes); - sq_addfirst(&readahead->rh_node, &conn->readahead); - } - else - { - uip_tcpreadahead_release(readahead); - } + tmp = iob_remove_queue(&conn->readahead); + DEBUGASSERT(tmp == iob); + UNUSED(tmp); + + /* And free the I/O buffer chain */ + + (void)iob_free_chain(iob); + } + else + { + /* The bytes that we have received from the from of the I/O + * buffer chain. + */ + + (void)iob_trimhead(iob, recvlen); } } - while (readahead && pstate->rf_buflen > 0); } #endif /* CONFIG_NET_UDP || CONFIG_NET_TCP */ @@ -1252,10 +1246,10 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, #ifdef CONFIG_NET_TCP_READAHEAD recvfrom_readahead(&state); - /* The default return value is the number of bytes that we just copied into - * the user buffer. We will return this if the socket has become disconnected - * or if the user request was completely satisfied with data from the readahead - * buffers. + /* The default return value is the number of bytes that we just copied + * into the user buffer. We will return this if the socket has become + * disconnected or if the user request was completely satisfied with + * data from the readahead buffers. */ ret = state.rf_recvlen; diff --git a/nuttx/net/tcp/Kconfig b/nuttx/net/tcp/Kconfig index dacb96395..b46b1ab84 100644 --- a/nuttx/net/tcp/Kconfig +++ b/nuttx/net/tcp/Kconfig @@ -36,6 +36,7 @@ config NET_MAX_LISTENPORTS config NET_TCP_READAHEAD bool "Enable TCP/IP read-ahead buffering" default y + select NET_IOB ---help--- Read-ahead buffers allows buffering of TCP/IP packets when there is no receive in place to catch the TCP packet. In that case, the packet @@ -43,40 +44,14 @@ config NET_TCP_READAHEAD You might want to disable TCP/IP read-ahead buffering on a highly memory constrained system that does not have any TCP/IP packet rate - issues. - -if NET_TCP_READAHEAD - -config NET_TCP_READAHEAD_BUFSIZE - int "TCP/IP read-ahead buffer size" - default 1220 if !NET_SLIP && NET_IPv6 - default 536 if !NET_SLIP && !NET_IPv6 - default 256 if NET_SLIP && !NET_IPv6 - ---help--- - Read-ahead buffers allows buffering of TCP/IP packets when there is no - receive in place to catch the TCP packet. In that case, the packet - will be retained in the NuttX read-ahead buffers. - - This setting specifies the size of one TCP/IP read-ahead buffer. - This should best be a equal to the maximum packet payload size (MSS). + issues. But, if disabled, there will probably be more packet + retransmissions or even packet loss. - Optimally, the size of the read-ahead buffer will should the maximum - size of an incoming TCP packet payload (MSS). This MSS value is - determined by NET_BUFSIZE minus the size of TCP, IP, and Ethernet - headers (assuming you are using the Ethernet transport). IPv4 hosts - are required to be able to handle an MSS of 536 octets and IPv6 hosts - are required to be able to handle an MSS of 1220 octets. - -config NET_NTCP_READAHEAD_BUFFERS - int "Number of TCP/IP read-ahead buffers" - default 8 - ---help--- - Read-ahead buffers allows buffering of TCP/IP packets when there is no - receive in place to catch the TCP packet. In that case, the packet - will be retained in the NuttX read-ahead buffers. - - This setting specifies the number of TCP/IP read-ahead buffers. + Make sure that you check the setting in the I/O Buffering menu. + These settings are critical to the reasonable operation of read- + ahead buffering. +if NET_TCP_READAHEAD endif # NET_TCP_READAHEAD config NET_TCP_WRITE_BUFFERS diff --git a/nuttx/net/tcp/Make.defs b/nuttx/net/tcp/Make.defs index 609fa24bb..c2d5f66f5 100644 --- a/nuttx/net/tcp/Make.defs +++ b/nuttx/net/tcp/Make.defs @@ -53,11 +53,7 @@ NET_CSRCS += tcp_conn.c tcp_seqno.c tcp_poll.c tcp_timer.c tcp_send.c NET_CSRCS += tcp_input.c tcp_appsend.c tcp_listen.c tcp_callback.c NET_CSRCS += tcp_backlog.c -# TCP Buffering - -ifeq ($(CONFIG_NET_TCP_READAHEAD),y) -NET_CSRCS += tcp_readahead.c -endif +# TCP write buffering ifeq ($(CONFIG_NET_TCP_WRITE_BUFFERS),y) NET_CSRCS += tcp_wrbuffer.c diff --git a/nuttx/net/tcp/tcp_callback.c b/nuttx/net/tcp/tcp_callback.c index b05027c5b..f9a99d7ab 100644 --- a/nuttx/net/tcp/tcp_callback.c +++ b/nuttx/net/tcp/tcp_callback.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/tcp/tcp_callback.c * - * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -60,47 +60,6 @@ ****************************************************************************/ /**************************************************************************** - * Function: uip_readahead - * - * Description: - * Copy as much received data as possible into the read-ahead buffer - * - * Assumptions: - * This function is called at the interrupt level with interrupts disabled. - * - ****************************************************************************/ - -#ifdef CONFIG_NET_TCP_READAHEAD -static int uip_readahead(FAR struct uip_readahead_s *readahead, - FAR uint8_t *buf, int len) -{ - int available = CONFIG_NET_TCP_READAHEAD_BUFSIZE - readahead->rh_nbytes; - int recvlen = 0; - - if (len > 0 && available > 0) - { - /* Get the length of the data to buffer. */ - - if (len > available) - { - recvlen = available; - } - else - { - recvlen = len; - } - - /* Copy the new appdata into the read-ahead buffer */ - - memcpy(&readahead->rh_buffer[readahead->rh_nbytes], buf, recvlen); - readahead->rh_nbytes += recvlen; - } - - return recvlen; -} -#endif - -/**************************************************************************** * Function: uip_dataevent * * Description: @@ -141,17 +100,12 @@ uip_dataevent(FAR struct uip_driver_s *dev, FAR struct uip_conn *conn, nllvdbg("No listener on connection\n"); #ifdef CONFIG_NET_TCP_READAHEAD - /* Save as much data as possible in the read-ahead buffers */ - - recvlen = uip_datahandler(conn, buffer, buflen); - - /* There are several complicated buffering issues that are not addressed - * properly here. For example, what if we cannot buffer the entire - * packet? In that case, some data will be accepted but not ACKed. - * Therefore it will be resent and duplicated. Fixing this could be tricky. + /* Save as the packet data as in the read-ahead buffer. NOTE that + * partial packets will not be buffered. */ - if (recvlen < buflen) + recvlen = uip_datahandler(conn, buffer, buflen); + if (recvlen < buflen) #endif { /* There is no handler to receive new data and there are no free @@ -267,8 +221,8 @@ uint16_t uip_tcpcallback(struct uip_driver_s *dev, struct uip_conn *conn, * buflen - The number of bytes to copy to the read-ahead buffer. * * Returned value: - * The number of bytes actually buffered. This could be less than 'nbytes' - * if there is insufficient buffering available. + * The number of bytes actually buffered is returned. This will be either + * zero or equal to buflen; partial packets are not buffered. * * Assumptions: * - The caller has checked that UIP_NEWDATA is set in flags and that is no @@ -281,57 +235,44 @@ uint16_t uip_tcpcallback(struct uip_driver_s *dev, struct uip_conn *conn, uint16_t uip_datahandler(FAR struct uip_conn *conn, FAR uint8_t *buffer, uint16_t buflen) { - FAR struct uip_readahead_s *readahead1; - FAR struct uip_readahead_s *readahead2 = NULL; - uint16_t remaining; - uint16_t recvlen = 0; - - /* First, we need to determine if we have space to buffer the data. This - * needs to be verified before we actually begin buffering the data. We - * will use any remaining space in the last allocated read-ahead buffer - * plus as much one additional buffer. It is expected that the size of - * read-ahead buffers are tuned so that one full packet will always fit - * into one read-ahead buffer (for example if the buffer size is 420, then - * a read-ahead buffer of 366 will hold a full packet of TCP data). - */ + FAR struct iob_s *iob; + int ret; - readahead1 = (FAR struct uip_readahead_s*)conn->readahead.tail; - if ((readahead1 && - (CONFIG_NET_TCP_READAHEAD_BUFSIZE - readahead1->rh_nbytes) > buflen) || - (readahead2 = uip_tcpreadahead_alloc()) != NULL) + /* Allocate on I/O buffer to start the chain (throttling as necessary) */ + + iob = iob_alloc(true); + if (iob == NULL) { - /* We have buffer space. Now try to append add as much data as possible - * to the last read-ahead buffer attached to this connection. - */ + nlldbg("ERROR: Failed to create new I/O buffer chain\n"); + return 0; + } - remaining = buflen; - if (readahead1) - { - recvlen = uip_readahead(readahead1, buffer, remaining); - if (recvlen > 0) - { - buffer += recvlen; - remaining -= recvlen; - } - } + /* Copy the new appdata into the I/O buffer chain */ - /* Do we need to buffer into the newly allocated buffer as well? */ + ret = iob_copyin(iob, buffer, buflen, 0, true); + if (ret < 0) + { + /* On a failure, iob_copyin return a negated error value but does + * not free any I/O buffers. + */ - if (readahead2) - { - readahead2->rh_nbytes = 0; - recvlen += uip_readahead(readahead2, buffer, remaining); + nlldbg("ERROR: Failed to add data to the I/O buffer chain: %d\n", ret); + (void)iob_free_chain(iob); + return 0; + } - /* Save the read-ahead buffer in the connection structure where - * it can be found with recv() is called. - */ + /* Add the new I/O buffer chain to the tail of the read-ahead queue */ - sq_addlast(&readahead2->rh_node, &conn->readahead); - } + ret = iob_add_queue(iob, &conn->readahead); + if (ret < 0) + { + nlldbg("ERROR: Failed to queue the I/O buffer chain: %d\n", ret); + (void)iob_free_chain(iob); + return 0; } - nllvdbg("Buffered %d bytes (of %d)\n", recvlen, buflen); - return recvlen; + nllvdbg("Buffered %d bytes\n", buflen); + return buflen; } #endif /* CONFIG_NET_TCP_READAHEAD */ diff --git a/nuttx/net/tcp/tcp_conn.c b/nuttx/net/tcp/tcp_conn.c index 893c95642..573d8cbf9 100644 --- a/nuttx/net/tcp/tcp_conn.c +++ b/nuttx/net/tcp/tcp_conn.c @@ -317,9 +317,6 @@ void uip_tcpfree(struct uip_conn *conn) { FAR struct uip_callback_s *cb; FAR struct uip_callback_s *next; -#ifdef CONFIG_NET_TCP_READAHEAD - FAR struct uip_readahead_s *readahead; -#endif #ifdef CONFIG_NET_TCP_WRITE_BUFFERS FAR struct tcp_wrbuffer_s *wrbuffer; #endif @@ -357,10 +354,7 @@ void uip_tcpfree(struct uip_conn *conn) #ifdef CONFIG_NET_TCP_READAHEAD /* Release any read-ahead buffers attached to the connection */ - while ((readahead = (struct uip_readahead_s *)sq_remfirst(&conn->readahead)) != NULL) - { - uip_tcpreadahead_release(readahead); - } + iob_free_queue(&conn->readahead); #endif #ifdef CONFIG_NET_TCP_WRITE_BUFFERS @@ -545,7 +539,7 @@ struct uip_conn *uip_tcpaccept(struct uip_tcpip_hdr *buf) #ifdef CONFIG_NET_TCP_READAHEAD /* Initialize the list of TCP read-ahead buffers */ - sq_init(&conn->readahead); + IOB_QINIT(&conn->readahead); #endif #ifdef CONFIG_NET_TCP_WRITE_BUFFERS @@ -700,7 +694,7 @@ int uip_tcpconnect(struct uip_conn *conn, const struct sockaddr_in *addr) #ifdef CONFIG_NET_TCP_READAHEAD /* Initialize the list of TCP read-ahead buffers */ - sq_init(&conn->readahead); + IOB_QINIT(&conn->readahead); #endif #ifdef CONFIG_NET_TCP_WRITE_BUFFERS diff --git a/nuttx/net/tcp/tcp_readahead.c b/nuttx/net/tcp/tcp_readahead.c deleted file mode 100644 index 059abbc5c..000000000 --- a/nuttx/net/tcp/tcp_readahead.c +++ /dev/null @@ -1,143 +0,0 @@ -/**************************************************************************** - * net/tcp/tcp_readahead.c - * - * Copyright (C) 2007-2009, 2013-2014 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/net/netconfig.h> -#if defined(CONFIG_NET) && defined(CONFIG_NET_TCP) && defined(CONFIG_NET_TCP_READAHEAD) - -#include <queue.h> -#include <debug.h> - -#include <nuttx/net/uip.h> - -#include "uip/uip.h" - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/* Package all globals used by this logic into a structure */ - -struct readahead_s -{ - /* This is the list of available write buffers */ - - sq_queue_t freebuffers; - - /* These are the pre-allocated write buffers */ - - struct uip_readahead_s buffers[CONFIG_NET_NTCP_READAHEAD_BUFFERS]; -}; - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/* This is the state of the global read-ahead resource */ - -static struct readahead_s g_readahead; - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Function: uip_tcpreadahead_init - * - * Description: - * Initialize the list of free read-ahead buffers - * - * Assumptions: - * Called once early initialization. - * - ****************************************************************************/ - -void uip_tcpreadahead_init(void) -{ - int i; - - sq_init(&g_readahead.freebuffers); - for (i = 0; i < CONFIG_NET_NTCP_READAHEAD_BUFFERS; i++) - { - sq_addfirst(&g_readahead.buffers[i].rh_node, &g_readahead.freebuffers); - } -} - -/**************************************************************************** - * Function: uip_tcpreadahead_alloc - * - * Description: - * Allocate a TCP read-ahead buffer by taking a pre-allocated buffer from - * the free list. This function is called from TCP logic when new, - * incoming TCP data is received but there is no user logic receiving the - * the data. Note: kmalloc() cannot be used because this function is - * called from interrupt level. - * - * Assumptions: - * Called from interrupt level with interrupts disabled. - * - ****************************************************************************/ - -FAR struct uip_readahead_s *uip_tcpreadahead_alloc(void) -{ - return (FAR struct uip_readahead_s*)sq_remfirst(&g_readahead.freebuffers); -} - -/**************************************************************************** - * Function: uip_tcpreadahead_release - * - * Description: - * Release a TCP read-ahead buffer by returning the buffer to the free list. - * This function is called from user logic after it is consumed the buffered - * data. - * - * Assumptions: - * Called from user logic BUT with interrupts disabled. - * - ****************************************************************************/ - -void uip_tcpreadahead_release(FAR struct uip_readahead_s *readahead) -{ - sq_addfirst(&readahead->rh_node, &g_readahead.freebuffers); -} - -#endif /* CONFIG_NET && CONFIG_NET_TCP && CONFIG_NET_TCP_READAHEAD */ diff --git a/nuttx/net/tcp/tcp_send_buffered.c b/nuttx/net/tcp/tcp_send_buffered.c index 05a0e4bfb..f8fcb5715 100644 --- a/nuttx/net/tcp/tcp_send_buffered.c +++ b/nuttx/net/tcp/tcp_send_buffered.c @@ -414,7 +414,7 @@ static uint16_t send_interrupt(FAR struct uip_driver_s *dev, FAR void *pvconn, tmp = (FAR struct tcp_wrbuffer_s *)sq_remfirst(&conn->write_q); DEBUGASSERT(tmp == wrb); - UNUSED(wrb); + UNUSED(tmp); /* And return the write buffer to the free list */ diff --git a/nuttx/net/uip/uip.h b/nuttx/net/uip/uip.h index 91e804d0f..06c4b58ea 100644 --- a/nuttx/net/uip/uip.h +++ b/nuttx/net/uip/uip.h @@ -183,17 +183,6 @@ uint16_t uip_tcpcallback(FAR struct uip_driver_s *dev, uint16_t uip_datahandler(FAR struct uip_conn *conn, FAR uint8_t *buffer, uint16_t nbytes); #endif - -/* Defined in tcp_readahead.c ***********************************************/ - -#ifdef CONFIG_NET_TCP_READAHEAD -void uip_tcpreadahead_init(void); - -struct uip_readahead_s; -FAR struct uip_readahead_s *uip_tcpreadahead_alloc(void); -void uip_tcpreadahead_release(FAR struct uip_readahead_s *readahead); -#endif /* CONFIG_NET_TCP_READAHEAD */ - #endif /* CONFIG_NET_TCP */ #ifdef CONFIG_NET_UDP diff --git a/nuttx/net/uip/uip_initialize.c b/nuttx/net/uip/uip_initialize.c index a76f0a1bd..8b88d5cf8 100644 --- a/nuttx/net/uip/uip_initialize.c +++ b/nuttx/net/uip/uip_initialize.c @@ -139,18 +139,12 @@ void uip_initialize(void) uip_tcpinit(); - /* Initialize the TCP/IP read-ahead buffering */ - -#ifdef CONFIG_NET_TCP_READAHEAD - uip_tcpreadahead_init(); -#endif -#endif /* CONFIG_NET_TCP */ - /* Initialize the TCP/IP write buffering */ #ifdef CONFIG_NET_TCP_WRITE_BUFFERS tcp_wrbuffer_initialize(); #endif +#endif /* CONFIG_NET_TCP */ /* Initialize the UDP connection structures */ |