diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-07 20:02:58 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-07 20:02:58 -0500 |
commit | 72eb6a791459c87a0340318840bb3bd9252b627b (patch) | |
tree | 3bfb8ad99f9c7e511f37f72d57b56a2cea06d753 /fs | |
parent | 23d69b09b78c4876e134f104a3814c30747c53f1 (diff) | |
parent | 55ee4ef30241a62b700f79517e6d5ef2ddbefa67 (diff) |
Merge branch 'for-2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu
* 'for-2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu: (30 commits)
gameport: use this_cpu_read instead of lookup
x86: udelay: Use this_cpu_read to avoid address calculation
x86: Use this_cpu_inc_return for nmi counter
x86: Replace uses of current_cpu_data with this_cpu ops
x86: Use this_cpu_ops to optimize code
vmstat: User per cpu atomics to avoid interrupt disable / enable
irq_work: Use per cpu atomics instead of regular atomics
cpuops: Use cmpxchg for xchg to avoid lock semantics
x86: this_cpu_cmpxchg and this_cpu_xchg operations
percpu: Generic this_cpu_cmpxchg() and this_cpu_xchg support
percpu,x86: relocate this_cpu_add_return() and friends
connector: Use this_cpu operations
xen: Use this_cpu_inc_return
taskstats: Use this_cpu_ops
random: Use this_cpu_inc_return
fs: Use this_cpu_inc_return in buffer.c
highmem: Use this_cpu_xx_return() operations
vmstat: Use this_cpu_inc_return for vm statistics
x86: Support for this_cpu_add, sub, dec, inc_return
percpu: Generic support for this_cpu_add, sub, dec, inc_return
...
Fixed up conflicts: in arch/x86/kernel/{apic/nmi.c, apic/x2apic_uv_x.c, process.c}
as per Tejun.
Diffstat (limited to 'fs')
-rw-r--r-- | fs/buffer.c | 37 |
1 files changed, 18 insertions, 19 deletions
diff --git a/fs/buffer.c b/fs/buffer.c index 5930e382959b..2219a76e2caf 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -1270,12 +1270,10 @@ static inline void check_irqs_on(void) | |||
1270 | static void bh_lru_install(struct buffer_head *bh) | 1270 | static void bh_lru_install(struct buffer_head *bh) |
1271 | { | 1271 | { |
1272 | struct buffer_head *evictee = NULL; | 1272 | struct buffer_head *evictee = NULL; |
1273 | struct bh_lru *lru; | ||
1274 | 1273 | ||
1275 | check_irqs_on(); | 1274 | check_irqs_on(); |
1276 | bh_lru_lock(); | 1275 | bh_lru_lock(); |
1277 | lru = &__get_cpu_var(bh_lrus); | 1276 | if (__this_cpu_read(bh_lrus.bhs[0]) != bh) { |
1278 | if (lru->bhs[0] != bh) { | ||
1279 | struct buffer_head *bhs[BH_LRU_SIZE]; | 1277 | struct buffer_head *bhs[BH_LRU_SIZE]; |
1280 | int in; | 1278 | int in; |
1281 | int out = 0; | 1279 | int out = 0; |
@@ -1283,7 +1281,8 @@ static void bh_lru_install(struct buffer_head *bh) | |||
1283 | get_bh(bh); | 1281 | get_bh(bh); |
1284 | bhs[out++] = bh; | 1282 | bhs[out++] = bh; |
1285 | for (in = 0; in < BH_LRU_SIZE; in++) { | 1283 | for (in = 0; in < BH_LRU_SIZE; in++) { |
1286 | struct buffer_head *bh2 = lru->bhs[in]; | 1284 | struct buffer_head *bh2 = |
1285 | __this_cpu_read(bh_lrus.bhs[in]); | ||
1287 | 1286 | ||
1288 | if (bh2 == bh) { | 1287 | if (bh2 == bh) { |
1289 | __brelse(bh2); | 1288 | __brelse(bh2); |
@@ -1298,7 +1297,7 @@ static void bh_lru_install(struct buffer_head *bh) | |||
1298 | } | 1297 | } |
1299 | while (out < BH_LRU_SIZE) | 1298 | while (out < BH_LRU_SIZE) |
1300 | bhs[out++] = NULL; | 1299 | bhs[out++] = NULL; |
1301 | memcpy(lru->bhs, bhs, sizeof(bhs)); | 1300 | memcpy(__this_cpu_ptr(&bh_lrus.bhs), bhs, sizeof(bhs)); |
1302 | } | 1301 | } |
1303 | bh_lru_unlock(); | 1302 | bh_lru_unlock(); |
1304 | 1303 | ||
@@ -1313,23 +1312,22 @@ static struct buffer_head * | |||
1313 | lookup_bh_lru(struct block_device *bdev, sector_t block, unsigned size) | 1312 | lookup_bh_lru(struct block_device *bdev, sector_t block, unsigned size) |
1314 | { | 1313 | { |
1315 | struct buffer_head *ret = NULL; | 1314 | struct buffer_head *ret = NULL; |
1316 | struct bh_lru *lru; | ||
1317 | unsigned int i; | 1315 | unsigned int i; |
1318 | 1316 | ||
1319 | check_irqs_on(); | 1317 | check_irqs_on(); |
1320 | bh_lru_lock(); | 1318 | bh_lru_lock(); |
1321 | lru = &__get_cpu_var(bh_lrus); | ||
1322 | for (i = 0; i < BH_LRU_SIZE; i++) { | 1319 | for (i = 0; i < BH_LRU_SIZE; i++) { |
1323 | struct buffer_head *bh = lru->bhs[i]; | 1320 | struct buffer_head *bh = __this_cpu_read(bh_lrus.bhs[i]); |
1324 | 1321 | ||
1325 | if (bh && bh->b_bdev == bdev && | 1322 | if (bh && bh->b_bdev == bdev && |
1326 | bh->b_blocknr == block && bh->b_size == size) { | 1323 | bh->b_blocknr == block && bh->b_size == size) { |
1327 | if (i) { | 1324 | if (i) { |
1328 | while (i) { | 1325 | while (i) { |
1329 | lru->bhs[i] = lru->bhs[i - 1]; | 1326 | __this_cpu_write(bh_lrus.bhs[i], |
1327 | __this_cpu_read(bh_lrus.bhs[i - 1])); | ||
1330 | i--; | 1328 | i--; |
1331 | } | 1329 | } |
1332 | lru->bhs[0] = bh; | 1330 | __this_cpu_write(bh_lrus.bhs[0], bh); |
1333 | } | 1331 | } |
1334 | get_bh(bh); | 1332 | get_bh(bh); |
1335 | ret = bh; | 1333 | ret = bh; |
@@ -3203,22 +3201,23 @@ static void recalc_bh_state(void) | |||
3203 | int i; | 3201 | int i; |
3204 | int tot = 0; | 3202 | int tot = 0; |
3205 | 3203 | ||
3206 | if (__get_cpu_var(bh_accounting).ratelimit++ < 4096) | 3204 | if (__this_cpu_inc_return(bh_accounting.ratelimit) - 1 < 4096) |
3207 | return; | 3205 | return; |
3208 | __get_cpu_var(bh_accounting).ratelimit = 0; | 3206 | __this_cpu_write(bh_accounting.ratelimit, 0); |
3209 | for_each_online_cpu(i) | 3207 | for_each_online_cpu(i) |
3210 | tot += per_cpu(bh_accounting, i).nr; | 3208 | tot += per_cpu(bh_accounting, i).nr; |
3211 | buffer_heads_over_limit = (tot > max_buffer_heads); | 3209 | buffer_heads_over_limit = (tot > max_buffer_heads); |
3212 | } | 3210 | } |
3213 | 3211 | ||
3214 | struct buffer_head *alloc_buffer_head(gfp_t gfp_flags) | 3212 | struct buffer_head *alloc_buffer_head(gfp_t gfp_flags) |
3215 | { | 3213 | { |
3216 | struct buffer_head *ret = kmem_cache_zalloc(bh_cachep, gfp_flags); | 3214 | struct buffer_head *ret = kmem_cache_zalloc(bh_cachep, gfp_flags); |
3217 | if (ret) { | 3215 | if (ret) { |
3218 | INIT_LIST_HEAD(&ret->b_assoc_buffers); | 3216 | INIT_LIST_HEAD(&ret->b_assoc_buffers); |
3219 | get_cpu_var(bh_accounting).nr++; | 3217 | preempt_disable(); |
3218 | __this_cpu_inc(bh_accounting.nr); | ||
3220 | recalc_bh_state(); | 3219 | recalc_bh_state(); |
3221 | put_cpu_var(bh_accounting); | 3220 | preempt_enable(); |
3222 | } | 3221 | } |
3223 | return ret; | 3222 | return ret; |
3224 | } | 3223 | } |
@@ -3228,9 +3227,10 @@ void free_buffer_head(struct buffer_head *bh) | |||
3228 | { | 3227 | { |
3229 | BUG_ON(!list_empty(&bh->b_assoc_buffers)); | 3228 | BUG_ON(!list_empty(&bh->b_assoc_buffers)); |
3230 | kmem_cache_free(bh_cachep, bh); | 3229 | kmem_cache_free(bh_cachep, bh); |
3231 | get_cpu_var(bh_accounting).nr--; | 3230 | preempt_disable(); |
3231 | __this_cpu_dec(bh_accounting.nr); | ||
3232 | recalc_bh_state(); | 3232 | recalc_bh_state(); |
3233 | put_cpu_var(bh_accounting); | 3233 | preempt_enable(); |
3234 | } | 3234 | } |
3235 | EXPORT_SYMBOL(free_buffer_head); | 3235 | EXPORT_SYMBOL(free_buffer_head); |
3236 | 3236 | ||
@@ -3243,9 +3243,8 @@ static void buffer_exit_cpu(int cpu) | |||
3243 | brelse(b->bhs[i]); | 3243 | brelse(b->bhs[i]); |
3244 | b->bhs[i] = NULL; | 3244 | b->bhs[i] = NULL; |
3245 | } | 3245 | } |
3246 | get_cpu_var(bh_accounting).nr += per_cpu(bh_accounting, cpu).nr; | 3246 | this_cpu_add(bh_accounting.nr, per_cpu(bh_accounting, cpu).nr); |
3247 | per_cpu(bh_accounting, cpu).nr = 0; | 3247 | per_cpu(bh_accounting, cpu).nr = 0; |
3248 | put_cpu_var(bh_accounting); | ||
3249 | } | 3248 | } |
3250 | 3249 | ||
3251 | static int buffer_cpu_notify(struct notifier_block *self, | 3250 | static int buffer_cpu_notify(struct notifier_block *self, |