diff options
Diffstat (limited to 'kernel/irq/irqdesc.c')
| -rw-r--r-- | kernel/irq/irqdesc.c | 13 | 
1 files changed, 7 insertions, 6 deletions
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index afc7f902d74a..578d0e5f1b5b 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;  }  |