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 <zhanghongyu@xiaomi.com>
This commit is contained in:
zhanghongyu
2025-04-29 20:14:52 +08:00
committed by Xiang Xiao
parent 2c0e105cad
commit e87082b195
9 changed files with 155 additions and 55 deletions
+4 -5
View File
@@ -62,7 +62,6 @@
NET_BUFPOOL_DECLARE(g_can_connections, sizeof(struct can_conn_s), NET_BUFPOOL_DECLARE(g_can_connections, sizeof(struct can_conn_s),
CONFIG_CAN_PREALLOC_CONNS, CONFIG_CAN_ALLOC_CONNS, CONFIG_CAN_PREALLOC_CONNS, CONFIG_CAN_ALLOC_CONNS,
CONFIG_CAN_MAX_CONNS); CONFIG_CAN_MAX_CONNS);
static mutex_t g_free_lock = NXMUTEX_INITIALIZER;
/* A list of all allocated NetLink connections */ /* 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. */ /* 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); conn = NET_BUFPOOL_TRYALLOC(g_can_connections);
if (conn != NULL) if (conn != NULL)
@@ -128,7 +127,7 @@ FAR struct can_conn_s *can_alloc(void)
dq_addlast(&conn->sconn.node, &g_active_can_connections); dq_addlast(&conn->sconn.node, &g_active_can_connections);
} }
nxmutex_unlock(&g_free_lock); NET_BUFPOLL_UNLOCK(g_can_connections);
return conn; return conn;
} }
@@ -147,7 +146,7 @@ void can_free(FAR struct can_conn_s *conn)
DEBUGASSERT(conn->crefs == 0); DEBUGASSERT(conn->crefs == 0);
nxmutex_lock(&g_free_lock); NET_BUFPOLL_LOCK(g_can_connections);
/* Remove the connection from the active list */ /* 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); NET_BUFPOOL_FREE(g_can_connections, conn);
nxmutex_unlock(&g_free_lock); NET_BUFPOLL_UNLOCK(g_can_connections);
} }
/**************************************************************************** /****************************************************************************
+10 -14
View File
@@ -62,7 +62,6 @@
NET_BUFPOOL_DECLARE(g_icmp_connections, sizeof(struct icmp_conn_s), NET_BUFPOOL_DECLARE(g_icmp_connections, sizeof(struct icmp_conn_s),
CONFIG_NET_ICMP_PREALLOC_CONNS, CONFIG_NET_ICMP_PREALLOC_CONNS,
CONFIG_NET_ICMP_ALLOC_CONNS, CONFIG_NET_ICMP_MAX_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 */ /* 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 *icmp_alloc(void)
{ {
FAR struct icmp_conn_s *conn = NULL; FAR struct icmp_conn_s *conn = NULL;
int ret;
/* The free list is protected by a mutex. */ /* The free list is protected by a mutex. */
ret = nxmutex_lock(&g_free_lock); NET_BUFPOLL_LOCK(g_icmp_connections);
if (ret >= 0)
conn = NET_BUFPOOL_TRYALLOC(g_icmp_connections);
if (conn != NULL)
{ {
conn = NET_BUFPOOL_TRYALLOC(g_icmp_connections); /* Enqueue the connection into the active list */
if (conn != NULL)
{
/* Enqueue the connection into the active list */
dq_addlast(&conn->sconn.node, &g_active_icmp_connections); dq_addlast(&conn->sconn.node, &g_active_icmp_connections);
}
nxmutex_unlock(&g_free_lock);
} }
NET_BUFPOLL_UNLOCK(g_icmp_connections);
return conn; return conn;
} }
@@ -123,7 +119,7 @@ void icmp_free(FAR struct icmp_conn_s *conn)
/* Take the mutex (perhaps waiting) */ /* 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 /* Is this the last reference on the connection? It might not be if the
* socket was cloned. * socket was cloned.
@@ -146,7 +142,7 @@ void icmp_free(FAR struct icmp_conn_s *conn)
NET_BUFPOOL_FREE(g_icmp_connections, conn); NET_BUFPOOL_FREE(g_icmp_connections, conn);
} }
nxmutex_unlock(&g_free_lock); NET_BUFPOLL_UNLOCK(g_icmp_connections);
} }
/**************************************************************************** /****************************************************************************
+10 -14
View File
@@ -63,7 +63,6 @@ NET_BUFPOOL_DECLARE(g_icmpv6_connections, sizeof(struct icmpv6_conn_s),
CONFIG_NET_ICMPv6_PREALLOC_CONNS, CONFIG_NET_ICMPv6_PREALLOC_CONNS,
CONFIG_NET_ICMPv6_ALLOC_CONNS, CONFIG_NET_ICMPv6_ALLOC_CONNS,
CONFIG_NET_ICMPv6_MAX_CONNS); CONFIG_NET_ICMPv6_MAX_CONNS);
static mutex_t g_free_lock = NXMUTEX_INITIALIZER;
/* A list of all allocated IPPROTO_ICMP socket connections */ /* 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 *icmpv6_alloc(void)
{ {
FAR struct icmpv6_conn_s *conn = NULL; FAR struct icmpv6_conn_s *conn = NULL;
int ret;
/* The free list is protected by a mutex. */ /* The free list is protected by a mutex. */
ret = nxmutex_lock(&g_free_lock); NET_BUFPOLL_LOCK(g_icmpv6_connections);
if (ret >= 0)
conn = NET_BUFPOOL_TRYALLOC(g_icmpv6_connections);
if (conn != NULL)
{ {
conn = NET_BUFPOOL_TRYALLOC(g_icmpv6_connections); /* Enqueue the connection into the active list */
if (conn != NULL)
{
/* Enqueue the connection into the active list */
dq_addlast(&conn->sconn.node, &g_active_icmpv6_connections); dq_addlast(&conn->sconn.node, &g_active_icmpv6_connections);
}
nxmutex_unlock(&g_free_lock);
} }
NET_BUFPOLL_UNLOCK(g_icmpv6_connections);
return conn; return conn;
} }
@@ -124,7 +120,7 @@ void icmpv6_free(FAR struct icmpv6_conn_s *conn)
/* Take the mutex (perhaps waiting) */ /* Take the mutex (perhaps waiting) */
nxmutex_lock(&g_free_lock); NET_BUFPOLL_LOCK(g_icmpv6_connections);
/* Remove the connection from the active list */ /* 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); NET_BUFPOOL_FREE(g_icmpv6_connections, conn);
nxmutex_unlock(&g_free_lock); NET_BUFPOLL_UNLOCK(g_icmpv6_connections);
} }
/**************************************************************************** /****************************************************************************
+4 -5
View File
@@ -65,7 +65,6 @@
NET_BUFPOOL_DECLARE(g_netlink_connections, sizeof(struct netlink_conn_s), NET_BUFPOOL_DECLARE(g_netlink_connections, sizeof(struct netlink_conn_s),
CONFIG_NETLINK_PREALLOC_CONNS, CONFIG_NETLINK_PREALLOC_CONNS,
CONFIG_NETLINK_ALLOC_CONNS, CONFIG_NETLINK_MAX_CONNS); CONFIG_NETLINK_ALLOC_CONNS, CONFIG_NETLINK_MAX_CONNS);
static mutex_t g_free_lock = NXMUTEX_INITIALIZER;
/* A list of all allocated NetLink connections */ /* 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. */ /* 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); conn = NET_BUFPOOL_TRYALLOC(g_netlink_connections);
if (conn != NULL) if (conn != NULL)
@@ -177,7 +176,7 @@ FAR struct netlink_conn_s *netlink_alloc(void)
dq_addlast(&conn->sconn.node, &g_active_netlink_connections); dq_addlast(&conn->sconn.node, &g_active_netlink_connections);
} }
nxmutex_unlock(&g_free_lock); NET_BUFPOLL_UNLOCK(g_netlink_connections);
return conn; return conn;
} }
@@ -198,7 +197,7 @@ void netlink_free(FAR struct netlink_conn_s *conn)
DEBUGASSERT(conn->crefs == 0); DEBUGASSERT(conn->crefs == 0);
nxmutex_lock(&g_free_lock); NET_BUFPOLL_LOCK(g_netlink_connections);
/* Remove the connection from the active list */ /* 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); NET_BUFPOOL_FREE(g_netlink_connections, conn);
nxmutex_unlock(&g_free_lock); NET_BUFPOLL_UNLOCK(g_netlink_connections);
} }
/**************************************************************************** /****************************************************************************
+4 -5
View File
@@ -66,7 +66,6 @@
NET_BUFPOOL_DECLARE(g_pkt_connections, sizeof(struct pkt_conn_s), NET_BUFPOOL_DECLARE(g_pkt_connections, sizeof(struct pkt_conn_s),
CONFIG_NET_PKT_PREALLOC_CONNS, CONFIG_NET_PKT_PREALLOC_CONNS,
CONFIG_NET_PKT_ALLOC_CONNS, CONFIG_NET_PKT_MAX_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 */ /* 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. */ /* 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); conn = NET_BUFPOOL_TRYALLOC(g_pkt_connections);
if (conn) if (conn)
@@ -114,7 +113,7 @@ FAR struct pkt_conn_s *pkt_alloc(void)
dq_addlast(&conn->sconn.node, &g_active_pkt_connections); dq_addlast(&conn->sconn.node, &g_active_pkt_connections);
} }
nxmutex_unlock(&g_free_lock); NET_BUFPOLL_UNLOCK(g_pkt_connections);
return conn; return conn;
} }
@@ -133,7 +132,7 @@ void pkt_free(FAR struct pkt_conn_s *conn)
DEBUGASSERT(conn->crefs == 0); DEBUGASSERT(conn->crefs == 0);
nxmutex_lock(&g_free_lock); NET_BUFPOLL_LOCK(g_pkt_connections);
/* Remove the connection from the active list */ /* 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); NET_BUFPOOL_FREE(g_pkt_connections, conn);
nxmutex_unlock(&g_free_lock); NET_BUFPOLL_UNLOCK(g_pkt_connections);
} }
/**************************************************************************** /****************************************************************************
+4 -5
View File
@@ -91,7 +91,6 @@
NET_BUFPOOL_DECLARE(g_udp_connections, sizeof(struct udp_conn_s), NET_BUFPOOL_DECLARE(g_udp_connections, sizeof(struct udp_conn_s),
CONFIG_NET_UDP_PREALLOC_CONNS, CONFIG_NET_UDP_PREALLOC_CONNS,
CONFIG_NET_UDP_ALLOC_CONNS, CONFIG_NET_UDP_MAX_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 */ /* 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. */ /* 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); 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); dq_addlast(&conn->sconn.node, &g_active_udp_connections);
} }
nxmutex_unlock(&g_free_lock); NET_BUFPOLL_UNLOCK(g_udp_connections);
return conn; return conn;
} }
@@ -622,7 +621,7 @@ void udp_free(FAR struct udp_conn_s *conn)
DEBUGASSERT(conn->crefs == 0); DEBUGASSERT(conn->crefs == 0);
nxmutex_lock(&g_free_lock); NET_BUFPOLL_LOCK(g_udp_connections);
conn->lport = 0; conn->lport = 0;
/* Remove the connection from the active list */ /* 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); NET_BUFPOOL_FREE(g_udp_connections, conn);
nxmutex_unlock(&g_free_lock); NET_BUFPOLL_UNLOCK(g_udp_connections);
} }
/**************************************************************************** /****************************************************************************
+4 -5
View File
@@ -63,7 +63,6 @@ NET_BUFPOOL_DECLARE(g_usrsock_connections, sizeof(struct usrsock_conn_s),
CONFIG_NET_USRSOCK_PREALLOC_CONNS, CONFIG_NET_USRSOCK_PREALLOC_CONNS,
CONFIG_NET_USRSOCK_ALLOC_CONNS, CONFIG_NET_USRSOCK_ALLOC_CONNS,
CONFIG_NET_USRSOCK_MAX_CONNS); CONFIG_NET_USRSOCK_MAX_CONNS);
static mutex_t g_free_lock = NXMUTEX_INITIALIZER;
/* A list of all allocated usrsock connections */ /* 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. */ /* 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); conn = NET_BUFPOOL_TRYALLOC(g_usrsock_connections);
if (conn) if (conn)
@@ -104,7 +103,7 @@ FAR struct usrsock_conn_s *usrsock_alloc(void)
dq_addlast(&conn->sconn.node, &g_active_usrsock_connections); dq_addlast(&conn->sconn.node, &g_active_usrsock_connections);
} }
nxmutex_unlock(&g_free_lock); NET_BUFPOLL_UNLOCK(g_usrsock_connections);
return conn; return conn;
} }
@@ -123,7 +122,7 @@ void usrsock_free(FAR struct usrsock_conn_s *conn)
DEBUGASSERT(conn->crefs == 0); DEBUGASSERT(conn->crefs == 0);
nxmutex_lock(&g_free_lock); NET_BUFPOLL_LOCK(g_usrsock_connections);
/* Remove the connection from the active list */ /* 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); NET_BUFPOOL_FREE(g_usrsock_connections, conn);
nxmutex_unlock(&g_free_lock); NET_BUFPOLL_UNLOCK(g_usrsock_connections);
} }
/**************************************************************************** /****************************************************************************
+71 -2
View File
@@ -98,6 +98,7 @@ FAR void *net_bufpool_timedalloc(FAR struct net_bufpool_s *pool,
unsigned int timeout) unsigned int timeout)
{ {
FAR struct net_bufnode_s *node; FAR struct net_bufnode_s *node;
FAR void *buf;
int ret; int ret;
int i; int i;
@@ -121,6 +122,8 @@ FAR void *net_bufpool_timedalloc(FAR struct net_bufpool_s *pool,
return NULL; return NULL;
} }
nxrmutex_lock(&pool->lock);
/* If we get here, then we didn't exceed maxalloc. */ /* If we get here, then we didn't exceed maxalloc. */
if (pool->dynalloc > 0 && sq_peek(&pool->freebuffers) == NULL) 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); node = kmm_zalloc(pool->nodesize * pool->dynalloc);
if (node == NULL) if (node == NULL)
{ {
return NULL; buf = NULL;
goto out;
} }
/* Now initialize each connection structure */ /* 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; 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 /* Set the buffer to zero, to make sure all nodes in the free buffer
* pool are zeroed. * pool are zeroed.
*/ */
memset(net_bufnode, 0, pool->nodesize); memset(net_bufnode, 0, pool->nodesize);
sq_addlast(&net_bufnode->node, &pool->freebuffers); sq_addlast(&net_bufnode->node, &pool->freebuffers);
net_bufpool_unlock(pool);
} }
nxsem_post(&pool->sem); nxsem_post(&pool->sem);
@@ -205,3 +217,60 @@ int net_bufpool_test(FAR struct net_bufpool_s *pool)
return ret; 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);
}
+44
View File
@@ -97,6 +97,7 @@
dynalloc, \ dynalloc, \
-(int)(nodesize), \ -(int)(nodesize), \
SEM_INITIALIZER(NET_BUFPOOL_MAX(prealloc, dynalloc, maxalloc)), \ SEM_INITIALIZER(NET_BUFPOOL_MAX(prealloc, dynalloc, maxalloc)), \
NXRMUTEX_INITIALIZER, \
{ NULL, NULL } \ { NULL, NULL } \
}; };
@@ -105,6 +106,9 @@
#define NET_BUFPOOL_ALLOC(p) net_bufpool_timedalloc(&p, UINT_MAX) #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_FREE(p,n) net_bufpool_free(&p, n)
#define NET_BUFPOOL_TEST(p) net_bufpool_test(&p) #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 * Public Types
@@ -132,6 +136,7 @@ struct net_bufpool_s
sem_t sem; /* The semaphore for waiting for free buffers */ sem_t sem; /* The semaphore for waiting for free buffers */
rmutex_t lock; /* The lock for the pool */
sq_queue_t freebuffers; 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); 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 * Name: net_chksum_adjust
* *