drivers/net/netdev: improve granularity of 'quota' locking

There is no need to use global spinlock to protect netdev
specific data counters. Allocate per-netdev specific spinlock
to get better locking granularity.

Move C/C++ atomic support checking to compiler.h

Signed-off-by: Petro Karashchenko <petro.karashchenko@gmail.com>
This commit is contained in:
Petro Karashchenko
2023-06-16 23:05:09 +03:00
committed by Alan Carvalho de Assis
parent e78eade641
commit 46facd44b3
4 changed files with 40 additions and 24 deletions
+12 -9
View File
@@ -91,10 +91,10 @@ struct netdev_upperhalf_s
static int quota_fetch_inc(FAR struct netdev_lowerhalf_s *lower,
enum netpkt_type_e type)
{
#ifndef HAVE_ATOMIC
irqstate_t flags = spin_lock_irqsave(NULL);
#ifndef HAVE_ATOMICS
irqstate_t flags = spin_lock_irqsave(&lower->lock);
int ret = lower->quota[type]++;
spin_unlock_irqrestore(NULL, flags);
spin_unlock_irqrestore(&lower->lock, flags);
return ret;
#else
return atomic_fetch_add(&lower->quota[type], 1);
@@ -104,10 +104,10 @@ static int quota_fetch_inc(FAR struct netdev_lowerhalf_s *lower,
static int quota_fetch_dec(FAR struct netdev_lowerhalf_s *lower,
enum netpkt_type_e type)
{
#ifndef HAVE_ATOMIC
irqstate_t flags = spin_lock_irqsave(NULL);
#ifndef HAVE_ATOMICS
irqstate_t flags = spin_lock_irqsave(&lower->lock);
int ret = lower->quota[type]--;
spin_unlock_irqrestore(NULL, flags);
spin_unlock_irqrestore(&lower->lock, flags);
return ret;
#else
return atomic_fetch_sub(&lower->quota[type], 1);
@@ -680,6 +680,9 @@ int netdev_lower_register(FAR struct netdev_lowerhalf_s *dev,
return -ENOMEM;
}
#ifndef HAVE_ATOMICS
spin_initialize(&dev->lock, SP_UNLOCKED);
#endif
dev->netdev.d_ifup = netdev_upper_ifup;
dev->netdev.d_ifdown = netdev_upper_ifdown;
dev->netdev.d_txavail = netdev_upper_txavail;
@@ -846,10 +849,10 @@ void netdev_lower_txdone(FAR struct netdev_lowerhalf_s *dev)
int netdev_lower_quota_load(FAR struct netdev_lowerhalf_s *dev,
enum netpkt_type_e type)
{
#ifndef HAVE_ATOMIC
irqstate_t flags = spin_lock_irqsave(NULL);
#ifndef HAVE_ATOMICS
irqstate_t flags = spin_lock_irqsave(&dev->lock);
int ret = dev->quota[type];
spin_unlock_irqrestore(NULL, flags);
spin_unlock_irqrestore(&dev->lock, flags);
return ret;
#else
return atomic_load(&dev->quota[type]);