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:
parent
4b351fc447
commit
64676641cb
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue