This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit e431cb00ca6e21512d0f3a0198f80114ae529b25
Author: zhanghongyu <[email protected]>
AuthorDate: Wed Jun 18 11:15:51 2025 +0800

    net/pkt: replace net_lock with netdev_lock
    
    protect PKT resources through netdev_lock, conn_lock, and pkt_list_lock
    
    Signed-off-by: zhanghongyu <[email protected]>
---
 net/devif/devif_poll.c           |  2 ++
 net/pkt/pkt.h                    | 26 +++++++++++++++++++++++++
 net/pkt/pkt_callback.c           |  3 +++
 net/pkt/pkt_conn.c               | 33 ++++++++++++++++++++++++++++++++
 net/pkt/pkt_input.c              | 10 +++++++++-
 net/pkt/pkt_netpoll.c            | 41 +++++++++++++++++++++-------------------
 net/pkt/pkt_recvmsg.c            | 25 ++++++++++++------------
 net/pkt/pkt_sendmsg_buffered.c   | 18 +++++-------------
 net/pkt/pkt_sendmsg_unbuffered.c |  8 ++++++--
 net/pkt/pkt_sockif.c             | 12 +++++++++---
 10 files changed, 128 insertions(+), 50 deletions(-)

diff --git a/net/devif/devif_poll.c b/net/devif/devif_poll.c
index 9f7d6ca9d1e..1bb4e46cbef 100644
--- a/net/devif/devif_poll.c
+++ b/net/devif/devif_poll.c
@@ -236,6 +236,7 @@ static int devif_poll_pkt_connections(FAR struct 
net_driver_s *dev,
    * action.
    */
 
+  pkt_conn_list_lock();
   while (!bstop && (pkt_conn = pkt_nextconn(pkt_conn)))
     {
       /* Skip packet connections that are bound to other polling devices */
@@ -259,6 +260,7 @@ static int devif_poll_pkt_connections(FAR struct 
net_driver_s *dev,
         }
     }
 
+  pkt_conn_list_unlock();
   return bstop;
 }
 #endif /* CONFIG_NET_PKT */
diff --git a/net/pkt/pkt.h b/net/pkt/pkt.h
index 767776b7f7c..b4c90eefcba 100644
--- a/net/pkt/pkt.h
+++ b/net/pkt/pkt.h
@@ -205,6 +205,32 @@ int pkt_sendmsg_is_valid(FAR struct socket *psock,
                          FAR const struct msghdr *msg,
                          FAR struct net_driver_s **dev);
 
+/****************************************************************************
+ * Name: pkt_conn_list_lock()
+ *
+ * Description:
+ *   Lock the packet connection list
+ *
+ * Assumptions:
+ *   This function must be called by driver thread.
+ *
+ ****************************************************************************/
+
+void pkt_conn_list_lock(void);
+
+/****************************************************************************
+ * Name: pkt_conn_list_unlock()
+ *
+ * Description:
+ *   Unlock the packet connection list
+ *
+ * Assumptions:
+ *   This function must be called by driver thread.
+ *
+ ****************************************************************************/
+
+void pkt_conn_list_unlock(void);
+
 /****************************************************************************
  * Name: pkt_callback
  *
diff --git a/net/pkt/pkt_callback.c b/net/pkt/pkt_callback.c
index 02ff88c7e28..4b74c1d3b55 100644
--- a/net/pkt/pkt_callback.c
+++ b/net/pkt/pkt_callback.c
@@ -35,6 +35,7 @@
 
 #include "devif/devif.h"
 #include "pkt/pkt.h"
+#include "utils/utils.h"
 
 /****************************************************************************
  * Public Functions
@@ -65,7 +66,9 @@ uint16_t pkt_callback(FAR struct net_driver_s *dev,
     {
       /* Perform the callback */
 
+      conn_lock(&conn->sconn);
       flags = devif_conn_event(dev, flags, conn->sconn.list);
+      conn_unlock(&conn->sconn);
     }
 
   return flags;
diff --git a/net/pkt/pkt_conn.c b/net/pkt/pkt_conn.c
index 46cb3c27f2b..0669cc7f8ea 100644
--- a/net/pkt/pkt_conn.c
+++ b/net/pkt/pkt_conn.c
@@ -127,6 +127,7 @@ void pkt_free(FAR struct pkt_conn_s *conn)
   /* Remove the connection from the active list */
 
   dq_rem(&conn->sconn.node, &g_active_pkt_connections);
+  nxmutex_destroy(&conn->sconn.s_lock);
 
 #ifdef CONFIG_NET_PKT_WRITE_BUFFERS
   /* Free the write queue */
@@ -279,4 +280,36 @@ int pkt_sendmsg_is_valid(FAR struct socket *psock,
   return OK;
 }
 
+/****************************************************************************
+ * Name: pkt_conn_list_lock()
+ *
+ * Description:
+ *   Lock the packet connection list
+ *
+ * Assumptions:
+ *   This function must be called by driver thread.
+ *
+ ****************************************************************************/
+
+void pkt_conn_list_lock(void)
+{
+  NET_BUFPOOL_LOCK(g_pkt_connections);
+}
+
+/****************************************************************************
+ * Name: pkt_conn_list_unlock()
+ *
+ * Description:
+ *   Unlock the packet connection list
+ *
+ * Assumptions:
+ *   This function must be called by driver thread.
+ *
+ ****************************************************************************/
+
+void pkt_conn_list_unlock(void)
+{
+  NET_BUFPOOL_UNLOCK(g_pkt_connections);
+}
+
 #endif /* CONFIG_NET && CONFIG_NET_PKT */
diff --git a/net/pkt/pkt_input.c b/net/pkt/pkt_input.c
index d2d7611b981..320eef7dc99 100644
--- a/net/pkt/pkt_input.c
+++ b/net/pkt/pkt_input.c
@@ -36,6 +36,7 @@
 
 #include "devif/devif.h"
 #include "pkt/pkt.h"
+#include "utils/utils.h"
 #include "socket/socket.h"
 
 /****************************************************************************
@@ -102,7 +103,11 @@ static uint16_t pkt_datahandler(FAR struct net_driver_s 
*dev,
    * without waiting).
    */
 
-  if ((ret = iob_tryadd_queue(iob, &conn->readahead)) < 0)
+  conn_lock(&conn->sconn);
+  ret = iob_tryadd_queue(iob, &conn->readahead);
+  conn_unlock(&conn->sconn);
+
+  if (ret < 0)
     {
       nerr("ERROR: Failed to queue the I/O buffer chain: %d\n", ret);
       goto errout;
@@ -151,6 +156,7 @@ static int pkt_in(FAR struct net_driver_s *dev)
   FAR struct pkt_conn_s *conn;
   int ret = OK;
 
+  pkt_conn_list_lock();
   conn = pkt_active(dev);
   if (conn)
     {
@@ -161,6 +167,7 @@ static int pkt_in(FAR struct net_driver_s *dev)
           /* Do not read back the packet sent by oneself */
 
           conn->pendiob = NULL;
+          pkt_conn_list_unlock();
           return OK;
         }
 
@@ -207,6 +214,7 @@ static int pkt_in(FAR struct net_driver_s *dev)
       ninfo("No PKT listener\n");
     }
 
+  pkt_conn_list_unlock();
   return ret;
 }
 
diff --git a/net/pkt/pkt_netpoll.c b/net/pkt/pkt_netpoll.c
index 652848acea4..5c52498efa9 100644
--- a/net/pkt/pkt_netpoll.c
+++ b/net/pkt/pkt_netpoll.c
@@ -38,6 +38,7 @@
 #include "devif/devif.h"
 #include "netdev/netdev.h"
 #include "socket/socket.h"
+#include "utils/utils.h"
 #include "pkt/pkt.h"
 
 /****************************************************************************
@@ -172,18 +173,24 @@ int pkt_pollsetup(FAR struct socket *psock, FAR struct 
pollfd *fds)
 
   /* Some of the following must be atomic */
 
-  net_lock();
-
   conn = psock->s_conn;
 
   /* Sanity check */
 
   if (conn == NULL || fds == NULL)
     {
-      ret = -EINVAL;
-      goto errout_with_lock;
+      return -EINVAL;
     }
 
+  dev = pkt_find_device(conn);
+  if (dev == NULL)
+    {
+      nerr("ERROR: No device found for PKT connection\n");
+      return -ENODEV;
+    }
+
+  conn_dev_lock(&conn->sconn, dev);
+
   /* Find a container to hold the poll information */
 
   info = conn->pollinfo;
@@ -196,10 +203,6 @@ int pkt_pollsetup(FAR struct socket *psock, FAR struct 
pollfd *fds)
         }
     }
 
-  /* Get the device that will provide the provide the NETDEV_DOWN event. */
-
-  dev = pkt_find_device(conn);
-
   /* Allocate a PKT callback structure */
 
   cb = pkt_callback_alloc(dev, conn);
@@ -263,7 +266,7 @@ int pkt_pollsetup(FAR struct socket *psock, FAR struct 
pollfd *fds)
   poll_notify(&fds, 1, eventset);
 
 errout_with_lock:
-  net_unlock();
+  conn_dev_unlock(&conn->sconn, dev);
   return ret;
 }
 
@@ -289,30 +292,30 @@ int pkt_pollteardown(FAR struct socket *psock, FAR struct 
pollfd *fds)
   FAR struct pkt_poll_s   *info;
   FAR struct net_driver_s *dev;
 
-  /* Some of the following must be atomic */
-
-  net_lock();
-
   conn = psock->s_conn;
 
   /* Sanity check */
 
   if (!conn || !fds->priv)
     {
-      net_unlock();
       return -EINVAL;
     }
 
+  dev = pkt_find_device(conn);
+  if (dev == NULL)
+    {
+      nerr("ERROR: No device found for PKT connection\n");
+      return -ENODEV;
+    }
+
+  conn_dev_lock(&conn->sconn, dev);
+
   /* Recover the socket descriptor poll state info from the poll structure */
 
   info = (FAR struct pkt_poll_s *)fds->priv;
   DEBUGASSERT(info->fds != NULL && info->cb != NULL);
   if (info != NULL)
     {
-      /* Get the device that will provide the NETDEV_DOWN event. */
-
-      dev = pkt_find_device(conn);
-
       /* Release the callback */
 
       pkt_callback_free(dev, conn, info->cb);
@@ -326,7 +329,7 @@ int pkt_pollteardown(FAR struct socket *psock, FAR struct 
pollfd *fds)
       info->conn = NULL;
     }
 
-  net_unlock();
+  conn_dev_unlock(&conn->sconn, dev);
 
   return OK;
 }
diff --git a/net/pkt/pkt_recvmsg.c b/net/pkt/pkt_recvmsg.c
index 8d3b179ca4d..756b2e0ebb0 100644
--- a/net/pkt/pkt_recvmsg.c
+++ b/net/pkt/pkt_recvmsg.c
@@ -47,6 +47,7 @@
 #include "devif/devif.h"
 #include "pkt/pkt.h"
 #include "socket/socket.h"
+#include "utils/utils.h"
 #include <netpacket/packet.h>
 
 /****************************************************************************
@@ -500,6 +501,14 @@ ssize_t pkt_recvmsg(FAR struct socket *psock, FAR struct 
msghdr *msg,
       ret = -ENOSYS;
     }
 
+  /* Get the device driver that will service this transfer */
+
+  dev  = pkt_find_device(conn);
+  if (dev == NULL)
+    {
+      return -ENODEV;
+    }
+
   /* Perform the packet recvfrom() operation */
 
   /* Initialize the state structure.  This is done with the network
@@ -508,7 +517,7 @@ ssize_t pkt_recvmsg(FAR struct socket *psock, FAR struct 
msghdr *msg,
 
   pkt_recvfrom_initialize(conn, msg, &state, psock->s_type);
 
-  net_lock();
+  conn_dev_lock(&conn->sconn, dev);
 
   /* Check if there is buffered read-ahead data for this socket.  We may have
    * already received the response to previous command.
@@ -528,15 +537,6 @@ ssize_t pkt_recvmsg(FAR struct socket *psock, FAR struct 
msghdr *msg,
     }
   else
     {
-      /* Get the device driver that will service this transfer */
-
-      dev  = pkt_find_device(conn);
-      if (dev == NULL)
-        {
-          ret = -ENODEV;
-          goto errout_with_state;
-        }
-
       /* TODO pkt_recvfrom_initialize() expects from to be of type
        * sockaddr_in, but in our case is sockaddr_ll
        */
@@ -565,7 +565,9 @@ ssize_t pkt_recvmsg(FAR struct socket *psock, FAR struct 
msghdr *msg,
            * the task restarts.
            */
 
+          conn_dev_unlock(&conn->sconn, dev);
           ret = net_sem_wait(&state.pr_sem);
+          conn_dev_lock(&conn->sconn, dev);
 
           /* Make sure that no further events are processed */
 
@@ -578,9 +580,8 @@ ssize_t pkt_recvmsg(FAR struct socket *psock, FAR struct 
msghdr *msg,
         }
     }
 
-  net_unlock();
+  conn_dev_unlock(&conn->sconn, dev);
 
-errout_with_state:
   pkt_recvfrom_uninitialize(&state);
 
   return ret;
diff --git a/net/pkt/pkt_sendmsg_buffered.c b/net/pkt/pkt_sendmsg_buffered.c
index baf4d89aaa0..8d6b9b43b9d 100644
--- a/net/pkt/pkt_sendmsg_buffered.c
+++ b/net/pkt/pkt_sendmsg_buffered.c
@@ -230,8 +230,6 @@ ssize_t pkt_sendmsg(FAR struct socket *psock, FAR const 
struct msghdr *msg,
       return 0;
     }
 
-  net_lock();
-
   conn = psock->s_conn;
   if (psock->s_type == SOCK_DGRAM)
     {
@@ -240,6 +238,7 @@ ssize_t pkt_sendmsg(FAR struct socket *psock, FAR const 
struct msghdr *msg,
       conn->ifindex = addr->sll_ifindex;
     }
 
+  conn_dev_lock(&conn->sconn, dev);
   nonblock = _SS_ISNONBLOCK(conn->sconn.s_flags) ||
              (flags & MSG_DONTWAIT) != 0;
 
@@ -309,20 +308,14 @@ ssize_t pkt_sendmsg(FAR struct socket *psock, FAR const 
struct msghdr *msg,
     }
   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);
+      conn_dev_unlock(&conn->sconn, dev);
       ret = iob_copyin(iob, buf, len, offset, false);
-      if (blresult >= 0)
-        {
-          net_restorelock(count);
-        }
+      conn_dev_lock(&conn->sconn, dev);
     }
 
   if (ret < 0)
@@ -379,21 +372,20 @@ ssize_t pkt_sendmsg(FAR struct socket *psock, FAR const 
struct msghdr *msg,
       conn->sndcb->flags = PKT_POLL;
       conn->sndcb->priv  = conn;
       conn->sndcb->event = psock_send_eventhandler;
+      conn_dev_unlock(&conn->sconn, dev);
 
       /* Notify the device driver that new TX data is available. */
 
       netdev_txnotify_dev(dev);
     }
 
-  net_unlock();
-
   return len;
 
 errout_with_iob:
   iob_free_chain(iob);
 
 errout_with_lock:
-  net_unlock();
+  conn_dev_unlock(&conn->sconn, dev);
 
   return ret;
 }
diff --git a/net/pkt/pkt_sendmsg_unbuffered.c b/net/pkt/pkt_sendmsg_unbuffered.c
index 65d306cccc0..6715b4d5e58 100644
--- a/net/pkt/pkt_sendmsg_unbuffered.c
+++ b/net/pkt/pkt_sendmsg_unbuffered.c
@@ -47,6 +47,7 @@
 #include "netdev/netdev.h"
 #include "devif/devif.h"
 #include "socket/socket.h"
+#include "utils/utils.h"
 #include "pkt/pkt.h"
 
 /****************************************************************************
@@ -213,7 +214,7 @@ ssize_t pkt_sendmsg(FAR struct socket *psock, FAR struct 
msghdr *msg,
    * because we don't want anything to happen until we are ready.
    */
 
-  net_lock();
+  conn_dev_lock(&conn->sconn, dev);
   memset(&state, 0, sizeof(struct send_s));
   nxsem_init(&state.snd_sem, 0, 0); /* Doesn't really fail */
 
@@ -236,6 +237,8 @@ ssize_t pkt_sendmsg(FAR struct socket *psock, FAR struct 
msghdr *msg,
           state.snd_cb->priv  = (FAR void *)&state;
           state.snd_cb->event = psock_send_eventhandler;
 
+          conn_dev_unlock(&conn->sconn, dev);
+
           /* Notify the device driver that new TX data is available. */
 
           netdev_txnotify_dev(dev);
@@ -245,6 +248,7 @@ ssize_t pkt_sendmsg(FAR struct socket *psock, FAR struct 
msghdr *msg,
            */
 
           ret = net_sem_wait(&state.snd_sem);
+          conn_dev_lock(&conn->sconn, dev);
 
           /* Make sure that no further events are processed */
 
@@ -253,7 +257,7 @@ ssize_t pkt_sendmsg(FAR struct socket *psock, FAR struct 
msghdr *msg,
     }
 
   nxsem_destroy(&state.snd_sem);
-  net_unlock();
+  conn_dev_unlock(&conn->sconn, dev);
 
   /* Check for errors.  Errors are signalled by negative errno values
    * for the send length
diff --git a/net/pkt/pkt_sockif.c b/net/pkt/pkt_sockif.c
index f720eb3eed5..17c2120e4f1 100644
--- a/net/pkt/pkt_sockif.c
+++ b/net/pkt/pkt_sockif.c
@@ -41,6 +41,7 @@
 
 #include "devif/devif.h"
 #include "netdev/netdev.h"
+#include "utils/utils.h"
 #include <socket/socket.h>
 #include "pkt/pkt.h"
 
@@ -132,6 +133,8 @@ static int pkt_sockif_alloc(FAR struct socket *psock)
   nxsem_init(&conn->sndsem, 0, 0);
 #endif
 
+  nxmutex_init(&conn->sconn.s_lock);
+
   /* Save the pre-allocated connection in the socket structure */
 
   psock->s_conn = conn;
@@ -354,6 +357,7 @@ static int pkt_close(FAR struct socket *psock)
       case SOCK_CTRL:
         {
           FAR struct pkt_conn_s *conn = psock->s_conn;
+          FAR struct net_driver_s *dev = pkt_find_device(conn);
 
           /* Is this the last reference to the connection structure (there
            * could be more if the socket was dup'ed).
@@ -361,6 +365,8 @@ static int pkt_close(FAR struct socket *psock)
 
           if (conn->crefs <= 1)
             {
+              conn_dev_lock(&conn->sconn, dev);
+
               /* Yes... free any read-ahead data */
 
               iob_free_queue(&conn->readahead);
@@ -370,21 +376,20 @@ static int pkt_close(FAR struct socket *psock)
 
               if (conn->sndcb != NULL)
                 {
-                  FAR struct net_driver_s *dev;
                   int ret;
 
                   while (iob_get_queue_entry_count(&conn->write_q) != 0)
                     {
+                      conn_dev_unlock(&conn->sconn, dev);
                       ret = net_sem_timedwait_uninterruptible(&conn->sndsem,
                             _SO_TIMEOUT(conn->sconn.s_sndtimeo));
+                      conn_dev_lock(&conn->sconn, dev);
                       if (ret < 0)
                         {
                           break;
                         }
                     }
 
-                  dev = pkt_find_device(conn);
-
                   pkt_callback_free(dev, conn, conn->sndcb);
                   conn->sndcb = NULL;
                 }
@@ -393,6 +398,7 @@ static int pkt_close(FAR struct socket *psock)
               /* Then free the connection structure */
 
               conn->crefs = 0;          /* No more references on the 
connection */
+              conn_dev_unlock(&conn->sconn, dev);
               pkt_free(psock->s_conn);  /* Free network resources */
             }
           else

Reply via email to