net/utils/net_lock.c: add api to lock conn and netdev

add new api to protect access and operation to conn and dev

Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
This commit is contained in:
zhanghongyu 2025-07-04 16:51:08 +08:00 committed by Xiang Xiao
parent 0af74a54bb
commit eb60667561
11 changed files with 168 additions and 16 deletions

View file

@ -382,7 +382,7 @@ static void netdev_upper_txavail_work(FAR struct netdev_upperhalf_s *upper)
/* Ignore the notification if the interface is not yet up */
net_lock();
netdev_lock(dev);
if (IFF_IS_UP(dev->d_flags) && !upper->txing)
{
DEBUGASSERT(dev->d_buf == NULL); /* Make sure: IOB only. */
@ -392,7 +392,7 @@ static void netdev_upper_txavail_work(FAR struct netdev_upperhalf_s *upper)
upper->txing = false;
}
net_unlock();
netdev_unlock(dev);
}
/****************************************************************************
@ -708,7 +708,7 @@ static void netdev_upper_rxpoll_work(FAR struct netdev_upperhalf_s *upper)
/* Loop while receive() successfully retrieves valid Ethernet frames. */
net_lock();
netdev_lock(dev);
while ((pkt = lower->ops->receive(lower)) != NULL)
{
if (!IFF_IS_UP(dev->d_flags))
@ -763,7 +763,7 @@ static void netdev_upper_rxpoll_work(FAR struct netdev_upperhalf_s *upper)
}
}
net_unlock();
netdev_unlock(dev);
}
/****************************************************************************
@ -1532,7 +1532,9 @@ void netdev_lower_carrier_on(FAR struct netdev_lowerhalf_s *dev)
netdev_upper_vlan_foreach(upper, netdev_lower_carrier_on);
#endif
netdev_lock(&dev->netdev);
netdev_carrier_on(&dev->netdev);
netdev_unlock(&dev->netdev);
}
/****************************************************************************
@ -1554,7 +1556,9 @@ void netdev_lower_carrier_off(FAR struct netdev_lowerhalf_s *dev)
netdev_upper_vlan_foreach(upper, netdev_lower_carrier_off);
#endif
netdev_lock(&dev->netdev);
netdev_carrier_off(&dev->netdev);
netdev_unlock(&dev->netdev);
}
/****************************************************************************

View file

@ -206,6 +206,13 @@ struct socket_conn_s
FAR struct devif_callback_s *list;
FAR struct devif_callback_s *list_tail;
/* This lock protects the connection structure. It is used to prevent
* re-entrance into the connection structure while it is being modified.
* This mutex is also used to protect the list of callbacks.
*/
mutex_t s_lock; /* Protect the connection structure */
/* Socket options */
#ifdef CONFIG_NET_SOCKOPTS
@ -1498,6 +1505,26 @@ int netdev_register(FAR struct net_driver_s *dev, enum net_lltype_e lltype);
int netdev_unregister(FAR struct net_driver_s *dev);
/****************************************************************************
* Name: netdev_lock
*
* Description:
* Lock the network device.
*
****************************************************************************/
void netdev_lock(FAR struct net_driver_s *dev);
/****************************************************************************
* Name: netdev_unlock
*
* Description:
* Unlock the network device.
*
****************************************************************************/
void netdev_unlock(FAR struct net_driver_s *dev);
#undef EXTERN
#ifdef __cplusplus
}

View file

@ -335,6 +335,8 @@ struct net_driver_s
char d_ifname[IFNAMSIZ];
#endif
rmutex_t d_lock;
/* Drivers interface flags. See IFF_* definitions in include/net/if.h */
uint32_t d_flags;

View file

@ -34,7 +34,8 @@ set(SRCS
netdev_carrier.c
netdev_default.c
netdev_verify.c
netdev_lladdrsize.c)
netdev_lladdrsize.c
netdev_lock.c)
if(CONFIG_MM_IOB)
list(APPEND SRCS netdev_input.c netdev_iob.c)

View file

@ -26,7 +26,7 @@ NETDEV_CSRCS += netdev_register.c netdev_ioctl.c netdev_txnotify.c
NETDEV_CSRCS += netdev_findbyname.c netdev_findbyaddr.c netdev_findbyindex.c
NETDEV_CSRCS += netdev_count.c netdev_ifconf.c netdev_foreach.c
NETDEV_CSRCS += netdev_unregister.c netdev_carrier.c netdev_default.c
NETDEV_CSRCS += netdev_verify.c netdev_lladdrsize.c
NETDEV_CSRCS += netdev_verify.c netdev_lladdrsize.c netdev_lock.c
ifeq ($(CONFIG_MM_IOB),y)
NETDEV_CSRCS += netdev_input.c netdev_iob.c

View file

@ -581,18 +581,18 @@ static int netdev_cell_ioctl(FAR struct socket *psock, int cmd,
int ret = -ENOTTY;
ninfo("cmd: %d\n", cmd);
net_lock();
if (_CELLIOCVALID(cmd))
{
dev = netdev_findbyname(req->ifr_name);
if (dev && dev->d_ioctl)
{
netdev_lock(dev);
ret = dev->d_ioctl(dev, cmd, (unsigned long)(uintptr_t)req);
netdev_unlock(dev);
}
}
net_unlock();
return ret;
}
#endif
@ -830,8 +830,6 @@ static int netdev_ifr_ioctl(FAR struct socket *psock, int cmd,
ninfo("cmd: %d\n", cmd);
net_lock();
/* Execute commands that do not need ifr_name or lifr_name */
switch (cmd)
@ -886,7 +884,6 @@ static int netdev_ifr_ioctl(FAR struct socket *psock, int cmd,
default:
if (req == NULL)
{
net_unlock();
return -ENOTTY;
}
@ -913,10 +910,11 @@ static int netdev_ifr_ioctl(FAR struct socket *psock, int cmd,
if (dev == NULL)
{
net_unlock();
return ret;
}
netdev_lock(dev);
/* Execute commands that need ifr_name or lifr_name */
switch (cmd)
@ -1322,7 +1320,7 @@ static int netdev_ifr_ioctl(FAR struct socket *psock, int cmd,
break;
}
net_unlock();
netdev_unlock(dev);
return ret;
}
@ -1383,8 +1381,6 @@ static int netdev_imsf_ioctl(FAR struct socket *psock, int cmd,
ninfo("cmd: %d\n", cmd);
net_lock();
/* Execute the command */
switch (cmd)
@ -1394,6 +1390,7 @@ static int netdev_imsf_ioctl(FAR struct socket *psock, int cmd,
dev = netdev_imsfdev(imsf);
if (dev)
{
netdev_lock(dev);
if (imsf->imsf_fmode == MCAST_INCLUDE)
{
ret = igmp_joingroup(dev, &imsf->imsf_multiaddr);
@ -1403,6 +1400,8 @@ static int netdev_imsf_ioctl(FAR struct socket *psock, int cmd,
DEBUGASSERT(imsf->imsf_fmode == MCAST_EXCLUDE);
ret = igmp_leavegroup(dev, &imsf->imsf_multiaddr);
}
netdev_unlock(dev);
}
}
break;
@ -1413,7 +1412,6 @@ static int netdev_imsf_ioctl(FAR struct socket *psock, int cmd,
break;
}
net_unlock();
return ret;
}
#endif

59
net/netdev/netdev_lock.c Normal file
View file

@ -0,0 +1,59 @@
/****************************************************************************
* net/netdev/netdev_lock.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/net/netdev.h>
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: netdev_lock
*
* Description:
* Lock the network device.
*
****************************************************************************/
void netdev_lock(FAR struct net_driver_s *dev)
{
nxrmutex_lock(&dev->d_lock);
}
/****************************************************************************
* Name: netdev_unlock
*
* Description:
* Unlock the network device.
*
****************************************************************************/
void netdev_unlock(FAR struct net_driver_s *dev)
{
nxrmutex_unlock(&dev->d_lock);
}

View file

@ -425,6 +425,8 @@ int netdev_register(FAR struct net_driver_s *dev, enum net_lltype_e lltype)
dev->d_conncb_tail = NULL;
dev->d_devcb = NULL;
nxrmutex_init(&dev->d_lock);
/* We need exclusive access for the following operations */
netdev_list_lock();

View file

@ -163,6 +163,8 @@ int netdev_unregister(FAR struct net_driver_s *dev)
netdev_list_unlock();
nxrmutex_destroy(&dev->d_lock);
#if CONFIG_NETDEV_STATISTICS_LOG_PERIOD > 0
work_cancel_sync(NETDEV_STATISTICS_WORK, &dev->d_statistics.logwork);
#endif

View file

@ -465,3 +465,43 @@ FAR struct iob_s *net_ioballoc(bool throttled)
return net_iobtimedalloc(throttled, UINT_MAX);
}
#endif
/****************************************************************************
* Name: conn_lock, conn_unlock, conn_dev_lock, conn_dev_unlock
*
* Description:
* Lock and unlock the connection and device.
*
****************************************************************************/
void conn_lock(FAR struct socket_conn_s *sconn)
{
nxmutex_lock(&sconn->s_lock);
}
void conn_unlock(FAR struct socket_conn_s *sconn)
{
nxmutex_unlock(&sconn->s_lock);
}
void conn_dev_lock(FAR struct socket_conn_s *sconn,
FAR struct net_driver_s *dev)
{
if (dev != NULL)
{
netdev_lock(dev);
}
nxmutex_lock(&sconn->s_lock);
}
void conn_dev_unlock(FAR struct socket_conn_s *sconn,
FAR struct net_driver_s *dev)
{
nxmutex_unlock(&sconn->s_lock);
if (dev != NULL)
{
netdev_unlock(dev);
}
}

View file

@ -606,6 +606,23 @@ uint16_t icmpv6_chksum(FAR struct net_driver_s *dev, unsigned int iplen);
FAR void *cmsg_append(FAR struct msghdr *msg, int level, int type,
FAR void *value, int value_len);
/****************************************************************************
* Name: conn_lock, conn_unlock, conn_dev_lock, conn_dev_unlock
*
* Description:
* Lock and unlock the connection and device.
*
****************************************************************************/
void conn_lock(FAR struct socket_conn_s *sconn);
void conn_unlock(FAR struct socket_conn_s *sconn);
void conn_dev_lock(FAR struct socket_conn_s *sconn,
FAR struct net_driver_s *dev);
void conn_dev_unlock(FAR struct socket_conn_s *sconn,
FAR struct net_driver_s *dev);
#undef EXTERN
#ifdef __cplusplus
}