mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
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:
parent
0af74a54bb
commit
eb60667561
11 changed files with 168 additions and 16 deletions
|
|
@ -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);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
59
net/netdev/netdev_lock.c
Normal 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);
|
||||
}
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue