summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2021-10-18 12:54:41 +0100
committerDavid S. Miller <davem@davemloft.net>2021-10-18 12:54:41 +0100
commitf8ba22a14268b432f685fd8463a958a3594b7fb6 (patch)
tree6feb3ee12123611d1988813e9e139c4c81280aec /include/linux
parent254ec036db1123b10e23e1412c191a3cf70dce71 (diff)
parent29cbcd85828372333aa87542c51f2b2b0fd4380c (diff)
Merge branch 'remove-qdisc-running-counter'
Sebastian Andrzej Siewior says: ==================== Try to simplify the gnet_stats and remove qdisc->running sequence counter. The first few patches is a follow up to https://lore.kernel.org/all/20211007175000.2334713-1-bigeasy@linutronix.de/ The remaining patches (#5+) remove the seqcount_t (Qdisc::running) from the Qdisc. The statistics (Qdisc::bstats and Qdisc::cpu_bstats) use u64_stats_t and the "running state" is now represented by a bit in Qdisc::state. By removing the seqcount_t from Qdisc and decoupling the bstats statistics from the seqcount_t it is possible to query the statistics even if the Qdisc is running instead of waiting until it is idle again. The try-lock like usage of the seqcount_t in qdisc_run_begin() is problematic on PREEMPT_RT. Inside the qdisc_run_begin/end() qdisc->running sequence counter write sections, at sch_direct_xmit(), the seqcount write serialization lock is released then re-acquired. This is fine for !RT, because the writer is in a BH disabled region and there is a no in-IRQ reader. For RT though, BH sections are preemptible. The earlier introduced seqcount_LOCKNAME_t mechanism, which for RT the reader acquires then relesaes the write serailization lock to avoid infinite spinning if it preempts a seqcount write section, cannot work: the qdisc->running write serialization lock is already intermittingly released inside the seqcount write section. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/netdevice.h4
-rw-r--r--include/linux/u64_stats_sync.h10
2 files changed, 10 insertions, 4 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 173984414f38..f9cd6fea213f 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1916,7 +1916,6 @@ enum netdev_ml_priv_type {
* @sfp_bus: attached &struct sfp_bus structure.
*
* @qdisc_tx_busylock: lockdep class annotating Qdisc->busylock spinlock
- * @qdisc_running_key: lockdep class annotating Qdisc->running seqcount
*
* @proto_down: protocol port state information can be sent to the
* switch driver and used to set the phys state of the
@@ -2250,7 +2249,6 @@ struct net_device {
struct phy_device *phydev;
struct sfp_bus *sfp_bus;
struct lock_class_key *qdisc_tx_busylock;
- struct lock_class_key *qdisc_running_key;
bool proto_down;
unsigned wol_enabled:1;
unsigned threaded:1;
@@ -2360,13 +2358,11 @@ static inline void netdev_for_each_tx_queue(struct net_device *dev,
#define netdev_lockdep_set_classes(dev) \
{ \
static struct lock_class_key qdisc_tx_busylock_key; \
- static struct lock_class_key qdisc_running_key; \
static struct lock_class_key qdisc_xmit_lock_key; \
static struct lock_class_key dev_addr_list_lock_key; \
unsigned int i; \
\
(dev)->qdisc_tx_busylock = &qdisc_tx_busylock_key; \
- (dev)->qdisc_running_key = &qdisc_running_key; \
lockdep_set_class(&(dev)->addr_list_lock, \
&dev_addr_list_lock_key); \
for (i = 0; i < (dev)->num_tx_queues; i++) \
diff --git a/include/linux/u64_stats_sync.h b/include/linux/u64_stats_sync.h
index e81856c0ba13..e8ec116c916b 100644
--- a/include/linux/u64_stats_sync.h
+++ b/include/linux/u64_stats_sync.h
@@ -83,6 +83,11 @@ static inline u64 u64_stats_read(const u64_stats_t *p)
return local64_read(&p->v);
}
+static inline void u64_stats_set(u64_stats_t *p, u64 val)
+{
+ local64_set(&p->v, val);
+}
+
static inline void u64_stats_add(u64_stats_t *p, unsigned long val)
{
local64_add(val, &p->v);
@@ -104,6 +109,11 @@ static inline u64 u64_stats_read(const u64_stats_t *p)
return p->v;
}
+static inline void u64_stats_set(u64_stats_t *p, u64 val)
+{
+ p->v = val;
+}
+
static inline void u64_stats_add(u64_stats_t *p, unsigned long val)
{
p->v += val;