[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20180618125612.155057-1-edumazet@google.com>
Date: Mon, 18 Jun 2018 05:56:12 -0700
From: Eric Dumazet <edumazet@...gle.com>
To: Thomas Gleixner <tglx@...utronix.de>
Cc: lkml <linux-kernel@...r.kernel.org>,
Eric Dumazet <edumazet@...gle.com>,
Eric Dumazet <eric.dumazet@...il.com>,
Willem de Bruijn <willemb@...gle.com>
Subject: [PATCH] genirq: use rcu in kstat_irqs_usr()
Jeremy Dorfman identified mutex contention when multiple threads
parse /proc/stat concurrently.
Since Thomas Gleixner commit 425a5072dcd1 ("genirq: Free irq_desc
with rcu"), we can easily switch kstat_irqs_usr() to rcu locking
and remove this mutex contetion.
show_interrupts() case will be handled in a separate patch.
Signed-off-by: Eric Dumazet <edumazet@...gle.com>
Reported-by: Jeremy Dorfman <jdorfman@...gle.com>
Cc: Thomas Gleixner <tglx@...utronix.de>
Cc: Willem de Bruijn <willemb@...gle.com>
---
kernel/irq/irqdesc.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index afc7f902d74a3eff5d1f8a5e407159c5d28625f7..a668b7ad8a5d5e3b191e3a1dc8f9f32293658d42 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -443,6 +443,7 @@ static void free_desc(unsigned int irq)
* We free the descriptor, masks and stat fields via RCU. That
* allows demultiplex interrupts to do rcu based management of
* the child interrupts.
+ * This also allows us to use rcu in kstat_irqs_usr().
*/
call_rcu(&desc->rcu, delayed_free_desc);
}
@@ -928,17 +929,17 @@ unsigned int kstat_irqs(unsigned int irq)
* kstat_irqs_usr - Get the statistics for an interrupt
* @irq: The interrupt number
*
- * Returns the sum of interrupt counts on all cpus since boot for
- * @irq. Contrary to kstat_irqs() this can be called from any
- * preemptible context. It's protected against concurrent removal of
- * an interrupt descriptor when sparse irqs are enabled.
+ * Returns the sum of interrupt counts on all cpus since boot for @irq.
+ * Contrary to kstat_irqs() this can be called from any context.
+ * It uses rcu since a concurrent removal of an interrupt descriptor is
+ * observing an rcu grace period before delayed_free_desc()/irq_kobj_release().
*/
unsigned int kstat_irqs_usr(unsigned int irq)
{
unsigned int sum;
- irq_lock_sparse();
+ rcu_read_lock();
sum = kstat_irqs(irq);
- irq_unlock_sparse();
+ rcu_read_unlock();
return sum;
}
--
2.18.0.rc1.244.gcf134e6275-goog
Powered by blists - more mailing lists