diff options
-rw-r--r-- | fs/ext4/balloc.c | 4 | ||||
-rw-r--r-- | include/linux/percpu_counter.h | 12 | ||||
-rw-r--r-- | lib/percpu_counter.c | 8 |
3 files changed, 16 insertions, 8 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index d2003cdc36aa..c17f69bcd7dd 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -609,8 +609,8 @@ int ext4_has_free_blocks(struct ext4_sb_info *sbi, s64 nblocks) | |||
609 | 609 | ||
610 | if (free_blocks - (nblocks + root_blocks + dirty_blocks) < | 610 | if (free_blocks - (nblocks + root_blocks + dirty_blocks) < |
611 | EXT4_FREEBLOCKS_WATERMARK) { | 611 | EXT4_FREEBLOCKS_WATERMARK) { |
612 | free_blocks = percpu_counter_sum(fbc); | 612 | free_blocks = percpu_counter_sum_and_set(fbc); |
613 | dirty_blocks = percpu_counter_sum(dbc); | 613 | dirty_blocks = percpu_counter_sum_and_set(dbc); |
614 | if (dirty_blocks < 0) { | 614 | if (dirty_blocks < 0) { |
615 | printk(KERN_CRIT "Dirty block accounting " | 615 | printk(KERN_CRIT "Dirty block accounting " |
616 | "went wrong %lld\n", | 616 | "went wrong %lld\n", |
diff --git a/include/linux/percpu_counter.h b/include/linux/percpu_counter.h index 9007ccdfc112..208388835357 100644 --- a/include/linux/percpu_counter.h +++ b/include/linux/percpu_counter.h | |||
@@ -35,7 +35,7 @@ int percpu_counter_init_irq(struct percpu_counter *fbc, s64 amount); | |||
35 | void percpu_counter_destroy(struct percpu_counter *fbc); | 35 | void percpu_counter_destroy(struct percpu_counter *fbc); |
36 | void percpu_counter_set(struct percpu_counter *fbc, s64 amount); | 36 | void percpu_counter_set(struct percpu_counter *fbc, s64 amount); |
37 | void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch); | 37 | void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch); |
38 | s64 __percpu_counter_sum(struct percpu_counter *fbc); | 38 | s64 __percpu_counter_sum(struct percpu_counter *fbc, int set); |
39 | 39 | ||
40 | static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount) | 40 | static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount) |
41 | { | 41 | { |
@@ -44,13 +44,19 @@ static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount) | |||
44 | 44 | ||
45 | static inline s64 percpu_counter_sum_positive(struct percpu_counter *fbc) | 45 | static inline s64 percpu_counter_sum_positive(struct percpu_counter *fbc) |
46 | { | 46 | { |
47 | s64 ret = __percpu_counter_sum(fbc); | 47 | s64 ret = __percpu_counter_sum(fbc, 0); |
48 | return ret < 0 ? 0 : ret; | 48 | return ret < 0 ? 0 : ret; |
49 | } | 49 | } |
50 | 50 | ||
51 | static inline s64 percpu_counter_sum_and_set(struct percpu_counter *fbc) | ||
52 | { | ||
53 | return __percpu_counter_sum(fbc, 1); | ||
54 | } | ||
55 | |||
56 | |||
51 | static inline s64 percpu_counter_sum(struct percpu_counter *fbc) | 57 | static inline s64 percpu_counter_sum(struct percpu_counter *fbc) |
52 | { | 58 | { |
53 | return __percpu_counter_sum(fbc); | 59 | return __percpu_counter_sum(fbc, 0); |
54 | } | 60 | } |
55 | 61 | ||
56 | static inline s64 percpu_counter_read(struct percpu_counter *fbc) | 62 | static inline s64 percpu_counter_read(struct percpu_counter *fbc) |
diff --git a/lib/percpu_counter.c b/lib/percpu_counter.c index 71b265c330ce..dba1530a5b29 100644 --- a/lib/percpu_counter.c +++ b/lib/percpu_counter.c | |||
@@ -52,7 +52,7 @@ EXPORT_SYMBOL(__percpu_counter_add); | |||
52 | * Add up all the per-cpu counts, return the result. This is a more accurate | 52 | * Add up all the per-cpu counts, return the result. This is a more accurate |
53 | * but much slower version of percpu_counter_read_positive() | 53 | * but much slower version of percpu_counter_read_positive() |
54 | */ | 54 | */ |
55 | s64 __percpu_counter_sum(struct percpu_counter *fbc) | 55 | s64 __percpu_counter_sum(struct percpu_counter *fbc, int set) |
56 | { | 56 | { |
57 | s64 ret; | 57 | s64 ret; |
58 | int cpu; | 58 | int cpu; |
@@ -62,9 +62,11 @@ s64 __percpu_counter_sum(struct percpu_counter *fbc) | |||
62 | for_each_online_cpu(cpu) { | 62 | for_each_online_cpu(cpu) { |
63 | s32 *pcount = per_cpu_ptr(fbc->counters, cpu); | 63 | s32 *pcount = per_cpu_ptr(fbc->counters, cpu); |
64 | ret += *pcount; | 64 | ret += *pcount; |
65 | *pcount = 0; | 65 | if (set) |
66 | *pcount = 0; | ||
66 | } | 67 | } |
67 | fbc->count = ret; | 68 | if (set) |
69 | fbc->count = ret; | ||
68 | 70 | ||
69 | spin_unlock(&fbc->lock); | 71 | spin_unlock(&fbc->lock); |
70 | return ret; | 72 | return ret; |