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 16:53:36 UTC

[incubator-nuttx] 02/02: 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 pr113
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 7c7750b39cc2ba13a8547fbf2d80392fa669ebef
Author: chao.an <an...@xiaomi.com>
AuthorDate: Wed Jan 15 16:33:46 2020 +0800

    net/udp: break the network lock to avoid deadlock
    
    network deadlock when udp sendto() storm is coming
    
    refer:
    
    commit d3cedfb8233700210a391ecdd15f8e1d3a8f99c9
    Author: Valmantas Paliksa <wa...@gmail.com>
    Date:   Wed May 29 07:26:26 2019 -0600
    
        net/tcp/tcp_send_buffered.c: Fix deadlock in iob_copyin when iob buffers are exhausted and network lock is taken.
    
    Change-Id: I6613579b02afe8a09400dc6220d13f16f6ffdfb2
    Signed-off-by: chao.an <an...@xiaomi.com>
---
 net/udp/udp_psock_sendto_buffered.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

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)