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


The following commit(s) were added to refs/heads/master by this push:
     new e87082b195a net/utils/net_bufpool: add lock to struct net_bufpool_s 
and bufpool_navail
e87082b195a is described below

commit e87082b195a1b4c7c3a300bbc8cc5f6c259f37ab
Author: zhanghongyu <[email protected]>
AuthorDate: Tue Apr 29 20:14:52 2025 +0800

    net/utils/net_bufpool: add lock to struct net_bufpool_s and bufpool_navail
    
    Add a lock to net_bufpool to simplify the protocol stack code.
    
    Signed-off-by: zhanghongyu <[email protected]>
---
 net/can/can_conn.c         |  9 +++---
 net/icmp/icmp_conn.c       | 24 +++++++--------
 net/icmpv6/icmpv6_conn.c   | 24 +++++++--------
 net/netlink/netlink_conn.c |  9 +++---
 net/pkt/pkt_conn.c         |  9 +++---
 net/udp/udp_conn.c         |  9 +++---
 net/usrsock/usrsock_conn.c |  9 +++---
 net/utils/net_bufpool.c    | 73 ++++++++++++++++++++++++++++++++++++++++++++--
 net/utils/utils.h          | 44 ++++++++++++++++++++++++++++
 9 files changed, 155 insertions(+), 55 deletions(-)

diff --git a/net/can/can_conn.c b/net/can/can_conn.c
index 30f38992423..fec70b616e0 100644
--- a/net/can/can_conn.c
+++ b/net/can/can_conn.c
@@ -62,7 +62,6 @@
 NET_BUFPOOL_DECLARE(g_can_connections, sizeof(struct can_conn_s),
                     CONFIG_CAN_PREALLOC_CONNS, CONFIG_CAN_ALLOC_CONNS,
                     CONFIG_CAN_MAX_CONNS);
-static mutex_t g_free_lock = NXMUTEX_INITIALIZER;
 
 /* A list of all allocated NetLink connections */
 
@@ -100,7 +99,7 @@ FAR struct can_conn_s *can_alloc(void)
 
   /* The free list is protected by a a mutex. */
 
-  nxmutex_lock(&g_free_lock);
+  NET_BUFPOLL_LOCK(g_can_connections);
 
   conn = NET_BUFPOOL_TRYALLOC(g_can_connections);
   if (conn != NULL)
@@ -128,7 +127,7 @@ FAR struct can_conn_s *can_alloc(void)
       dq_addlast(&conn->sconn.node, &g_active_can_connections);
     }
 
-  nxmutex_unlock(&g_free_lock);
+  NET_BUFPOLL_UNLOCK(g_can_connections);
   return conn;
 }
 
@@ -147,7 +146,7 @@ void can_free(FAR struct can_conn_s *conn)
 
   DEBUGASSERT(conn->crefs == 0);
 
-  nxmutex_lock(&g_free_lock);
+  NET_BUFPOLL_LOCK(g_can_connections);
 
   /* Remove the connection from the active list */
 
@@ -157,7 +156,7 @@ void can_free(FAR struct can_conn_s *conn)
 
   NET_BUFPOOL_FREE(g_can_connections, conn);
 
-  nxmutex_unlock(&g_free_lock);
+  NET_BUFPOLL_UNLOCK(g_can_connections);
 }
 
 /****************************************************************************
diff --git a/net/icmp/icmp_conn.c b/net/icmp/icmp_conn.c
index f7e9256b6a1..333c13309fb 100644
--- a/net/icmp/icmp_conn.c
+++ b/net/icmp/icmp_conn.c
@@ -62,7 +62,6 @@
 NET_BUFPOOL_DECLARE(g_icmp_connections, sizeof(struct icmp_conn_s),
                     CONFIG_NET_ICMP_PREALLOC_CONNS,
                     CONFIG_NET_ICMP_ALLOC_CONNS, CONFIG_NET_ICMP_MAX_CONNS);
-static mutex_t g_free_lock = NXMUTEX_INITIALIZER;
 
 /* A list of all allocated IPPROTO_ICMP socket connections */
 
@@ -85,24 +84,21 @@ static dq_queue_t g_active_icmp_connections;
 FAR struct icmp_conn_s *icmp_alloc(void)
 {
   FAR struct icmp_conn_s *conn = NULL;
-  int ret;
 
   /* The free list is protected by a mutex. */
 
-  ret = nxmutex_lock(&g_free_lock);
-  if (ret >= 0)
-    {
-      conn = NET_BUFPOOL_TRYALLOC(g_icmp_connections);
-      if (conn != NULL)
-        {
-          /* Enqueue the connection into the active list */
+  NET_BUFPOLL_LOCK(g_icmp_connections);
 
-          dq_addlast(&conn->sconn.node, &g_active_icmp_connections);
-        }
+  conn = NET_BUFPOOL_TRYALLOC(g_icmp_connections);
+  if (conn != NULL)
+    {
+      /* Enqueue the connection into the active list */
 
-      nxmutex_unlock(&g_free_lock);
+      dq_addlast(&conn->sconn.node, &g_active_icmp_connections);
     }
 
+  NET_BUFPOLL_UNLOCK(g_icmp_connections);
+
   return conn;
 }
 
@@ -123,7 +119,7 @@ void icmp_free(FAR struct icmp_conn_s *conn)
 
   /* Take the mutex (perhaps waiting) */
 
-  nxmutex_lock(&g_free_lock);
+  NET_BUFPOLL_LOCK(g_icmp_connections);
 
   /* Is this the last reference on the connection?  It might not be if the
    * socket was cloned.
@@ -146,7 +142,7 @@ void icmp_free(FAR struct icmp_conn_s *conn)
       NET_BUFPOOL_FREE(g_icmp_connections, conn);
     }
 
-  nxmutex_unlock(&g_free_lock);
+  NET_BUFPOLL_UNLOCK(g_icmp_connections);
 }
 
 /****************************************************************************
diff --git a/net/icmpv6/icmpv6_conn.c b/net/icmpv6/icmpv6_conn.c
index 0d49222850c..abce6df0e11 100644
--- a/net/icmpv6/icmpv6_conn.c
+++ b/net/icmpv6/icmpv6_conn.c
@@ -63,7 +63,6 @@ NET_BUFPOOL_DECLARE(g_icmpv6_connections, sizeof(struct 
icmpv6_conn_s),
                     CONFIG_NET_ICMPv6_PREALLOC_CONNS,
                     CONFIG_NET_ICMPv6_ALLOC_CONNS,
                     CONFIG_NET_ICMPv6_MAX_CONNS);
-static mutex_t g_free_lock = NXMUTEX_INITIALIZER;
 
 /* A list of all allocated IPPROTO_ICMP socket connections */
 
@@ -86,24 +85,21 @@ static dq_queue_t g_active_icmpv6_connections;
 FAR struct icmpv6_conn_s *icmpv6_alloc(void)
 {
   FAR struct icmpv6_conn_s *conn = NULL;
-  int ret;
 
   /* The free list is protected by a mutex. */
 
-  ret = nxmutex_lock(&g_free_lock);
-  if (ret >= 0)
-    {
-      conn = NET_BUFPOOL_TRYALLOC(g_icmpv6_connections);
-      if (conn != NULL)
-        {
-          /* Enqueue the connection into the active list */
+  NET_BUFPOLL_LOCK(g_icmpv6_connections);
 
-          dq_addlast(&conn->sconn.node, &g_active_icmpv6_connections);
-        }
+  conn = NET_BUFPOOL_TRYALLOC(g_icmpv6_connections);
+  if (conn != NULL)
+    {
+      /* Enqueue the connection into the active list */
 
-      nxmutex_unlock(&g_free_lock);
+      dq_addlast(&conn->sconn.node, &g_active_icmpv6_connections);
     }
 
+  NET_BUFPOLL_UNLOCK(g_icmpv6_connections);
+
   return conn;
 }
 
@@ -124,7 +120,7 @@ void icmpv6_free(FAR struct icmpv6_conn_s *conn)
 
   /* Take the mutex (perhaps waiting) */
 
-  nxmutex_lock(&g_free_lock);
+  NET_BUFPOLL_LOCK(g_icmpv6_connections);
 
   /* Remove the connection from the active list */
 
@@ -134,7 +130,7 @@ void icmpv6_free(FAR struct icmpv6_conn_s *conn)
 
   NET_BUFPOOL_FREE(g_icmpv6_connections, conn);
 
-  nxmutex_unlock(&g_free_lock);
+  NET_BUFPOLL_UNLOCK(g_icmpv6_connections);
 }
 
 /****************************************************************************
diff --git a/net/netlink/netlink_conn.c b/net/netlink/netlink_conn.c
index fa960a0cffa..dca52b37232 100644
--- a/net/netlink/netlink_conn.c
+++ b/net/netlink/netlink_conn.c
@@ -65,7 +65,6 @@
 NET_BUFPOOL_DECLARE(g_netlink_connections, sizeof(struct netlink_conn_s),
                     CONFIG_NETLINK_PREALLOC_CONNS,
                     CONFIG_NETLINK_ALLOC_CONNS, CONFIG_NETLINK_MAX_CONNS);
-static mutex_t g_free_lock = NXMUTEX_INITIALIZER;
 
 /* A list of all allocated NetLink connections */
 
@@ -167,7 +166,7 @@ FAR struct netlink_conn_s *netlink_alloc(void)
 
   /* The free list is protected by a mutex. */
 
-  nxmutex_lock(&g_free_lock);
+  NET_BUFPOLL_LOCK(g_netlink_connections);
 
   conn = NET_BUFPOOL_TRYALLOC(g_netlink_connections);
   if (conn != NULL)
@@ -177,7 +176,7 @@ FAR struct netlink_conn_s *netlink_alloc(void)
       dq_addlast(&conn->sconn.node, &g_active_netlink_connections);
     }
 
-  nxmutex_unlock(&g_free_lock);
+  NET_BUFPOLL_UNLOCK(g_netlink_connections);
   return conn;
 }
 
@@ -198,7 +197,7 @@ void netlink_free(FAR struct netlink_conn_s *conn)
 
   DEBUGASSERT(conn->crefs == 0);
 
-  nxmutex_lock(&g_free_lock);
+  NET_BUFPOLL_LOCK(g_netlink_connections);
 
   /* Remove the connection from the active list */
 
@@ -215,7 +214,7 @@ void netlink_free(FAR struct netlink_conn_s *conn)
 
   NET_BUFPOOL_FREE(g_netlink_connections, conn);
 
-  nxmutex_unlock(&g_free_lock);
+  NET_BUFPOLL_UNLOCK(g_netlink_connections);
 }
 
 /****************************************************************************
diff --git a/net/pkt/pkt_conn.c b/net/pkt/pkt_conn.c
index 8482d68de3a..91ea5bb09e9 100644
--- a/net/pkt/pkt_conn.c
+++ b/net/pkt/pkt_conn.c
@@ -66,7 +66,6 @@
 NET_BUFPOOL_DECLARE(g_pkt_connections, sizeof(struct pkt_conn_s),
                     CONFIG_NET_PKT_PREALLOC_CONNS,
                     CONFIG_NET_PKT_ALLOC_CONNS, CONFIG_NET_PKT_MAX_CONNS);
-static mutex_t g_free_lock = NXMUTEX_INITIALIZER;
 
 /* A list of all allocated packet socket connections */
 
@@ -104,7 +103,7 @@ FAR struct pkt_conn_s *pkt_alloc(void)
 
   /* The free list is protected by a mutex. */
 
-  nxmutex_lock(&g_free_lock);
+  NET_BUFPOLL_LOCK(g_pkt_connections);
 
   conn = NET_BUFPOOL_TRYALLOC(g_pkt_connections);
   if (conn)
@@ -114,7 +113,7 @@ FAR struct pkt_conn_s *pkt_alloc(void)
       dq_addlast(&conn->sconn.node, &g_active_pkt_connections);
     }
 
-  nxmutex_unlock(&g_free_lock);
+  NET_BUFPOLL_UNLOCK(g_pkt_connections);
   return conn;
 }
 
@@ -133,7 +132,7 @@ void pkt_free(FAR struct pkt_conn_s *conn)
 
   DEBUGASSERT(conn->crefs == 0);
 
-  nxmutex_lock(&g_free_lock);
+  NET_BUFPOLL_LOCK(g_pkt_connections);
 
   /* Remove the connection from the active list */
 
@@ -143,7 +142,7 @@ void pkt_free(FAR struct pkt_conn_s *conn)
 
   NET_BUFPOOL_FREE(g_pkt_connections, conn);
 
-  nxmutex_unlock(&g_free_lock);
+  NET_BUFPOLL_UNLOCK(g_pkt_connections);
 }
 
 /****************************************************************************
diff --git a/net/udp/udp_conn.c b/net/udp/udp_conn.c
index 538a443e895..e4c253e46e7 100644
--- a/net/udp/udp_conn.c
+++ b/net/udp/udp_conn.c
@@ -91,7 +91,6 @@
 NET_BUFPOOL_DECLARE(g_udp_connections, sizeof(struct udp_conn_s),
                     CONFIG_NET_UDP_PREALLOC_CONNS,
                     CONFIG_NET_UDP_ALLOC_CONNS, CONFIG_NET_UDP_MAX_CONNS);
-static mutex_t g_free_lock = NXMUTEX_INITIALIZER;
 
 /* A list of all allocated UDP connections */
 
@@ -566,7 +565,7 @@ FAR struct udp_conn_s *udp_alloc(uint8_t domain)
 
   /* The free list is protected by a mutex. */
 
-  nxmutex_lock(&g_free_lock);
+  NET_BUFPOLL_LOCK(g_udp_connections);
 
   conn = NET_BUFPOOL_TRYALLOC(g_udp_connections);
 
@@ -599,7 +598,7 @@ FAR struct udp_conn_s *udp_alloc(uint8_t domain)
       dq_addlast(&conn->sconn.node, &g_active_udp_connections);
     }
 
-  nxmutex_unlock(&g_free_lock);
+  NET_BUFPOLL_UNLOCK(g_udp_connections);
   return conn;
 }
 
@@ -622,7 +621,7 @@ void udp_free(FAR struct udp_conn_s *conn)
 
   DEBUGASSERT(conn->crefs == 0);
 
-  nxmutex_lock(&g_free_lock);
+  NET_BUFPOLL_LOCK(g_udp_connections);
   conn->lport = 0;
 
   /* Remove the connection from the active list */
@@ -654,7 +653,7 @@ void udp_free(FAR struct udp_conn_s *conn)
 
   NET_BUFPOOL_FREE(g_udp_connections, conn);
 
-  nxmutex_unlock(&g_free_lock);
+  NET_BUFPOLL_UNLOCK(g_udp_connections);
 }
 
 /****************************************************************************
diff --git a/net/usrsock/usrsock_conn.c b/net/usrsock/usrsock_conn.c
index 528b79ca283..b7e3a72389e 100644
--- a/net/usrsock/usrsock_conn.c
+++ b/net/usrsock/usrsock_conn.c
@@ -63,7 +63,6 @@ NET_BUFPOOL_DECLARE(g_usrsock_connections, sizeof(struct 
usrsock_conn_s),
                     CONFIG_NET_USRSOCK_PREALLOC_CONNS,
                     CONFIG_NET_USRSOCK_ALLOC_CONNS,
                     CONFIG_NET_USRSOCK_MAX_CONNS);
-static mutex_t g_free_lock = NXMUTEX_INITIALIZER;
 
 /* A list of all allocated usrsock connections */
 
@@ -88,7 +87,7 @@ FAR struct usrsock_conn_s *usrsock_alloc(void)
 
   /* The free list is protected by a a mutex. */
 
-  nxmutex_lock(&g_free_lock);
+  NET_BUFPOLL_LOCK(g_usrsock_connections);
 
   conn = NET_BUFPOOL_TRYALLOC(g_usrsock_connections);
   if (conn)
@@ -104,7 +103,7 @@ FAR struct usrsock_conn_s *usrsock_alloc(void)
       dq_addlast(&conn->sconn.node, &g_active_usrsock_connections);
     }
 
-  nxmutex_unlock(&g_free_lock);
+  NET_BUFPOLL_UNLOCK(g_usrsock_connections);
   return conn;
 }
 
@@ -123,7 +122,7 @@ void usrsock_free(FAR struct usrsock_conn_s *conn)
 
   DEBUGASSERT(conn->crefs == 0);
 
-  nxmutex_lock(&g_free_lock);
+  NET_BUFPOLL_LOCK(g_usrsock_connections);
 
   /* Remove the connection from the active list */
 
@@ -137,7 +136,7 @@ void usrsock_free(FAR struct usrsock_conn_s *conn)
 
   NET_BUFPOOL_FREE(g_usrsock_connections, conn);
 
-  nxmutex_unlock(&g_free_lock);
+  NET_BUFPOLL_UNLOCK(g_usrsock_connections);
 }
 
 /****************************************************************************
diff --git a/net/utils/net_bufpool.c b/net/utils/net_bufpool.c
index 89f4f9d3515..9a8c0848af3 100644
--- a/net/utils/net_bufpool.c
+++ b/net/utils/net_bufpool.c
@@ -98,6 +98,7 @@ FAR void *net_bufpool_timedalloc(FAR struct net_bufpool_s 
*pool,
                                  unsigned int timeout)
 {
   FAR struct net_bufnode_s *node;
+  FAR void *buf;
   int ret;
   int i;
 
@@ -121,6 +122,8 @@ FAR void *net_bufpool_timedalloc(FAR struct net_bufpool_s 
*pool,
       return NULL;
     }
 
+  nxrmutex_lock(&pool->lock);
+
   /* If we get here, then we didn't exceed maxalloc. */
 
   if (pool->dynalloc > 0 && sq_peek(&pool->freebuffers) == NULL)
@@ -128,7 +131,8 @@ FAR void *net_bufpool_timedalloc(FAR struct net_bufpool_s 
*pool,
       node = kmm_zalloc(pool->nodesize * pool->dynalloc);
       if (node == NULL)
         {
-          return NULL;
+          buf = NULL;
+          goto out;
         }
 
       /* Now initialize each connection structure */
@@ -141,7 +145,11 @@ FAR void *net_bufpool_timedalloc(FAR struct net_bufpool_s 
*pool,
         }
     }
 
-  return sq_remfirst(&pool->freebuffers);
+  buf = sq_remfirst(&pool->freebuffers);
+
+out:
+  nxrmutex_unlock(&pool->lock);
+  return buf;
 }
 
 /****************************************************************************
@@ -170,12 +178,16 @@ void net_bufpool_free(FAR struct net_bufpool_s *pool, FAR 
void *node)
     {
       FAR struct net_bufnode_s *net_bufnode = node;
 
+      net_bufpool_lock(pool);
+
       /* Set the buffer to zero, to make sure all nodes in the free buffer
        * pool are zeroed.
        */
 
       memset(net_bufnode, 0, pool->nodesize);
       sq_addlast(&net_bufnode->node, &pool->freebuffers);
+
+      net_bufpool_unlock(pool);
     }
 
   nxsem_post(&pool->sem);
@@ -205,3 +217,60 @@ int net_bufpool_test(FAR struct net_bufpool_s *pool)
 
   return ret;
 }
+
+/****************************************************************************
+ * Name: net_bufpool_navail
+ *
+ * Description:
+ *   Return the number of available buffers in the buffer pool.
+ *
+ * Assumptions:
+ *   None.
+ *
+ ****************************************************************************/
+
+int net_bufpool_navail(FAR struct net_bufpool_s *pool)
+{
+  int val = 0;
+  int ret;
+
+  ret = nxsem_get_value(&pool->sem, &val);
+  if (ret >= 0)
+    {
+      ret = val;
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: net_bufpool_lock
+ *
+ * Description:
+ *   Use the bufpool lock to protect the node of the buffer pool.
+ *
+ * Input Parameters:
+ *   pool - The lock of pool to be locked.
+ *
+ ****************************************************************************/
+
+void net_bufpool_lock(FAR struct net_bufpool_s *pool)
+{
+  nxrmutex_lock(&pool->lock);
+}
+
+/****************************************************************************
+ * Name: net_bufpool_unlock
+ *
+ * Description:
+ *   Finish using the bufpool lock to protect the node of the buffer pool.
+ *
+ * Input Parameters:
+ *   pool - The lock of pool to be unlocked.
+ *
+ ****************************************************************************/
+
+void net_bufpool_unlock(FAR struct net_bufpool_s *pool)
+{
+  nxrmutex_unlock(&pool->lock);
+}
diff --git a/net/utils/utils.h b/net/utils/utils.h
index e325941b036..dd3a6099c09 100644
--- a/net/utils/utils.h
+++ b/net/utils/utils.h
@@ -97,6 +97,7 @@
       dynalloc, \
       -(int)(nodesize), \
       SEM_INITIALIZER(NET_BUFPOOL_MAX(prealloc, dynalloc, maxalloc)), \
+      NXRMUTEX_INITIALIZER, \
       { NULL, NULL } \
     };
 
@@ -105,6 +106,9 @@
 #define NET_BUFPOOL_ALLOC(p)        net_bufpool_timedalloc(&p, UINT_MAX)
 #define NET_BUFPOOL_FREE(p,n)       net_bufpool_free(&p, n)
 #define NET_BUFPOOL_TEST(p)         net_bufpool_test(&p)
+#define NET_BUFPOOL_NAVAIL(p)       net_bufpool_navail(&p)
+#define NET_BUFPOLL_LOCK(p)         net_bufpool_lock(&p)
+#define NET_BUFPOLL_UNLOCK(p)       net_bufpool_unlock(&p)
 
 /****************************************************************************
  * Public Types
@@ -132,6 +136,7 @@ struct net_bufpool_s
 
   sem_t      sem;      /* The semaphore for waiting for free buffers */
 
+  rmutex_t   lock;     /* The lock for the pool */
   sq_queue_t freebuffers;
 };
 
@@ -415,6 +420,45 @@ void net_bufpool_free(FAR struct net_bufpool_s *pool, FAR 
void *node);
 
 int net_bufpool_test(FAR struct net_bufpool_s *pool);
 
+/****************************************************************************
+ * Name: net_bufpool_navail
+ *
+ * Description:
+ *   Return the number of available buffers in the buffer pool.
+ *
+ * Assumptions:
+ *   None.
+ *
+ ****************************************************************************/
+
+int net_bufpool_navail(FAR struct net_bufpool_s *pool);
+
+/****************************************************************************
+ * Name: net_bufpool_lock
+ *
+ * Description:
+ *   Use the bufpool lock to protect the node of the buffer pool.
+ *
+ * Input Parameters:
+ *   pool - The lock of pool to be locked.
+ *
+ ****************************************************************************/
+
+void net_bufpool_lock(FAR struct net_bufpool_s *pool);
+
+/****************************************************************************
+ * Name: net_bufpool_unlock
+ *
+ * Description:
+ *   Finish using the bufpool lock to protect the node of the buffer pool.
+ *
+ * Input Parameters:
+ *   pool - The lock of pool to be unlocked.
+ *
+ ****************************************************************************/
+
+void net_bufpool_unlock(FAR struct net_bufpool_s *pool);
+
 /****************************************************************************
  * Name: net_chksum_adjust
  *

Reply via email to