diff options
author | Tejun Heo <tj@kernel.org> | 2015-05-22 17:13:27 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2015-06-02 10:33:34 -0400 |
commit | 93f78d882865cb90020d0f80a9523c99cf46924c (patch) | |
tree | 6cd9c3531085c7d51fbd6ec2086142255bc2c219 /mm/backing-dev.c | |
parent | 4452226ea276e74fc3e252c88d9bb7e8f8e44bf0 (diff) |
writeback: move backing_dev_info->bdi_stat[] into bdi_writeback
Currently, a bdi (backing_dev_info) embeds single wb (bdi_writeback)
and the role of the separation is unclear. For cgroup support for
writeback IOs, a bdi will be updated to host multiple wb's where each
wb serves writeback IOs of a different cgroup on the bdi. To achieve
that, a wb should carry all states necessary for servicing writeback
IOs for a cgroup independently.
This patch moves bdi->bdi_stat[] into wb.
* enum bdi_stat_item is renamed to wb_stat_item and the prefix of all
enums is changed from BDI_ to WB_.
* BDI_STAT_BATCH() -> WB_STAT_BATCH()
* [__]{add|inc|dec|sum}_wb_stat(bdi, ...) -> [__]{add|inc}_wb_stat(wb, ...)
* bdi_stat[_error]() -> wb_stat[_error]()
* bdi_writeout_inc() -> wb_writeout_inc()
* stat init is moved to bdi_wb_init() and bdi_wb_exit() is added and
frees stat.
* As there's still only one bdi_writeback per backing_dev_info, all
uses of bdi->stat[] are mechanically replaced with bdi->wb.stat[]
introducing no behavior changes.
Signed-off-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Jan Kara <jack@suse.cz>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Miklos Szeredi <miklos@szeredi.hu>
Cc: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'mm/backing-dev.c')
-rw-r--r-- | mm/backing-dev.c | 60 |
1 files changed, 37 insertions, 23 deletions
diff --git a/mm/backing-dev.c b/mm/backing-dev.c index b23cf0ea5912..7b1d1917b658 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c | |||
@@ -84,13 +84,13 @@ static int bdi_debug_stats_show(struct seq_file *m, void *v) | |||
84 | "b_dirty_time: %10lu\n" | 84 | "b_dirty_time: %10lu\n" |
85 | "bdi_list: %10u\n" | 85 | "bdi_list: %10u\n" |
86 | "state: %10lx\n", | 86 | "state: %10lx\n", |
87 | (unsigned long) K(bdi_stat(bdi, BDI_WRITEBACK)), | 87 | (unsigned long) K(wb_stat(wb, WB_WRITEBACK)), |
88 | (unsigned long) K(bdi_stat(bdi, BDI_RECLAIMABLE)), | 88 | (unsigned long) K(wb_stat(wb, WB_RECLAIMABLE)), |
89 | K(bdi_thresh), | 89 | K(bdi_thresh), |
90 | K(dirty_thresh), | 90 | K(dirty_thresh), |
91 | K(background_thresh), | 91 | K(background_thresh), |
92 | (unsigned long) K(bdi_stat(bdi, BDI_DIRTIED)), | 92 | (unsigned long) K(wb_stat(wb, WB_DIRTIED)), |
93 | (unsigned long) K(bdi_stat(bdi, BDI_WRITTEN)), | 93 | (unsigned long) K(wb_stat(wb, WB_WRITTEN)), |
94 | (unsigned long) K(bdi->write_bandwidth), | 94 | (unsigned long) K(bdi->write_bandwidth), |
95 | nr_dirty, | 95 | nr_dirty, |
96 | nr_io, | 96 | nr_io, |
@@ -376,8 +376,10 @@ void bdi_unregister(struct backing_dev_info *bdi) | |||
376 | } | 376 | } |
377 | EXPORT_SYMBOL(bdi_unregister); | 377 | EXPORT_SYMBOL(bdi_unregister); |
378 | 378 | ||
379 | static void bdi_wb_init(struct bdi_writeback *wb, struct backing_dev_info *bdi) | 379 | static int bdi_wb_init(struct bdi_writeback *wb, struct backing_dev_info *bdi) |
380 | { | 380 | { |
381 | int i, err; | ||
382 | |||
381 | memset(wb, 0, sizeof(*wb)); | 383 | memset(wb, 0, sizeof(*wb)); |
382 | 384 | ||
383 | wb->bdi = bdi; | 385 | wb->bdi = bdi; |
@@ -388,6 +390,27 @@ static void bdi_wb_init(struct bdi_writeback *wb, struct backing_dev_info *bdi) | |||
388 | INIT_LIST_HEAD(&wb->b_dirty_time); | 390 | INIT_LIST_HEAD(&wb->b_dirty_time); |
389 | spin_lock_init(&wb->list_lock); | 391 | spin_lock_init(&wb->list_lock); |
390 | INIT_DELAYED_WORK(&wb->dwork, bdi_writeback_workfn); | 392 | INIT_DELAYED_WORK(&wb->dwork, bdi_writeback_workfn); |
393 | |||
394 | for (i = 0; i < NR_WB_STAT_ITEMS; i++) { | ||
395 | err = percpu_counter_init(&wb->stat[i], 0, GFP_KERNEL); | ||
396 | if (err) { | ||
397 | while (--i) | ||
398 | percpu_counter_destroy(&wb->stat[i]); | ||
399 | return err; | ||
400 | } | ||
401 | } | ||
402 | |||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | static void bdi_wb_exit(struct bdi_writeback *wb) | ||
407 | { | ||
408 | int i; | ||
409 | |||
410 | WARN_ON(delayed_work_pending(&wb->dwork)); | ||
411 | |||
412 | for (i = 0; i < NR_WB_STAT_ITEMS; i++) | ||
413 | percpu_counter_destroy(&wb->stat[i]); | ||
391 | } | 414 | } |
392 | 415 | ||
393 | /* | 416 | /* |
@@ -397,7 +420,7 @@ static void bdi_wb_init(struct bdi_writeback *wb, struct backing_dev_info *bdi) | |||
397 | 420 | ||
398 | int bdi_init(struct backing_dev_info *bdi) | 421 | int bdi_init(struct backing_dev_info *bdi) |
399 | { | 422 | { |
400 | int i, err; | 423 | int err; |
401 | 424 | ||
402 | bdi->dev = NULL; | 425 | bdi->dev = NULL; |
403 | 426 | ||
@@ -408,13 +431,9 @@ int bdi_init(struct backing_dev_info *bdi) | |||
408 | INIT_LIST_HEAD(&bdi->bdi_list); | 431 | INIT_LIST_HEAD(&bdi->bdi_list); |
409 | INIT_LIST_HEAD(&bdi->work_list); | 432 | INIT_LIST_HEAD(&bdi->work_list); |
410 | 433 | ||
411 | bdi_wb_init(&bdi->wb, bdi); | 434 | err = bdi_wb_init(&bdi->wb, bdi); |
412 | 435 | if (err) | |
413 | for (i = 0; i < NR_BDI_STAT_ITEMS; i++) { | 436 | return err; |
414 | err = percpu_counter_init(&bdi->bdi_stat[i], 0, GFP_KERNEL); | ||
415 | if (err) | ||
416 | goto err; | ||
417 | } | ||
418 | 437 | ||
419 | bdi->dirty_exceeded = 0; | 438 | bdi->dirty_exceeded = 0; |
420 | 439 | ||
@@ -427,25 +446,20 @@ int bdi_init(struct backing_dev_info *bdi) | |||
427 | bdi->avg_write_bandwidth = INIT_BW; | 446 | bdi->avg_write_bandwidth = INIT_BW; |
428 | 447 | ||
429 | err = fprop_local_init_percpu(&bdi->completions, GFP_KERNEL); | 448 | err = fprop_local_init_percpu(&bdi->completions, GFP_KERNEL); |
430 | |||
431 | if (err) { | 449 | if (err) { |
432 | err: | 450 | bdi_wb_exit(&bdi->wb); |
433 | while (i--) | 451 | return err; |
434 | percpu_counter_destroy(&bdi->bdi_stat[i]); | ||
435 | } | 452 | } |
436 | 453 | ||
437 | return err; | 454 | return 0; |
438 | } | 455 | } |
439 | EXPORT_SYMBOL(bdi_init); | 456 | EXPORT_SYMBOL(bdi_init); |
440 | 457 | ||
441 | void bdi_destroy(struct backing_dev_info *bdi) | 458 | void bdi_destroy(struct backing_dev_info *bdi) |
442 | { | 459 | { |
443 | int i; | ||
444 | |||
445 | bdi_wb_shutdown(bdi); | 460 | bdi_wb_shutdown(bdi); |
446 | 461 | ||
447 | WARN_ON(!list_empty(&bdi->work_list)); | 462 | WARN_ON(!list_empty(&bdi->work_list)); |
448 | WARN_ON(delayed_work_pending(&bdi->wb.dwork)); | ||
449 | 463 | ||
450 | if (bdi->dev) { | 464 | if (bdi->dev) { |
451 | bdi_debug_unregister(bdi); | 465 | bdi_debug_unregister(bdi); |
@@ -453,8 +467,8 @@ void bdi_destroy(struct backing_dev_info *bdi) | |||
453 | bdi->dev = NULL; | 467 | bdi->dev = NULL; |
454 | } | 468 | } |
455 | 469 | ||
456 | for (i = 0; i < NR_BDI_STAT_ITEMS; i++) | 470 | bdi_wb_exit(&bdi->wb); |
457 | percpu_counter_destroy(&bdi->bdi_stat[i]); | 471 | |
458 | fprop_local_destroy_percpu(&bdi->completions); | 472 | fprop_local_destroy_percpu(&bdi->completions); |
459 | } | 473 | } |
460 | EXPORT_SYMBOL(bdi_destroy); | 474 | EXPORT_SYMBOL(bdi_destroy); |