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:
parent
e78eade641
commit
46facd44b3
@ -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]);
|
||||
|
@ -61,6 +61,16 @@
|
||||
# define CONFIG_C99_BOOL 1
|
||||
#endif
|
||||
|
||||
/* ISO C/C++11 atomic types support */
|
||||
|
||||
#undef CONFIG_HAVE_ATOMICS
|
||||
|
||||
#if ((defined(__cplusplus) && __cplusplus >= 201103L) || \
|
||||
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L)) && \
|
||||
!defined(__STDC_NO_ATOMICS__)
|
||||
# define CONFIG_HAVE_ATOMICS
|
||||
#endif
|
||||
|
||||
/* C++ support */
|
||||
|
||||
#undef CONFIG_HAVE_CXX14
|
||||
|
@ -28,6 +28,8 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/compiler.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
@ -37,10 +39,9 @@
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_OPENAMP)
|
||||
#include <metal/atomic.h>
|
||||
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && \
|
||||
!defined(__STDC_NO_ATOMICS__)
|
||||
#include <stdatomic.h>
|
||||
# include <metal/atomic.h>
|
||||
#elif defined(CONFIG_HAVE_ATOMICS)
|
||||
# include <stdatomic.h>
|
||||
#endif
|
||||
|
||||
#include <nuttx/net/ip.h>
|
||||
@ -61,10 +62,8 @@
|
||||
|
||||
#define NETPKT_BUFLEN CONFIG_IOB_BUFSIZE
|
||||
|
||||
#if defined(CONFIG_OPENAMP) || \
|
||||
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && \
|
||||
!defined(__STDC_NO_ATOMICS__))
|
||||
#define HAVE_ATOMIC
|
||||
#if defined(CONFIG_OPENAMP) || defined(CONFIG_HAVE_ATOMICS)
|
||||
# define HAVE_ATOMICS
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
@ -104,10 +103,11 @@ struct netdev_lowerhalf_s
|
||||
|
||||
/* Max # of buffer held by driver */
|
||||
|
||||
#ifdef HAVE_ATOMIC
|
||||
#ifdef HAVE_ATOMICS
|
||||
atomic_int quota[NETPKT_TYPENUM];
|
||||
#else
|
||||
int quota[NETPKT_TYPENUM];
|
||||
spinlock_t lock;
|
||||
#endif
|
||||
|
||||
/* The structure used by net stack.
|
||||
|
@ -33,6 +33,9 @@
|
||||
#include <nuttx/irq.h>
|
||||
|
||||
#ifndef CONFIG_SPINLOCK
|
||||
# define SP_UNLOCKED 0 /* The Un-locked state */
|
||||
# define SP_LOCKED 1 /* The Locked state */
|
||||
|
||||
typedef uint8_t spinlock_t;
|
||||
#else
|
||||
|
||||
@ -106,9 +109,9 @@ typedef uint8_t spinlock_t;
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_ARCH_HAVE_TESTSET)
|
||||
spinlock_t up_testset(volatile FAR spinlock_t *lock);
|
||||
spinlock_t up_testset(FAR volatile spinlock_t *lock);
|
||||
#elif !defined(CONFIG_SMP)
|
||||
static inline spinlock_t up_testset(volatile FAR spinlock_t *lock)
|
||||
static inline spinlock_t up_testset(FAR volatile spinlock_t *lock)
|
||||
{
|
||||
irqstate_t flags;
|
||||
spinlock_t ret;
|
||||
@ -386,7 +389,7 @@ void spin_clrbit(FAR volatile cpu_set_t *set, unsigned int cpu,
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_SMP)
|
||||
irqstate_t spin_lock_irqsave(spinlock_t *lock);
|
||||
irqstate_t spin_lock_irqsave(FAR spinlock_t *lock);
|
||||
#else
|
||||
# define spin_lock_irqsave(l) ((void)(l), up_irq_save())
|
||||
#endif
|
||||
@ -396,7 +399,7 @@ irqstate_t spin_lock_irqsave(spinlock_t *lock);
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_SMP)
|
||||
irqstate_t spin_lock_irqsave_wo_note(spinlock_t *lock);
|
||||
irqstate_t spin_lock_irqsave_wo_note(FAR spinlock_t *lock);
|
||||
#else
|
||||
# define spin_lock_irqsave_wo_note(l) ((void)(l), up_irq_save())
|
||||
#endif
|
||||
@ -431,7 +434,7 @@ irqstate_t spin_lock_irqsave_wo_note(spinlock_t *lock);
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_SMP)
|
||||
void spin_unlock_irqrestore(spinlock_t *lock, irqstate_t flags);
|
||||
void spin_unlock_irqrestore(FAR spinlock_t *lock, irqstate_t flags);
|
||||
#else
|
||||
# define spin_unlock_irqrestore(l, f) up_irq_restore(f)
|
||||
#endif
|
||||
@ -441,7 +444,7 @@ void spin_unlock_irqrestore(spinlock_t *lock, irqstate_t flags);
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_SMP)
|
||||
void spin_unlock_irqrestore_wo_note(spinlock_t *lock, irqstate_t flags);
|
||||
void spin_unlock_irqrestore_wo_note(FAR spinlock_t *lock, irqstate_t flags);
|
||||
#else
|
||||
# define spin_unlock_irqrestore_wo_note(l, f) up_irq_restore(f)
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user