From: Jan Kara Subject: 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: Jan Kara diff --git a/lib/flex_proportions.c b/lib/flex_proportions.c index 530dbc2..fbf6b11 100644 --- a/lib/flex_proportions.c +++ b/lib/flex_proportions.c @@ -62,8 +62,12 @@ void fprop_global_destroy(struct fprop_global *p) */ 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); + local_irq_restore(flags); /* * Don't do anything if there are no events. */ @@ -73,7 +77,9 @@ bool fprop_new_period(struct fprop_global *p, int periods) if (periods < 64) events -= events >> periods; /* Use addition to avoid losing events happening between sum and set */ + local_irq_save(flags); percpu_counter_add(&p->events, -events); + local_irq_restore(flags); p->period += periods; write_seqcount_end(&p->sequence);