When percpu counter function in fprop_new_period() is interrupted by an
interrupt while holding counter lock, it can cause deadlock when the
interrupt wants to take the lock as well. Fix the problem by disabling
interrupts when calling percpu counter functions.
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
*/
bool fprop_new_period(struct fprop_global *p, int periods)
{
- u64 events = percpu_counter_sum(&p->events);
+ u64 events;
+ unsigned long flags;
+ local_irq_save(flags);
+ events = percpu_counter_sum(&p->events);
/*
* Don't do anything if there are no events.
*/
- if (events <= 1)
+ if (events <= 1) {
+ local_irq_restore(flags);
return false;
+ }
write_seqcount_begin(&p->sequence);
if (periods < 64)
events -= events >> periods;
percpu_counter_add(&p->events, -events);
p->period += periods;
write_seqcount_end(&p->sequence);
+ local_irq_restore(flags);
return true;
}