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
