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; |
