You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2020/01/16 17:27:02 UTC
[incubator-nuttx] branch master updated: net/udp: break the network
lock to avoid deadlock
This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 2d0baa7 net/udp: break the network lock to avoid deadlock
2d0baa7 is described below
commit 2d0baa779d997f39b8121f5965f8125184e80d71
Author: chao.an <an...@xiaomi.com>
AuthorDate: Thu Jan 16 14:20:09 2020 -0300
net/udp: break the network lock to avoid deadlock
Author: chao.an <an...@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 <an...@xiaomi.com>
---
net/inet/inet_close.c | 24 +++++++++++++-----------
net/udp/udp_psock_sendto_buffered.c | 14 ++++++++++++++
2 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/net/inet/inet_close.c b/net/inet/inet_close.c
index 2b26a63..dd5dd83 100644
--- a/net/inet/inet_close.c
+++ b/net/inet/inet_close.c
@@ -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,21 +437,21 @@ static inline int udp_close(FAR struct socket *psock)
if (_SO_GETOPT(psock->s_options, SO_LINGER))
{
- int ret;
+ timeout = _SO_TIMEOUT(psock->s_linger);
+ }
+#endif
- /* Wait until for the buffered TX data to be sent. */
+ /* 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.
- */
+ 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);
- }
+ nerr("ERROR: udp_txdrain() failed: %d\n", ret);
}
-#endif
#ifdef CONFIG_NET_UDP_WRITE_BUFFERS
/* Free any semi-permanent write buffer callback in place. */
diff --git a/net/udp/udp_psock_sendto_buffered.c b/net/udp/udp_psock_sendto_buffered.c
index 0dcf892..fbc44de 100644
--- a/net/udp/udp_psock_sendto_buffered.c
+++ b/net/udp/udp_psock_sendto_buffered.c
@@ -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)