]> git.karo-electronics.de Git - linux-beck.git/commitdiff
lib: Fix possible deadlock in flexible proportion code
authorJan Kara <jack@suse.cz>
Thu, 31 May 2012 22:42:06 +0000 (00:42 +0200)
committerFengguang Wu <fengguang.wu@intel.com>
Fri, 8 Jun 2012 23:37:55 +0000 (08:37 +0900)
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>
lib/flex_proportions.c

index e02a3883ae01444352775f6823d7a61a5b77dd6c..c785554f95237897edc7e86f7c3ea6f1811b9bbf 100644 (file)
@@ -62,13 +62,18 @@ 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);
        /*
         * 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;
@@ -76,6 +81,7 @@ bool fprop_new_period(struct fprop_global *p, int periods)
        percpu_counter_add(&p->events, -events);
        p->period += periods;
        write_seqcount_end(&p->sequence);
+       local_irq_restore(flags);
 
        return true;
 }