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,
|
static int quota_fetch_inc(FAR struct netdev_lowerhalf_s *lower,
|
||||||
enum netpkt_type_e type)
|
enum netpkt_type_e type)
|
||||||
{
|
{
|
||||||
#ifndef HAVE_ATOMIC
|
#ifndef HAVE_ATOMICS
|
||||||
irqstate_t flags = spin_lock_irqsave(NULL);
|
irqstate_t flags = spin_lock_irqsave(&lower->lock);
|
||||||
int ret = lower->quota[type]++;
|
int ret = lower->quota[type]++;
|
||||||
spin_unlock_irqrestore(NULL, flags);
|
spin_unlock_irqrestore(&lower->lock, flags);
|
||||||
return ret;
|
return ret;
|
||||||
#else
|
#else
|
||||||
return atomic_fetch_add(&lower->quota[type], 1);
|
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,
|
static int quota_fetch_dec(FAR struct netdev_lowerhalf_s *lower,
|
||||||
enum netpkt_type_e type)
|
enum netpkt_type_e type)
|
||||||
{
|
{
|
||||||
#ifndef HAVE_ATOMIC
|
#ifndef HAVE_ATOMICS
|
||||||
irqstate_t flags = spin_lock_irqsave(NULL);
|
irqstate_t flags = spin_lock_irqsave(&lower->lock);
|
||||||
int ret = lower->quota[type]--;
|
int ret = lower->quota[type]--;
|
||||||
spin_unlock_irqrestore(NULL, flags);
|
spin_unlock_irqrestore(&lower->lock, flags);
|
||||||
return ret;
|
return ret;
|
||||||
#else
|
#else
|
||||||
return atomic_fetch_sub(&lower->quota[type], 1);
|
return atomic_fetch_sub(&lower->quota[type], 1);
|
||||||
@ -680,6 +680,9 @@ int netdev_lower_register(FAR struct netdev_lowerhalf_s *dev,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_ATOMICS
|
||||||
|
spin_initialize(&dev->lock, SP_UNLOCKED);
|
||||||
|
#endif
|
||||||
dev->netdev.d_ifup = netdev_upper_ifup;
|
dev->netdev.d_ifup = netdev_upper_ifup;
|
||||||
dev->netdev.d_ifdown = netdev_upper_ifdown;
|
dev->netdev.d_ifdown = netdev_upper_ifdown;
|
||||||
dev->netdev.d_txavail = netdev_upper_txavail;
|
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,
|
int netdev_lower_quota_load(FAR struct netdev_lowerhalf_s *dev,
|
||||||
enum netpkt_type_e type)
|
enum netpkt_type_e type)
|
||||||
{
|
{
|
||||||
#ifndef HAVE_ATOMIC
|
#ifndef HAVE_ATOMICS
|
||||||
irqstate_t flags = spin_lock_irqsave(NULL);
|
irqstate_t flags = spin_lock_irqsave(&dev->lock);
|
||||||
int ret = dev->quota[type];
|
int ret = dev->quota[type];
|
||||||
spin_unlock_irqrestore(NULL, flags);
|
spin_unlock_irqrestore(&dev->lock, flags);
|
||||||
return ret;
|
return ret;
|
||||||
#else
|
#else
|
||||||
return atomic_load(&dev->quota[type]);
|
return atomic_load(&dev->quota[type]);
|
||||||
|
@ -61,6 +61,16 @@
|
|||||||
# define CONFIG_C99_BOOL 1
|
# define CONFIG_C99_BOOL 1
|
||||||
#endif
|
#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 */
|
/* C++ support */
|
||||||
|
|
||||||
#undef CONFIG_HAVE_CXX14
|
#undef CONFIG_HAVE_CXX14
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
#include <nuttx/compiler.h>
|
||||||
|
#include <nuttx/spinlock.h>
|
||||||
|
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
@ -37,10 +39,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(CONFIG_OPENAMP)
|
#if defined(CONFIG_OPENAMP)
|
||||||
#include <metal/atomic.h>
|
# include <metal/atomic.h>
|
||||||
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && \
|
#elif defined(CONFIG_HAVE_ATOMICS)
|
||||||
!defined(__STDC_NO_ATOMICS__)
|
# include <stdatomic.h>
|
||||||
#include <stdatomic.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <nuttx/net/ip.h>
|
#include <nuttx/net/ip.h>
|
||||||
@ -61,10 +62,8 @@
|
|||||||
|
|
||||||
#define NETPKT_BUFLEN CONFIG_IOB_BUFSIZE
|
#define NETPKT_BUFLEN CONFIG_IOB_BUFSIZE
|
||||||
|
|
||||||
#if defined(CONFIG_OPENAMP) || \
|
#if defined(CONFIG_OPENAMP) || defined(CONFIG_HAVE_ATOMICS)
|
||||||
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && \
|
# define HAVE_ATOMICS
|
||||||
!defined(__STDC_NO_ATOMICS__))
|
|
||||||
#define HAVE_ATOMIC
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -104,10 +103,11 @@ struct netdev_lowerhalf_s
|
|||||||
|
|
||||||
/* Max # of buffer held by driver */
|
/* Max # of buffer held by driver */
|
||||||
|
|
||||||
#ifdef HAVE_ATOMIC
|
#ifdef HAVE_ATOMICS
|
||||||
atomic_int quota[NETPKT_TYPENUM];
|
atomic_int quota[NETPKT_TYPENUM];
|
||||||
#else
|
#else
|
||||||
int quota[NETPKT_TYPENUM];
|
int quota[NETPKT_TYPENUM];
|
||||||
|
spinlock_t lock;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The structure used by net stack.
|
/* The structure used by net stack.
|
||||||
|
@ -33,6 +33,9 @@
|
|||||||
#include <nuttx/irq.h>
|
#include <nuttx/irq.h>
|
||||||
|
|
||||||
#ifndef CONFIG_SPINLOCK
|
#ifndef CONFIG_SPINLOCK
|
||||||
|
# define SP_UNLOCKED 0 /* The Un-locked state */
|
||||||
|
# define SP_LOCKED 1 /* The Locked state */
|
||||||
|
|
||||||
typedef uint8_t spinlock_t;
|
typedef uint8_t spinlock_t;
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@ -106,9 +109,9 @@ typedef uint8_t spinlock_t;
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if defined(CONFIG_ARCH_HAVE_TESTSET)
|
#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)
|
#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;
|
irqstate_t flags;
|
||||||
spinlock_t ret;
|
spinlock_t ret;
|
||||||
@ -386,7 +389,7 @@ void spin_clrbit(FAR volatile cpu_set_t *set, unsigned int cpu,
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if defined(CONFIG_SMP)
|
#if defined(CONFIG_SMP)
|
||||||
irqstate_t spin_lock_irqsave(spinlock_t *lock);
|
irqstate_t spin_lock_irqsave(FAR spinlock_t *lock);
|
||||||
#else
|
#else
|
||||||
# define spin_lock_irqsave(l) ((void)(l), up_irq_save())
|
# define spin_lock_irqsave(l) ((void)(l), up_irq_save())
|
||||||
#endif
|
#endif
|
||||||
@ -396,7 +399,7 @@ irqstate_t spin_lock_irqsave(spinlock_t *lock);
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if defined(CONFIG_SMP)
|
#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
|
#else
|
||||||
# define spin_lock_irqsave_wo_note(l) ((void)(l), up_irq_save())
|
# define spin_lock_irqsave_wo_note(l) ((void)(l), up_irq_save())
|
||||||
#endif
|
#endif
|
||||||
@ -431,7 +434,7 @@ irqstate_t spin_lock_irqsave_wo_note(spinlock_t *lock);
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if defined(CONFIG_SMP)
|
#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
|
#else
|
||||||
# define spin_unlock_irqrestore(l, f) up_irq_restore(f)
|
# define spin_unlock_irqrestore(l, f) up_irq_restore(f)
|
||||||
#endif
|
#endif
|
||||||
@ -441,7 +444,7 @@ void spin_unlock_irqrestore(spinlock_t *lock, irqstate_t flags);
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if defined(CONFIG_SMP)
|
#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
|
#else
|
||||||
# define spin_unlock_irqrestore_wo_note(l, f) up_irq_restore(f)
|
# define spin_unlock_irqrestore_wo_note(l, f) up_irq_restore(f)
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user