Skip to content

Commit 098faf5

Browse files
shaohualiaxboe
authored andcommitted
percpu_counter: make APIs irq safe
In my usage, sometimes the percpu APIs are called with irq locked, sometimes not. lockdep complains there is potential deadlock. Let's always use percpucounter lock in irq safe way. There should be no performance penality, as all those are slow code path. Cc: Andrew Morton <[email protected]> Signed-off-by: Shaohua Li <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 71fe07d commit 098faf5

File tree

1 file changed

+9
-6
lines changed

1 file changed

+9
-6
lines changed

lib/percpu_counter.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,15 @@ static inline void debug_percpu_counter_deactivate(struct percpu_counter *fbc)
6060
void percpu_counter_set(struct percpu_counter *fbc, s64 amount)
6161
{
6262
int cpu;
63+
unsigned long flags;
6364

64-
raw_spin_lock(&fbc->lock);
65+
raw_spin_lock_irqsave(&fbc->lock, flags);
6566
for_each_possible_cpu(cpu) {
6667
s32 *pcount = per_cpu_ptr(fbc->counters, cpu);
6768
*pcount = 0;
6869
}
6970
fbc->count = amount;
70-
raw_spin_unlock(&fbc->lock);
71+
raw_spin_unlock_irqrestore(&fbc->lock, flags);
7172
}
7273
EXPORT_SYMBOL(percpu_counter_set);
7374

@@ -78,9 +79,10 @@ void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch)
7879
preempt_disable();
7980
count = __this_cpu_read(*fbc->counters) + amount;
8081
if (count >= batch || count <= -batch) {
81-
raw_spin_lock(&fbc->lock);
82+
unsigned long flags;
83+
raw_spin_lock_irqsave(&fbc->lock, flags);
8284
fbc->count += count;
83-
raw_spin_unlock(&fbc->lock);
85+
raw_spin_unlock_irqrestore(&fbc->lock, flags);
8486
__this_cpu_write(*fbc->counters, 0);
8587
} else {
8688
__this_cpu_write(*fbc->counters, count);
@@ -97,14 +99,15 @@ s64 __percpu_counter_sum(struct percpu_counter *fbc)
9799
{
98100
s64 ret;
99101
int cpu;
102+
unsigned long flags;
100103

101-
raw_spin_lock(&fbc->lock);
104+
raw_spin_lock_irqsave(&fbc->lock, flags);
102105
ret = fbc->count;
103106
for_each_online_cpu(cpu) {
104107
s32 *pcount = per_cpu_ptr(fbc->counters, cpu);
105108
ret += *pcount;
106109
}
107-
raw_spin_unlock(&fbc->lock);
110+
raw_spin_unlock_irqrestore(&fbc->lock, flags);
108111
return ret;
109112
}
110113
EXPORT_SYMBOL(__percpu_counter_sum);

0 commit comments

Comments
 (0)