tcp_datahandler: try throttled=false on iob_trycopyin failure as well

I assume this was just an oversight because I couldn't
find any obvious reason to special-case only the first IOB.

The commit message of the original commit is cited below.

```
commit bf21056001
Author: chao.an <anchao@xiaomi.com>
Date:   Fri Nov 27 09:50:38 2020 +0800

    net/tcp: fallback to unthrottle pool to avoid deadlock

    Add a fallback mechanism to ensure that there are still available
    iobs for an free connection, Guarantees all connections will have
    a minimum threshold iob to keep the connection not be hanged.

    Change-Id: I59bed98d135ccd1f16264b9ccacdd1b0d91261de
    Signed-off-by: chao.an <anchao@xiaomi.com>
```
This commit is contained in:
YAMAMOTO Takashi 2021-06-08 10:09:01 +09:00 committed by Xiang Xiao
parent 4b351fc447
commit 64676641cb
1 changed files with 24 additions and 23 deletions

View File

@ -233,43 +233,44 @@ uint16_t tcp_datahandler(FAR struct tcp_conn_s *conn, FAR uint8_t *buffer,
bool throttled = true;
int ret;
/* Try to allocate on I/O buffer to start the chain without waiting (and
* throttling as necessary). If we would have to wait, then drop the
* packet.
/* Try to allocate I/O buffers and copy the data into them
* without waiting (and throttling as necessary).
*/
iob = iob_tryalloc(throttled, IOBUSER_NET_TCP_READAHEAD);
if (iob == NULL)
while (true)
{
iob = iob_tryalloc(throttled, IOBUSER_NET_TCP_READAHEAD);
if (iob != NULL)
{
ret = iob_trycopyin(iob, buffer, buflen, 0, throttled,
IOBUSER_NET_TCP_READAHEAD);
if (ret < 0)
{
/* On a failure, iob_copyin return a negated error value but
* does not free any I/O buffers.
*/
iob_free_chain(iob, IOBUSER_NET_TCP_READAHEAD);
iob = NULL;
}
}
#if CONFIG_IOB_THROTTLE > 0
if (IOB_QEMPTY(&conn->readahead))
if (iob == NULL && throttled && IOB_QEMPTY(&conn->readahead))
{
/* Fallback out of the throttled entry */
throttled = false;
iob = iob_tryalloc(throttled, IOBUSER_NET_TCP_READAHEAD);
continue;
}
#endif
if (iob == NULL)
{
nerr("ERROR: Failed to create new I/O buffer chain\n");
return 0;
}
break;
}
/* Copy the new appdata into the I/O buffer chain (without waiting) */
ret = iob_trycopyin(iob, buffer, buflen, 0, throttled,
IOBUSER_NET_TCP_READAHEAD);
if (ret < 0)
if (iob == NULL)
{
/* On a failure, iob_copyin return a negated error value but does
* not free any I/O buffers.
*/
nerr("ERROR: Failed to add data to the I/O buffer chain: %d\n", ret);
iob_free_chain(iob, IOBUSER_NET_TCP_READAHEAD);
nerr("ERROR: Failed to create new I/O buffer chain\n");
return 0;
}