revert "percpu_counter: new function percpu_counter_sum_and_set"
Revert
commit e8ced39d5e
Author: Mingming Cao <cmm@us.ibm.com>
Date: Fri Jul 11 19:27:31 2008 -0400
percpu_counter: new function percpu_counter_sum_and_set
As described in
revert "percpu counter: clean up percpu_counter_sum_and_set()"
the new percpu_counter_sum_and_set() is racy against updates to the
cpu-local accumulators on other CPUs. Revert that change.
This means that ext4 will be slow again. But correct.
Reported-by: Eric Dumazet <dada1@cosmosbay.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mingming Cao <cmm@us.ibm.com>
Cc: <linux-ext4@vger.kernel.org>
Cc: <stable@kernel.org> [2.6.27.x]
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
71c5576fbd
commit
02d2116887
|
@ -609,8 +609,8 @@ int ext4_has_free_blocks(struct ext4_sb_info *sbi, s64 nblocks)
|
||||||
|
|
||||||
if (free_blocks - (nblocks + root_blocks + dirty_blocks) <
|
if (free_blocks - (nblocks + root_blocks + dirty_blocks) <
|
||||||
EXT4_FREEBLOCKS_WATERMARK) {
|
EXT4_FREEBLOCKS_WATERMARK) {
|
||||||
free_blocks = percpu_counter_sum_and_set(fbc);
|
free_blocks = percpu_counter_sum_positive(fbc);
|
||||||
dirty_blocks = percpu_counter_sum_and_set(dbc);
|
dirty_blocks = percpu_counter_sum_positive(dbc);
|
||||||
if (dirty_blocks < 0) {
|
if (dirty_blocks < 0) {
|
||||||
printk(KERN_CRIT "Dirty block accounting "
|
printk(KERN_CRIT "Dirty block accounting "
|
||||||
"went wrong %lld\n",
|
"went wrong %lld\n",
|
||||||
|
|
|
@ -35,7 +35,7 @@ int percpu_counter_init_irq(struct percpu_counter *fbc, s64 amount);
|
||||||
void percpu_counter_destroy(struct percpu_counter *fbc);
|
void percpu_counter_destroy(struct percpu_counter *fbc);
|
||||||
void percpu_counter_set(struct percpu_counter *fbc, s64 amount);
|
void percpu_counter_set(struct percpu_counter *fbc, s64 amount);
|
||||||
void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch);
|
void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch);
|
||||||
s64 __percpu_counter_sum(struct percpu_counter *fbc, int set);
|
s64 __percpu_counter_sum(struct percpu_counter *fbc);
|
||||||
|
|
||||||
static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount)
|
static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount)
|
||||||
{
|
{
|
||||||
|
@ -44,19 +44,13 @@ static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount)
|
||||||
|
|
||||||
static inline s64 percpu_counter_sum_positive(struct percpu_counter *fbc)
|
static inline s64 percpu_counter_sum_positive(struct percpu_counter *fbc)
|
||||||
{
|
{
|
||||||
s64 ret = __percpu_counter_sum(fbc, 0);
|
s64 ret = __percpu_counter_sum(fbc);
|
||||||
return ret < 0 ? 0 : ret;
|
return ret < 0 ? 0 : ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline s64 percpu_counter_sum_and_set(struct percpu_counter *fbc)
|
|
||||||
{
|
|
||||||
return __percpu_counter_sum(fbc, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline s64 percpu_counter_sum(struct percpu_counter *fbc)
|
static inline s64 percpu_counter_sum(struct percpu_counter *fbc)
|
||||||
{
|
{
|
||||||
return __percpu_counter_sum(fbc, 0);
|
return __percpu_counter_sum(fbc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline s64 percpu_counter_read(struct percpu_counter *fbc)
|
static inline s64 percpu_counter_read(struct percpu_counter *fbc)
|
||||||
|
|
|
@ -52,7 +52,7 @@ EXPORT_SYMBOL(__percpu_counter_add);
|
||||||
* Add up all the per-cpu counts, return the result. This is a more accurate
|
* Add up all the per-cpu counts, return the result. This is a more accurate
|
||||||
* but much slower version of percpu_counter_read_positive()
|
* but much slower version of percpu_counter_read_positive()
|
||||||
*/
|
*/
|
||||||
s64 __percpu_counter_sum(struct percpu_counter *fbc, int set)
|
s64 __percpu_counter_sum(struct percpu_counter *fbc)
|
||||||
{
|
{
|
||||||
s64 ret;
|
s64 ret;
|
||||||
int cpu;
|
int cpu;
|
||||||
|
@ -62,12 +62,7 @@ s64 __percpu_counter_sum(struct percpu_counter *fbc, int set)
|
||||||
for_each_online_cpu(cpu) {
|
for_each_online_cpu(cpu) {
|
||||||
s32 *pcount = per_cpu_ptr(fbc->counters, cpu);
|
s32 *pcount = per_cpu_ptr(fbc->counters, cpu);
|
||||||
ret += *pcount;
|
ret += *pcount;
|
||||||
if (set)
|
|
||||||
*pcount = 0;
|
|
||||||
}
|
}
|
||||||
if (set)
|
|
||||||
fbc->count = ret;
|
|
||||||
|
|
||||||
spin_unlock(&fbc->lock);
|
spin_unlock(&fbc->lock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue