diff options
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, |
