mirror of
https://github.com/apache/nuttx.git
synced 2026-05-25 09:45:55 +08:00
net/pkt: replace net_lock with netdev_lock
protect PKT resources through netdev_lock, conn_lock, and pkt_list_lock Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
+9
-1
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+22
-19
@@ -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;
|
||||
}
|
||||
|
||||
+13
-12
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user