Commit e78d4833 authored by Jan Kara's avatar Jan Kara Committed by Fengguang Wu

lib: Fix possible deadlock in flexible proportion code

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: default avatarJan Kara <jack@suse.cz>
Signed-off-by: default avatarFengguang Wu <fengguang.wu@intel.com>
parent f3109a51
...@@ -62,13 +62,18 @@ void fprop_global_destroy(struct fprop_global *p) ...@@ -62,13 +62,18 @@ void fprop_global_destroy(struct fprop_global *p)
*/ */
bool fprop_new_period(struct fprop_global *p, int periods) 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. * Don't do anything if there are no events.
*/ */
if (events <= 1) if (events <= 1) {
local_irq_restore(flags);
return false; return false;
}
write_seqcount_begin(&p->sequence); write_seqcount_begin(&p->sequence);
if (periods < 64) if (periods < 64)
events -= events >> periods; events -= events >> periods;
...@@ -76,6 +81,7 @@ bool fprop_new_period(struct fprop_global *p, int periods) ...@@ -76,6 +81,7 @@ bool fprop_new_period(struct fprop_global *p, int periods)
percpu_counter_add(&p->events, -events); percpu_counter_add(&p->events, -events);
p->period += periods; p->period += periods;
write_seqcount_end(&p->sequence); write_seqcount_end(&p->sequence);
local_irq_restore(flags);
return true; return true;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment