net/udp: break the network lock to avoid deadlock
Author: chao.an <anchao@xiaomi.com> net/udp: break the network lock to avoid deadlock network deadlock when udp sendto() storm is coming net/close: force wait tx drain to complete atomic send() and close() will causes data to be discarded directly Signed-off-by: chao.an <anchao@xiaomi.com>
This commit is contained in:
parent
b3fd644f1b
commit
2d0baa779d
@ -412,6 +412,8 @@ static inline int tcp_close_disconnect(FAR struct socket *psock)
|
||||
static inline int udp_close(FAR struct socket *psock)
|
||||
{
|
||||
FAR struct udp_conn_s *conn;
|
||||
unsigned int timeout = UINT_MAX;
|
||||
int ret;
|
||||
|
||||
/* Interrupts are disabled here to avoid race conditions */
|
||||
|
||||
@ -435,22 +437,22 @@ static inline int udp_close(FAR struct socket *psock)
|
||||
|
||||
if (_SO_GETOPT(psock->s_options, SO_LINGER))
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Wait until for the buffered TX data to be sent. */
|
||||
|
||||
ret = udp_txdrain(psock, _SO_TIMEOUT(psock->s_linger));
|
||||
if (ret < 0)
|
||||
{
|
||||
/* udp_txdrain may fail, but that won't stop us from closing
|
||||
* the socket.
|
||||
*/
|
||||
|
||||
nerr("ERROR: udp_txdrain() failed: %d\n", ret);
|
||||
}
|
||||
timeout = _SO_TIMEOUT(psock->s_linger);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Wait until for the buffered TX data to be sent. */
|
||||
|
||||
ret = udp_txdrain(psock, timeout);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* udp_txdrain may fail, but that won't stop us from closing
|
||||
* the socket.
|
||||
*/
|
||||
|
||||
nerr("ERROR: udp_txdrain() failed: %d\n", ret);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_UDP_WRITE_BUFFERS
|
||||
/* Free any semi-permanent write buffer callback in place. */
|
||||
|
||||
|
@ -75,6 +75,7 @@
|
||||
#include "neighbor/neighbor.h"
|
||||
#include "udp/udp.h"
|
||||
#include "devif/devif.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
@ -713,8 +714,21 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf,
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int count;
|
||||
int blresult;
|
||||
|
||||
/* iob_copyin might wait for buffers to be freed, but if
|
||||
* network is locked this might never happen, since network
|
||||
* driver is also locked, therefore we need to break the lock
|
||||
*/
|
||||
|
||||
blresult = net_breaklock(&count);
|
||||
ret = iob_copyin(wrb->wb_iob, (FAR uint8_t *)buf, len, 0, false,
|
||||
IOBUSER_NET_SOCK_UDP);
|
||||
if (blresult >= 0)
|
||||
{
|
||||
net_restorelock(count);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
|
Loading…
Reference in New Issue
Block a user