mirror of
https://github.com/apache/nuttx.git
synced 2026-05-30 05:16:47 +08:00
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:
+10
-4
@@ -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
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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
@@ -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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user