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 0af74a54bb604e6913bf833a0ac94afe5216541f
Author: zhanghongyu <[email protected]>
AuthorDate: Mon Jun 16 17:38:55 2025 +0800

    net/netdev: separate netdev_list_lock from net_lock
    
    use netdev_list_lock to protect all network card traversal, registration,
    and deregistration operations.
    
    Signed-off-by: zhanghongyu <[email protected]>
---
 net/ipfrag/ipfrag.c             |  8 ++++----
 net/netdev/netdev.h             | 21 +++++++++++++++++++++
 net/netdev/netdev_count.c       |  4 ++--
 net/netdev/netdev_default.c     |  4 ++--
 net/netdev/netdev_findbyaddr.c  |  8 ++++----
 net/netdev/netdev_findbyindex.c | 14 +++++++-------
 net/netdev/netdev_findbyname.c  |  6 +++---
 net/netdev/netdev_register.c    | 39 ++++++++++++++++++++++++++++++++++++---
 net/netdev/netdev_unregister.c  |  4 ++--
 net/netdev/netdev_verify.c      |  4 ++--
 net/tcp/tcp_conn.c              |  5 +++++
 net/udp/udp_conn.c              |  4 ++++
 12 files changed, 92 insertions(+), 29 deletions(-)

diff --git a/net/ipfrag/ipfrag.c b/net/ipfrag/ipfrag.c
index 0e65f050576..09618dbd8a9 100644
--- a/net/ipfrag/ipfrag.c
+++ b/net/ipfrag/ipfrag.c
@@ -1078,7 +1078,7 @@ int32_t ip_frag_uninit(void)
 
   /* Release frag processing resources of each NIC */
 
-  net_lock();
+  netdev_list_lock();
   for (dev = g_netdevices; dev; dev = dev->flink)
     {
       /* Is the interface in the "up" state? */
@@ -1089,7 +1089,7 @@ int32_t ip_frag_uninit(void)
         }
     }
 
-  net_unlock();
+  netdev_list_unlock();
 
   return OK;
 }
@@ -1209,7 +1209,7 @@ void ip_frag_remallfrags(void)
 
   /* Drop all unsent outgoing fragments */
 
-  net_lock();
+  netdev_list_lock();
   for (dev = g_netdevices; dev; dev = dev->flink)
     {
       /* Is the interface in the "up" state? */
@@ -1220,7 +1220,7 @@ void ip_frag_remallfrags(void)
         }
     }
 
-  net_unlock();
+  netdev_list_unlock();
 }
 
 /****************************************************************************
diff --git a/net/netdev/netdev.h b/net/netdev/netdev.h
index 05a3866f891..5f4a541cb19 100644
--- a/net/netdev/netdev.h
+++ b/net/netdev/netdev.h
@@ -533,6 +533,27 @@ void netdev_notify_recvcpu(FAR struct net_driver_s *dev,
                            FAR const void *dst_addr, uint16_t dst_port);
 #endif
 
+/****************************************************************************
+ * Name: netdev_list_lock
+ *
+ * Description:
+ *   Lock the network device list.  This is used to protect the network
+ *   device list from concurrent access.
+ *
+ ****************************************************************************/
+
+void netdev_list_lock(void);
+
+/****************************************************************************
+ * Name: netdev_list_unlock
+ *
+ * Description:
+ *   Unlock the network device list.
+ *
+ ****************************************************************************/
+
+void netdev_list_unlock(void);
+
 #undef EXTERN
 #ifdef __cplusplus
 }
diff --git a/net/netdev/netdev_count.c b/net/netdev/netdev_count.c
index e0e634d2b57..0c201699247 100644
--- a/net/netdev/netdev_count.c
+++ b/net/netdev/netdev_count.c
@@ -57,8 +57,8 @@ int netdev_count(void)
   struct net_driver_s *dev;
   int ndev;
 
-  net_lock();
+  netdev_list_lock();
   for (dev = g_netdevices, ndev = 0; dev; dev = dev->flink, ndev++);
-  net_unlock();
+  netdev_list_unlock();
   return ndev;
 }
diff --git a/net/netdev/netdev_default.c b/net/netdev/netdev_default.c
index 187734d9209..99c520f11ee 100644
--- a/net/netdev/netdev_default.c
+++ b/net/netdev/netdev_default.c
@@ -63,7 +63,7 @@ FAR struct net_driver_s *netdev_default(void)
 
   /* Examine each registered network device */
 
-  net_lock();
+  netdev_list_lock();
   for (dev = g_netdevices; dev; dev = dev->flink)
     {
       /* Is the interface in the "up" state? */
@@ -84,6 +84,6 @@ FAR struct net_driver_s *netdev_default(void)
         }
     }
 
-  net_unlock();
+  netdev_list_unlock();
   return ret;
 }
diff --git a/net/netdev/netdev_findbyaddr.c b/net/netdev/netdev_findbyaddr.c
index 98f01260b4c..b89ed6e43bf 100644
--- a/net/netdev/netdev_findbyaddr.c
+++ b/net/netdev/netdev_findbyaddr.c
@@ -80,7 +80,7 @@ netdev_prefixlen_findby_lipv4addr(in_addr_t lipaddr, FAR 
int8_t *prefixlen)
 
   /* Examine each registered network device */
 
-  net_lock();
+  netdev_list_lock();
   for (dev = g_netdevices; dev; dev = dev->flink)
     {
       /* Is the interface in the "up" state? */
@@ -141,7 +141,7 @@ netdev_prefixlen_findby_lipv4addr(in_addr_t lipaddr, FAR 
int8_t *prefixlen)
         }
     }
 
-  net_unlock();
+  netdev_list_unlock();
   *prefixlen = bestpref;
   return bestdev;
 }
@@ -180,7 +180,7 @@ netdev_prefixlen_findby_lipv6addr(const net_ipv6addr_t 
lipaddr,
   int16_t len;
 #endif
 
-  net_lock();
+  netdev_list_lock();
 
 #ifdef CONFIG_ROUTE_LONGEST_MATCH
   /* Find a hint from neighbor table in case same prefix length exists on
@@ -245,7 +245,7 @@ netdev_prefixlen_findby_lipv6addr(const net_ipv6addr_t 
lipaddr,
         }
     }
 
-  net_unlock();
+  netdev_list_unlock();
   *prefixlen = bestpref;
   return bestdev;
 }
diff --git a/net/netdev/netdev_findbyindex.c b/net/netdev/netdev_findbyindex.c
index 508422e9d9c..4ae0ef2142a 100644
--- a/net/netdev/netdev_findbyindex.c
+++ b/net/netdev/netdev_findbyindex.c
@@ -72,7 +72,7 @@ FAR struct net_driver_s *netdev_findbyindex(int ifindex)
 
 #endif
 
-  net_lock();
+  netdev_list_lock();
 
 #ifdef CONFIG_NETDEV_IFINDEX
   /* Check if this index has been assigned */
@@ -81,7 +81,7 @@ FAR struct net_driver_s *netdev_findbyindex(int ifindex)
     {
       /* This index has not been assigned */
 
-      net_unlock();
+      netdev_list_unlock();
       return NULL;
     }
 #endif
@@ -104,12 +104,12 @@ FAR struct net_driver_s *netdev_findbyindex(int ifindex)
       if (++i == ifindex)
 #endif
         {
-          net_unlock();
+          netdev_list_unlock();
           return dev;
         }
     }
 
-  net_unlock();
+  netdev_list_unlock();
   return NULL;
 }
 
@@ -141,7 +141,7 @@ int netdev_nextindex(int ifindex)
 
   if (ifindex >= 0 && ifindex < MAX_IFINDEX)
     {
-      net_lock();
+      netdev_list_lock();
       for (; ifindex < MAX_IFINDEX; ifindex++)
         {
           if ((g_devset & (1UL << ifindex)) != 0)
@@ -150,12 +150,12 @@ int netdev_nextindex(int ifindex)
                * mean no-index in the POSIX standards.
                */
 
-              net_unlock();
+              netdev_list_unlock();
               return ifindex + 1;
             }
         }
 
-      net_unlock();
+      netdev_list_unlock();
     }
 
   return -ENODEV;
diff --git a/net/netdev/netdev_findbyname.c b/net/netdev/netdev_findbyname.c
index 2c7eec2ac54..4ccb823c863 100644
--- a/net/netdev/netdev_findbyname.c
+++ b/net/netdev/netdev_findbyname.c
@@ -59,17 +59,17 @@ FAR struct net_driver_s *netdev_findbyname(FAR const char 
*ifname)
 
   if (ifname)
     {
-      net_lock();
+      netdev_list_lock();
       for (dev = g_netdevices; dev; dev = dev->flink)
         {
           if (strcmp(ifname, dev->d_ifname) == 0)
             {
-              net_unlock();
+              netdev_list_unlock();
               return dev;
             }
         }
 
-      net_unlock();
+      netdev_list_unlock();
     }
 
   return NULL;
diff --git a/net/netdev/netdev_register.c b/net/netdev/netdev_register.c
index a35f17096e4..07d388ecca5 100644
--- a/net/netdev/netdev_register.c
+++ b/net/netdev/netdev_register.c
@@ -106,6 +106,12 @@ uint32_t g_devset;
 uint32_t g_devfreed;
 #endif
 
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static mutex_t g_netdevices_lock = NXMUTEX_INITIALIZER;
+
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
@@ -216,6 +222,33 @@ static int get_ifindex(void)
  * Public Functions
  ****************************************************************************/
 
+/****************************************************************************
+ * Name: netdev_list_lock
+ *
+ * Description:
+ *   Lock the network device list.  This is used to protect the network
+ *   device list from concurrent access.
+ *
+ ****************************************************************************/
+
+void netdev_list_lock(void)
+{
+  nxmutex_lock(&g_netdevices_lock);
+}
+
+/****************************************************************************
+ * Name: netdev_list_unlock
+ *
+ * Description:
+ *   Unlock the network device list.
+ *
+ ****************************************************************************/
+
+void netdev_list_unlock(void)
+{
+  nxmutex_unlock(&g_netdevices_lock);
+}
+
 /****************************************************************************
  * Name: netdev_register
  *
@@ -394,13 +427,13 @@ int netdev_register(FAR struct net_driver_s *dev, enum 
net_lltype_e lltype)
 
       /* We need exclusive access for the following operations */
 
-      net_lock();
+      netdev_list_lock();
 
 #ifdef CONFIG_NETDEV_IFINDEX
       ifindex = get_ifindex();
       if (ifindex < 0)
         {
-          net_unlock();
+          netdev_list_unlock();
           return ifindex;
         }
 
@@ -489,7 +522,7 @@ int netdev_register(FAR struct net_driver_s *dev, enum 
net_lltype_e lltype)
       icmpv6_devinit(dev);
 #endif
 
-      net_unlock();
+      netdev_list_unlock();
 
 #if defined(CONFIG_NET_ETHERNET) || defined(CONFIG_DRIVERS_IEEE80211)
       ninfo("Registered MAC: %02x:%02x:%02x:%02x:%02x:%02x as dev: %s\n",
diff --git a/net/netdev/netdev_unregister.c b/net/netdev/netdev_unregister.c
index 57f59a9dee2..1ef46c95a0e 100644
--- a/net/netdev/netdev_unregister.c
+++ b/net/netdev/netdev_unregister.c
@@ -118,7 +118,7 @@ int netdev_unregister(FAR struct net_driver_s *dev)
 
   if (dev)
     {
-      net_lock();
+      netdev_list_lock();
 
       /* Find the device in the list of known network devices */
 
@@ -161,7 +161,7 @@ int netdev_unregister(FAR struct net_driver_s *dev)
         }
 #endif
 
-      net_unlock();
+      netdev_list_unlock();
 
 #if CONFIG_NETDEV_STATISTICS_LOG_PERIOD > 0
       work_cancel_sync(NETDEV_STATISTICS_WORK, &dev->d_statistics.logwork);
diff --git a/net/netdev/netdev_verify.c b/net/netdev/netdev_verify.c
index b803430b4ff..9e348a8af94 100644
--- a/net/netdev/netdev_verify.c
+++ b/net/netdev/netdev_verify.c
@@ -55,7 +55,7 @@ bool netdev_verify(FAR struct net_driver_s *dev)
 
   /* Search the list of registered devices */
 
-  net_lock();
+  netdev_list_lock();
   for (chkdev = g_netdevices; chkdev != NULL; chkdev = chkdev->flink)
     {
       /* Is the network device that we are looking for? */
@@ -69,6 +69,6 @@ bool netdev_verify(FAR struct net_driver_s *dev)
         }
     }
 
-  net_unlock();
+  netdev_list_unlock();
   return valid;
 }
diff --git a/net/tcp/tcp_conn.c b/net/tcp/tcp_conn.c
index 56e167eca07..e8fdb5bb427 100644
--- a/net/tcp/tcp_conn.c
+++ b/net/tcp/tcp_conn.c
@@ -358,6 +358,7 @@ static inline int tcp_ipv4_bind(FAR struct tcp_conn_s *conn,
     {
       ret = -EADDRNOTAVAIL;
 
+      netdev_list_lock();
       for (dev = g_netdevices; dev; dev = dev->flink)
         {
           if (net_ipv4addr_cmp(addr->sin_addr.s_addr, dev->d_ipaddr))
@@ -367,6 +368,8 @@ static inline int tcp_ipv4_bind(FAR struct tcp_conn_s *conn,
             }
         }
 
+      netdev_list_unlock();
+
       if (ret == -EADDRNOTAVAIL)
         {
           net_unlock();
@@ -456,6 +459,7 @@ static inline int tcp_ipv6_bind(FAR struct tcp_conn_s *conn,
     {
       ret = -EADDRNOTAVAIL;
 
+      netdev_list_lock();
       for (dev = g_netdevices; dev; dev = dev->flink)
         {
           if (NETDEV_IS_MY_V6ADDR(dev, addr->sin6_addr.in6_u.u6_addr16))
@@ -465,6 +469,7 @@ static inline int tcp_ipv6_bind(FAR struct tcp_conn_s *conn,
             }
         }
 
+      netdev_list_unlock();
       if (ret == -EADDRNOTAVAIL)
         {
           net_unlock();
diff --git a/net/udp/udp_conn.c b/net/udp/udp_conn.c
index f8c5f06066a..ee3f64762d4 100644
--- a/net/udp/udp_conn.c
+++ b/net/udp/udp_conn.c
@@ -751,6 +751,7 @@ int udp_bind(FAR struct udp_conn_s *conn, FAR const struct 
sockaddr *addr)
         {
           ret = -EADDRNOTAVAIL;
 
+          netdev_list_lock();
           for (dev = g_netdevices; dev; dev = dev->flink)
             {
               if (net_ipv4addr_cmp(inaddr->sin_addr.s_addr, dev->d_ipaddr))
@@ -760,6 +761,7 @@ int udp_bind(FAR struct udp_conn_s *conn, FAR const struct 
sockaddr *addr)
                 }
             }
 
+          netdev_list_unlock();
           if (ret == -EADDRNOTAVAIL)
             {
               net_unlock();
@@ -798,6 +800,7 @@ int udp_bind(FAR struct udp_conn_s *conn, FAR const struct 
sockaddr *addr)
         {
           ret = -EADDRNOTAVAIL;
 
+          netdev_list_lock();
           for (dev = g_netdevices; dev; dev = dev->flink)
             {
               if (NETDEV_IS_MY_V6ADDR(dev,
@@ -808,6 +811,7 @@ int udp_bind(FAR struct udp_conn_s *conn, FAR const struct 
sockaddr *addr)
                 }
             }
 
+          netdev_list_unlock();
           if (ret == -EADDRNOTAVAIL)
             {
               net_unlock();

Reply via email to