diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-01-09 02:38:23 -0500 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-01-09 02:38:23 -0500 |
commit | da733563be5a9da26fe81d9f007262d00b846e22 (patch) | |
tree | db28291df94a2043af2123911984c5c173da4e6f /mm/backing-dev.c | |
parent | 6ccbcf2cb41131f8d56ef0723bf3f7c1f8486076 (diff) | |
parent | dab78d7924598ea4031663dd10db814e2e324928 (diff) |
Merge branch 'next' into for-linus
Diffstat (limited to 'mm/backing-dev.c')
-rw-r--r-- | mm/backing-dev.c | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/mm/backing-dev.c b/mm/backing-dev.c index d6edf8d14f9c..71034f41a2ba 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c | |||
@@ -97,6 +97,7 @@ static int bdi_debug_stats_show(struct seq_file *m, void *v) | |||
97 | "BdiDirtyThresh: %10lu kB\n" | 97 | "BdiDirtyThresh: %10lu kB\n" |
98 | "DirtyThresh: %10lu kB\n" | 98 | "DirtyThresh: %10lu kB\n" |
99 | "BackgroundThresh: %10lu kB\n" | 99 | "BackgroundThresh: %10lu kB\n" |
100 | "BdiDirtied: %10lu kB\n" | ||
100 | "BdiWritten: %10lu kB\n" | 101 | "BdiWritten: %10lu kB\n" |
101 | "BdiWriteBandwidth: %10lu kBps\n" | 102 | "BdiWriteBandwidth: %10lu kBps\n" |
102 | "b_dirty: %10lu\n" | 103 | "b_dirty: %10lu\n" |
@@ -109,6 +110,7 @@ static int bdi_debug_stats_show(struct seq_file *m, void *v) | |||
109 | K(bdi_thresh), | 110 | K(bdi_thresh), |
110 | K(dirty_thresh), | 111 | K(dirty_thresh), |
111 | K(background_thresh), | 112 | K(background_thresh), |
113 | (unsigned long) K(bdi_stat(bdi, BDI_DIRTIED)), | ||
112 | (unsigned long) K(bdi_stat(bdi, BDI_WRITTEN)), | 114 | (unsigned long) K(bdi_stat(bdi, BDI_WRITTEN)), |
113 | (unsigned long) K(bdi->write_bandwidth), | 115 | (unsigned long) K(bdi->write_bandwidth), |
114 | nr_dirty, | 116 | nr_dirty, |
@@ -359,6 +361,17 @@ static unsigned long bdi_longest_inactive(void) | |||
359 | return max(5UL * 60 * HZ, interval); | 361 | return max(5UL * 60 * HZ, interval); |
360 | } | 362 | } |
361 | 363 | ||
364 | /* | ||
365 | * Clear pending bit and wakeup anybody waiting for flusher thread creation or | ||
366 | * shutdown | ||
367 | */ | ||
368 | static void bdi_clear_pending(struct backing_dev_info *bdi) | ||
369 | { | ||
370 | clear_bit(BDI_pending, &bdi->state); | ||
371 | smp_mb__after_clear_bit(); | ||
372 | wake_up_bit(&bdi->state, BDI_pending); | ||
373 | } | ||
374 | |||
362 | static int bdi_forker_thread(void *ptr) | 375 | static int bdi_forker_thread(void *ptr) |
363 | { | 376 | { |
364 | struct bdi_writeback *me = ptr; | 377 | struct bdi_writeback *me = ptr; |
@@ -390,6 +403,12 @@ static int bdi_forker_thread(void *ptr) | |||
390 | } | 403 | } |
391 | 404 | ||
392 | spin_lock_bh(&bdi_lock); | 405 | spin_lock_bh(&bdi_lock); |
406 | /* | ||
407 | * In the following loop we are going to check whether we have | ||
408 | * some work to do without any synchronization with tasks | ||
409 | * waking us up to do work for them. Set the task state here | ||
410 | * so that we don't miss wakeups after verifying conditions. | ||
411 | */ | ||
393 | set_current_state(TASK_INTERRUPTIBLE); | 412 | set_current_state(TASK_INTERRUPTIBLE); |
394 | 413 | ||
395 | list_for_each_entry(bdi, &bdi_list, bdi_list) { | 414 | list_for_each_entry(bdi, &bdi_list, bdi_list) { |
@@ -456,7 +475,8 @@ static int bdi_forker_thread(void *ptr) | |||
456 | * the bdi from the thread. Hopefully 1024 is | 475 | * the bdi from the thread. Hopefully 1024 is |
457 | * large enough for efficient IO. | 476 | * large enough for efficient IO. |
458 | */ | 477 | */ |
459 | writeback_inodes_wb(&bdi->wb, 1024); | 478 | writeback_inodes_wb(&bdi->wb, 1024, |
479 | WB_REASON_FORKER_THREAD); | ||
460 | } else { | 480 | } else { |
461 | /* | 481 | /* |
462 | * The spinlock makes sure we do not lose | 482 | * The spinlock makes sure we do not lose |
@@ -469,11 +489,13 @@ static int bdi_forker_thread(void *ptr) | |||
469 | spin_unlock_bh(&bdi->wb_lock); | 489 | spin_unlock_bh(&bdi->wb_lock); |
470 | wake_up_process(task); | 490 | wake_up_process(task); |
471 | } | 491 | } |
492 | bdi_clear_pending(bdi); | ||
472 | break; | 493 | break; |
473 | 494 | ||
474 | case KILL_THREAD: | 495 | case KILL_THREAD: |
475 | __set_current_state(TASK_RUNNING); | 496 | __set_current_state(TASK_RUNNING); |
476 | kthread_stop(task); | 497 | kthread_stop(task); |
498 | bdi_clear_pending(bdi); | ||
477 | break; | 499 | break; |
478 | 500 | ||
479 | case NO_ACTION: | 501 | case NO_ACTION: |
@@ -489,16 +511,8 @@ static int bdi_forker_thread(void *ptr) | |||
489 | else | 511 | else |
490 | schedule_timeout(msecs_to_jiffies(dirty_writeback_interval * 10)); | 512 | schedule_timeout(msecs_to_jiffies(dirty_writeback_interval * 10)); |
491 | try_to_freeze(); | 513 | try_to_freeze(); |
492 | /* Back to the main loop */ | 514 | break; |
493 | continue; | ||
494 | } | 515 | } |
495 | |||
496 | /* | ||
497 | * Clear pending bit and wakeup anybody waiting to tear us down. | ||
498 | */ | ||
499 | clear_bit(BDI_pending, &bdi->state); | ||
500 | smp_mb__after_clear_bit(); | ||
501 | wake_up_bit(&bdi->state, BDI_pending); | ||
502 | } | 516 | } |
503 | 517 | ||
504 | return 0; | 518 | return 0; |
@@ -672,6 +686,8 @@ int bdi_init(struct backing_dev_info *bdi) | |||
672 | bdi->bw_time_stamp = jiffies; | 686 | bdi->bw_time_stamp = jiffies; |
673 | bdi->written_stamp = 0; | 687 | bdi->written_stamp = 0; |
674 | 688 | ||
689 | bdi->balanced_dirty_ratelimit = INIT_BW; | ||
690 | bdi->dirty_ratelimit = INIT_BW; | ||
675 | bdi->write_bandwidth = INIT_BW; | 691 | bdi->write_bandwidth = INIT_BW; |
676 | bdi->avg_write_bandwidth = INIT_BW; | 692 | bdi->avg_write_bandwidth = INIT_BW; |
677 | 693 | ||
@@ -708,6 +724,14 @@ void bdi_destroy(struct backing_dev_info *bdi) | |||
708 | 724 | ||
709 | bdi_unregister(bdi); | 725 | bdi_unregister(bdi); |
710 | 726 | ||
727 | /* | ||
728 | * If bdi_unregister() had already been called earlier, the | ||
729 | * wakeup_timer could still be armed because bdi_prune_sb() | ||
730 | * can race with the bdi_wakeup_thread_delayed() calls from | ||
731 | * __mark_inode_dirty(). | ||
732 | */ | ||
733 | del_timer_sync(&bdi->wb.wakeup_timer); | ||
734 | |||
711 | for (i = 0; i < NR_BDI_STAT_ITEMS; i++) | 735 | for (i = 0; i < NR_BDI_STAT_ITEMS; i++) |
712 | percpu_counter_destroy(&bdi->bdi_stat[i]); | 736 | percpu_counter_destroy(&bdi->bdi_stat[i]); |
713 | 737 | ||