drivers/net: replace critical_section with spinlock

so as to better support multi-core scenarios

Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
This commit is contained in:
zhanghongyu
2025-06-23 14:20:21 +08:00
committed by archer
parent fe822145a3
commit 521e319aa3
7 changed files with 52 additions and 30 deletions
+10 -4
View File
@@ -171,6 +171,10 @@ struct e1000_driver_s
FAR uint32_t *mta; FAR uint32_t *mta;
#endif #endif
/* A spinlock for protecting the driving state */
spinlock_t lock;
}; };
/***************************************************************************** /*****************************************************************************
@@ -995,12 +999,12 @@ static int e1000_ifup(FAR struct netdev_lowerhalf_s *dev)
dev->netdev.d_ipv6addr[6], dev->netdev.d_ipv6addr[7]); dev->netdev.d_ipv6addr[6], dev->netdev.d_ipv6addr[7]);
#endif #endif
flags = enter_critical_section(); flags = spin_lock_irqsave(&priv->lock);
/* Enable the Ethernet */ /* Enable the Ethernet */
e1000_enable(priv); e1000_enable(priv);
leave_critical_section(flags); spin_unlock_irqrestore(&priv->lock, flags);
/* Update link status in case link status interrupt is missing */ /* Update link status in case link status interrupt is missing */
@@ -1031,7 +1035,7 @@ static int e1000_ifdown(FAR struct netdev_lowerhalf_s *dev)
FAR struct e1000_driver_s *priv = (FAR struct e1000_driver_s *)dev; FAR struct e1000_driver_s *priv = (FAR struct e1000_driver_s *)dev;
irqstate_t flags; irqstate_t flags;
flags = enter_critical_section(); flags = spin_lock_irqsave(&priv->lock);
/* Put the EMAC in its reset, non-operational state. This should be /* Put the EMAC in its reset, non-operational state. This should be
* a known configuration that will guarantee the e1000_ifup() always * a known configuration that will guarantee the e1000_ifup() always
@@ -1042,7 +1046,7 @@ static int e1000_ifdown(FAR struct netdev_lowerhalf_s *dev)
/* Mark the device "down" */ /* Mark the device "down" */
leave_critical_section(flags); spin_unlock_irqrestore(&priv->lock, flags);
return OK; return OK;
} }
@@ -1534,6 +1538,8 @@ static int e1000_probe(FAR struct pci_device_s *dev)
goto errout; goto errout;
} }
spin_lock_init(&priv->lock);
/* Register the network device */ /* Register the network device */
netdev->quota[NETPKT_TX] = E1000_TX_QUOTA; netdev->quota[NETPKT_TX] = E1000_TX_QUOTA;
+10 -4
View File
@@ -151,6 +151,10 @@ struct igb_driver_s
FAR uint32_t *mta; FAR uint32_t *mta;
#endif #endif
/* A spinlock for protecting the driving state */
spinlock_t lock;
}; };
/***************************************************************************** /*****************************************************************************
@@ -903,12 +907,12 @@ static int igb_ifup(FAR struct netdev_lowerhalf_s *dev)
dev->netdev.d_ipv6addr[6], dev->netdev.d_ipv6addr[7]); dev->netdev.d_ipv6addr[6], dev->netdev.d_ipv6addr[7]);
#endif #endif
flags = enter_critical_section(); flags = spin_lock_irqsave(&priv->lock);
/* Enable the Ethernet */ /* Enable the Ethernet */
igb_enable(priv); igb_enable(priv);
leave_critical_section(flags); spin_unlock_irqrestore(&priv->lock, flags);
/* Update link status in case link status interrupt is missing */ /* Update link status in case link status interrupt is missing */
@@ -939,7 +943,7 @@ static int igb_ifdown(FAR struct netdev_lowerhalf_s *dev)
FAR struct igb_driver_s *priv = (FAR struct igb_driver_s *)dev; FAR struct igb_driver_s *priv = (FAR struct igb_driver_s *)dev;
irqstate_t flags; irqstate_t flags;
flags = enter_critical_section(); flags = spin_lock_irqsave(&priv->lock);
/* Put the EMAC in its reset, non-operational state. This should be /* Put the EMAC in its reset, non-operational state. This should be
* a known configuration that will guarantee the igb_ifup() always * a known configuration that will guarantee the igb_ifup() always
@@ -947,7 +951,7 @@ static int igb_ifdown(FAR struct netdev_lowerhalf_s *dev)
*/ */
igb_disable(priv); igb_disable(priv);
leave_critical_section(flags); spin_unlock_irqrestore(&priv->lock, flags);
return OK; return OK;
} }
@@ -1456,6 +1460,8 @@ static int igb_probe(FAR struct pci_device_s *dev)
return ret; return ret;
} }
spin_lock_init(&priv->lock);
/* Register the network device */ /* Register the network device */
netdev->quota[NETPKT_TX] = IGB_TX_QUOTA; netdev->quota[NETPKT_TX] = IGB_TX_QUOTA;
+10 -4
View File
@@ -151,6 +151,10 @@ struct igc_driver_s
FAR uint32_t *mta; FAR uint32_t *mta;
#endif #endif
/* A spinlock for protecting the driving state */
spinlock_t lock;
}; };
/***************************************************************************** /*****************************************************************************
@@ -876,12 +880,12 @@ static int igc_ifup(FAR struct netdev_lowerhalf_s *dev)
dev->netdev.d_ipv6addr[6], dev->netdev.d_ipv6addr[7]); dev->netdev.d_ipv6addr[6], dev->netdev.d_ipv6addr[7]);
#endif #endif
flags = enter_critical_section(); flags = spin_lock_irqsave(&priv->lock);
/* Enable the Ethernet */ /* Enable the Ethernet */
igc_enable(priv); igc_enable(priv);
leave_critical_section(flags); spin_unlock_irqrestore(&priv->lock, flags);
/* Update link status in case link status interrupt is missing */ /* Update link status in case link status interrupt is missing */
@@ -912,7 +916,7 @@ static int igc_ifdown(FAR struct netdev_lowerhalf_s *dev)
FAR struct igc_driver_s *priv = (FAR struct igc_driver_s *)dev; FAR struct igc_driver_s *priv = (FAR struct igc_driver_s *)dev;
irqstate_t flags; irqstate_t flags;
flags = enter_critical_section(); flags = spin_lock_irqsave(&priv->lock);
/* Put the EMAC in its reset, non-operational state. This should be /* Put the EMAC in its reset, non-operational state. This should be
* a known configuration that will guarantee the igc_ifup() always * a known configuration that will guarantee the igc_ifup() always
@@ -923,7 +927,7 @@ static int igc_ifdown(FAR struct netdev_lowerhalf_s *dev)
/* Mark the device "down" */ /* Mark the device "down" */
leave_critical_section(flags); spin_unlock_irqrestore(&priv->lock, flags);
return OK; return OK;
} }
@@ -1432,6 +1436,8 @@ static int igc_probe(FAR struct pci_device_s *dev)
return ret; return ret;
} }
spin_lock_init(&priv->lock);
/* Register the network device */ /* Register the network device */
netdev->quota[NETPKT_TX] = IGC_TX_QUOTA; netdev->quota[NETPKT_TX] = IGC_TX_QUOTA;
+6 -3
View File
@@ -31,8 +31,8 @@
#include <errno.h> #include <errno.h>
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include <nuttx/irq.h>
#include <nuttx/kmalloc.h> #include <nuttx/kmalloc.h>
#include <nuttx/spinlock.h>
#include <nuttx/wqueue.h> #include <nuttx/wqueue.h>
#include <nuttx/net/ip.h> #include <nuttx/net/ip.h>
@@ -90,6 +90,7 @@ struct lan91c111_driver_s
int irq; /* IRQ number */ int irq; /* IRQ number */
struct work_s irqwork; /* For deferring interrupt work to the work queue */ struct work_s irqwork; /* For deferring interrupt work to the work queue */
struct work_s pollwork; /* For deferring poll work to the work queue */ struct work_s pollwork; /* For deferring poll work to the work queue */
spinlock_t lock; /* Spinlock to protect the driver state */
uint16_t bank; /* Current bank */ uint16_t bank; /* Current bank */
uint16_t pktbuf[(MAX_NETDEV_PKTSIZE + 4 + 1) / 2]; /* +4 due to getregs32/putregs32 */ uint16_t pktbuf[(MAX_NETDEV_PKTSIZE + 4 + 1) / 2]; /* +4 due to getregs32/putregs32 */
@@ -1005,7 +1006,7 @@ static int lan91c111_ifdown(FAR struct net_driver_s *dev)
/* Disable the Ethernet interrupt */ /* Disable the Ethernet interrupt */
flags = enter_critical_section(); flags = spin_lock_irqsave(&priv->lock);
up_disable_irq(priv->irq); up_disable_irq(priv->irq);
work_cancel(LAN91C111_WORK, &priv->irqwork); work_cancel(LAN91C111_WORK, &priv->irqwork);
@@ -1023,7 +1024,7 @@ static int lan91c111_ifdown(FAR struct net_driver_s *dev)
putreg16(priv, CTL_REG, CTL_CLEAR); putreg16(priv, CTL_REG, CTL_CLEAR);
putreg16(priv, CONFIG_REG, CONFIG_CLEAR); putreg16(priv, CONFIG_REG, CONFIG_CLEAR);
leave_critical_section(flags); spin_unlock_irqrestore(&priv->lock, flags);
return OK; return OK;
} }
@@ -1364,6 +1365,8 @@ int lan91c111_initialize(uintptr_t base, int irq)
goto err; goto err;
} }
spin_lock_init(&priv->lock);
/* Initialize the driver structure */ /* Initialize the driver structure */
dev->d_buf = (FAR uint8_t *)priv->pktbuf; /* Single packet buffer */ dev->d_buf = (FAR uint8_t *)priv->pktbuf; /* Single packet buffer */
-7
View File
@@ -779,16 +779,9 @@ static int net_rpmsg_drv_ifdown(FAR struct net_driver_s *dev)
{ {
FAR struct net_rpmsg_drv_s *priv = dev->d_private; FAR struct net_rpmsg_drv_s *priv = dev->d_private;
FAR struct net_rpmsg_ifdown_s msg; FAR struct net_rpmsg_ifdown_s msg;
irqstate_t flags;
/* Disable the interrupt */
flags = enter_critical_section();
work_cancel(LPWORK, &priv->pollwork); work_cancel(LPWORK, &priv->pollwork);
leave_critical_section(flags);
/* Put the EMAC in its reset, non-operational state. This should be /* Put the EMAC in its reset, non-operational state. This should be
* a known configuration that will guarantee the net_rpmsg_drv_ifup() * a known configuration that will guarantee the net_rpmsg_drv_ifup()
* always successfully brings the interface back up. * always successfully brings the interface back up.
+9 -3
View File
@@ -37,7 +37,7 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include <nuttx/irq.h> #include <nuttx/spinlock.h>
#include <nuttx/wdog.h> #include <nuttx/wdog.h>
#include <nuttx/wqueue.h> #include <nuttx/wqueue.h>
#include <nuttx/net/ip.h> #include <nuttx/net/ip.h>
@@ -104,6 +104,7 @@ struct skel_driver_s
struct wdog_s sk_txtimeout; /* TX timeout timer */ struct wdog_s sk_txtimeout; /* TX timeout timer */
struct work_s sk_irqwork; /* For deferring interrupt work to the work queue */ struct work_s sk_irqwork; /* For deferring interrupt work to the work queue */
struct work_s sk_pollwork; /* For deferring poll work to the work queue */ struct work_s sk_pollwork; /* For deferring poll work to the work queue */
spinlock_t sk_lock; /* Spinlock to protect the driver state */
/* This holds the information visible to the NuttX network */ /* This holds the information visible to the NuttX network */
@@ -634,6 +635,7 @@ static int skel_ifup(FAR struct net_driver_s *dev)
{ {
FAR struct skel_driver_s *priv = FAR struct skel_driver_s *priv =
(FAR struct skel_driver_s *)dev->d_private; (FAR struct skel_driver_s *)dev->d_private;
irqstate_t flags;
#ifdef CONFIG_NET_IPv4 #ifdef CONFIG_NET_IPv4
ninfo("Bringing up: %u.%u.%u.%u\n", ninfo("Bringing up: %u.%u.%u.%u\n",
@@ -651,8 +653,10 @@ static int skel_ifup(FAR struct net_driver_s *dev)
/* Enable the Ethernet interrupt */ /* Enable the Ethernet interrupt */
flags = spin_lock_irqsave(&priv->sk_lock);
priv->sk_bifup = true; priv->sk_bifup = true;
up_enable_irq(CONFIG_NET_SKELETON_IRQ); up_enable_irq(CONFIG_NET_SKELETON_IRQ);
spin_unlock_irqrestore(&priv->sk_lock, flags);
return OK; return OK;
} }
@@ -681,7 +685,7 @@ static int skel_ifdown(FAR struct net_driver_s *dev)
/* Disable the Ethernet interrupt */ /* Disable the Ethernet interrupt */
flags = enter_critical_section(); flags = spin_lock_irqsave(&priv->sk_lock);
up_disable_irq(CONFIG_NET_SKELETON_IRQ); up_disable_irq(CONFIG_NET_SKELETON_IRQ);
/* Cancel the TX timeout timers */ /* Cancel the TX timeout timers */
@@ -696,7 +700,7 @@ static int skel_ifdown(FAR struct net_driver_s *dev)
/* Mark the device "down" */ /* Mark the device "down" */
priv->sk_bifup = false; priv->sk_bifup = false;
leave_critical_section(flags); spin_unlock_irqrestore(&priv->sk_lock, flags);
return OK; return OK;
} }
@@ -940,6 +944,8 @@ int skel_initialize(int intf)
#endif #endif
priv->sk_dev.d_private = g_skel; /* Used to recover private state from dev */ priv->sk_dev.d_private = g_skel; /* Used to recover private state from dev */
spin_lock_init(&priv->sk_lock);
/* Put the interface in the down state. This usually amounts to resetting /* Put the interface in the down state. This usually amounts to resetting
* the device and/or calling skel_ifdown(). * the device and/or calling skel_ifdown().
*/ */
+7 -5
View File
@@ -59,7 +59,7 @@
#endif #endif
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include <nuttx/irq.h> #include <nuttx/spinlock.h>
#include <nuttx/mutex.h> #include <nuttx/mutex.h>
#include <nuttx/wqueue.h> #include <nuttx/wqueue.h>
#include <nuttx/mm/iob.h> #include <nuttx/mm/iob.h>
@@ -126,6 +126,7 @@ struct tun_device_s
struct work_s work; /* For deferring poll work to the work queue */ struct work_s work; /* For deferring poll work to the work queue */
FAR struct pollfd *poll_fds; FAR struct pollfd *poll_fds;
mutex_t lock; mutex_t lock;
spinlock_t spinlock; /* Spinlock to protect the driver state */
sem_t read_wait_sem; sem_t read_wait_sem;
sem_t write_wait_sem; sem_t write_wait_sem;
size_t read_d_len; size_t read_d_len;
@@ -694,7 +695,7 @@ static int tun_ifdown(FAR struct net_driver_s *dev)
netdev_carrier_off(dev); netdev_carrier_off(dev);
flags = enter_critical_section(); flags = spin_lock_irqsave_nopreempt(&priv->spinlock);
/* Mark the device "down" */ /* Mark the device "down" */
@@ -703,7 +704,7 @@ static int tun_ifdown(FAR struct net_driver_s *dev)
nxsem_post(&priv->read_wait_sem); nxsem_post(&priv->read_wait_sem);
nxsem_post(&priv->write_wait_sem); nxsem_post(&priv->write_wait_sem);
leave_critical_section(flags); spin_unlock_irqrestore_nopreempt(&priv->spinlock, flags);
return OK; return OK;
} }
@@ -783,7 +784,7 @@ static int tun_txavail(FAR struct net_driver_s *dev)
FAR struct tun_device_s *priv = (FAR struct tun_device_s *)dev->d_private; FAR struct tun_device_s *priv = (FAR struct tun_device_s *)dev->d_private;
irqstate_t flags; irqstate_t flags;
flags = enter_critical_section(); /* No interrupts */ flags = spin_lock_irqsave(&priv->spinlock); /* No interrupts */
/* Schedule to perform the TX poll on the worker thread when priv->bifup /* Schedule to perform the TX poll on the worker thread when priv->bifup
* is true. * is true.
@@ -794,7 +795,7 @@ static int tun_txavail(FAR struct net_driver_s *dev)
work_queue(TUNWORK, &priv->work, tun_txavail_work, priv, 0); work_queue(TUNWORK, &priv->work, tun_txavail_work, priv, 0);
} }
leave_critical_section(flags); spin_unlock_irqrestore(&priv->spinlock, flags);
return OK; return OK;
} }
@@ -889,6 +890,7 @@ static int tun_dev_init(FAR struct tun_device_s *priv,
/* Initialize the mutual exclusion and wait semaphore */ /* Initialize the mutual exclusion and wait semaphore */
nxmutex_init(&priv->lock); nxmutex_init(&priv->lock);
spin_lock_init(&priv->spinlock);
nxsem_init(&priv->read_wait_sem, 0, 0); nxsem_init(&priv->read_wait_sem, 0, 0);
nxsem_init(&priv->write_wait_sem, 0, 0); nxsem_init(&priv->write_wait_sem, 0, 0);