This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 46facd44b3 drivers/net/netdev: improve granularity of 'quota' locking
46facd44b3 is described below
commit 46facd44b3e78e43f5b701373edb029846cda19c
Author: Petro Karashchenko <[email protected]>
AuthorDate: Fri Jun 16 23:05:09 2023 +0300
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 <[email protected]>
---
drivers/net/netdev_upperhalf.c | 21 ++++++++++++---------
include/nuttx/compiler.h | 10 ++++++++++
include/nuttx/net/netdev_lowerhalf.h | 18 +++++++++---------
include/nuttx/spinlock.h | 15 +++++++++------
4 files changed, 40 insertions(+), 24 deletions(-)
diff --git a/drivers/net/netdev_upperhalf.c b/drivers/net/netdev_upperhalf.c
index 1a12a49599..1bca7fe93b 100644
--- a/drivers/net/netdev_upperhalf.c
+++ b/drivers/net/netdev_upperhalf.c
@@ -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]);
diff --git a/include/nuttx/compiler.h b/include/nuttx/compiler.h
index 7cd6246c36..7564f1fdb4 100644
--- a/include/nuttx/compiler.h
+++ b/include/nuttx/compiler.h
@@ -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
diff --git a/include/nuttx/net/netdev_lowerhalf.h
b/include/nuttx/net/netdev_lowerhalf.h
index e3298ea4b6..44459b2e4a 100644
--- a/include/nuttx/net/netdev_lowerhalf.h
+++ b/include/nuttx/net/netdev_lowerhalf.h
@@ -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.
diff --git a/include/nuttx/spinlock.h b/include/nuttx/spinlock.h
index d3b858e9f0..ea23e982d4 100644
--- a/include/nuttx/spinlock.h
+++ b/include/nuttx/spinlock.h
@@ -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