diff options
Diffstat (limited to 'lib/percpu_counter.c')
| -rw-r--r-- | lib/percpu_counter.c | 21 | 
1 files changed, 12 insertions, 9 deletions
diff --git a/lib/percpu_counter.c b/lib/percpu_counter.c index 93c5d5ecff4..7dd33577b90 100644 --- a/lib/percpu_counter.c +++ b/lib/percpu_counter.c @@ -60,14 +60,15 @@ static inline void debug_percpu_counter_deactivate(struct percpu_counter *fbc)  void percpu_counter_set(struct percpu_counter *fbc, s64 amount)  {  	int cpu; +	unsigned long flags; -	raw_spin_lock(&fbc->lock); +	raw_spin_lock_irqsave(&fbc->lock, flags);  	for_each_possible_cpu(cpu) {  		s32 *pcount = per_cpu_ptr(fbc->counters, cpu);  		*pcount = 0;  	}  	fbc->count = amount; -	raw_spin_unlock(&fbc->lock); +	raw_spin_unlock_irqrestore(&fbc->lock, flags);  }  EXPORT_SYMBOL(percpu_counter_set); @@ -78,12 +79,13 @@ void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch)  	preempt_disable();  	count = __this_cpu_read(*fbc->counters) + amount;  	if (count >= batch || count <= -batch) { -		raw_spin_lock(&fbc->lock); +		unsigned long flags; +		raw_spin_lock_irqsave(&fbc->lock, flags);  		fbc->count += count; -		raw_spin_unlock(&fbc->lock); -		__this_cpu_write(*fbc->counters, 0); +		__this_cpu_sub(*fbc->counters, count - amount); +		raw_spin_unlock_irqrestore(&fbc->lock, flags);  	} else { -		__this_cpu_write(*fbc->counters, count); +		this_cpu_add(*fbc->counters, amount);  	}  	preempt_enable();  } @@ -97,14 +99,15 @@ s64 __percpu_counter_sum(struct percpu_counter *fbc)  {  	s64 ret;  	int cpu; +	unsigned long flags; -	raw_spin_lock(&fbc->lock); +	raw_spin_lock_irqsave(&fbc->lock, flags);  	ret = fbc->count;  	for_each_online_cpu(cpu) {  		s32 *pcount = per_cpu_ptr(fbc->counters, cpu);  		ret += *pcount;  	} -	raw_spin_unlock(&fbc->lock); +	raw_spin_unlock_irqrestore(&fbc->lock, flags);  	return ret;  }  EXPORT_SYMBOL(__percpu_counter_sum); @@ -166,7 +169,7 @@ static int percpu_counter_hotcpu_callback(struct notifier_block *nb,  	struct percpu_counter *fbc;  	compute_batch_value(); -	if (action != CPU_DEAD) +	if (action != CPU_DEAD && action != CPU_DEAD_FROZEN)  		return NOTIFY_OK;  	cpu = (unsigned long)hcpu;  | 
