diff options
-rw-r--r-- | fs/fs-writeback.c | 54 | ||||
-rw-r--r-- | mm/backing-dev.c | 69 |
2 files changed, 70 insertions, 53 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 9f5cab75c157..905f3ea38488 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -78,21 +78,17 @@ static void bdi_queue_work(struct backing_dev_info *bdi, | |||
78 | 78 | ||
79 | spin_lock(&bdi->wb_lock); | 79 | spin_lock(&bdi->wb_lock); |
80 | list_add_tail(&work->list, &bdi->work_list); | 80 | list_add_tail(&work->list, &bdi->work_list); |
81 | spin_unlock(&bdi->wb_lock); | 81 | if (bdi->wb.task) { |
82 | 82 | wake_up_process(bdi->wb.task); | |
83 | /* | 83 | } else { |
84 | * If the default thread isn't there, make sure we add it. When | 84 | /* |
85 | * it gets created and wakes up, we'll run this work. | 85 | * The bdi thread isn't there, wake up the forker thread which |
86 | */ | 86 | * will create and run it. |
87 | if (unlikely(!bdi->wb.task)) { | 87 | */ |
88 | trace_writeback_nothread(bdi, work); | 88 | trace_writeback_nothread(bdi, work); |
89 | wake_up_process(default_backing_dev_info.wb.task); | 89 | wake_up_process(default_backing_dev_info.wb.task); |
90 | } else { | ||
91 | struct bdi_writeback *wb = &bdi->wb; | ||
92 | |||
93 | if (wb->task) | ||
94 | wake_up_process(wb->task); | ||
95 | } | 90 | } |
91 | spin_unlock(&bdi->wb_lock); | ||
96 | } | 92 | } |
97 | 93 | ||
98 | static void | 94 | static void |
@@ -800,7 +796,6 @@ int bdi_writeback_thread(void *data) | |||
800 | { | 796 | { |
801 | struct bdi_writeback *wb = data; | 797 | struct bdi_writeback *wb = data; |
802 | struct backing_dev_info *bdi = wb->bdi; | 798 | struct backing_dev_info *bdi = wb->bdi; |
803 | unsigned long wait_jiffies = -1UL; | ||
804 | long pages_written; | 799 | long pages_written; |
805 | 800 | ||
806 | current->flags |= PF_FLUSHER | PF_SWAPWRITE; | 801 | current->flags |= PF_FLUSHER | PF_SWAPWRITE; |
@@ -812,13 +807,6 @@ int bdi_writeback_thread(void *data) | |||
812 | */ | 807 | */ |
813 | set_user_nice(current, 0); | 808 | set_user_nice(current, 0); |
814 | 809 | ||
815 | /* | ||
816 | * Clear pending bit and wakeup anybody waiting to tear us down | ||
817 | */ | ||
818 | clear_bit(BDI_pending, &bdi->state); | ||
819 | smp_mb__after_clear_bit(); | ||
820 | wake_up_bit(&bdi->state, BDI_pending); | ||
821 | |||
822 | trace_writeback_thread_start(bdi); | 810 | trace_writeback_thread_start(bdi); |
823 | 811 | ||
824 | while (!kthread_should_stop()) { | 812 | while (!kthread_should_stop()) { |
@@ -828,18 +816,6 @@ int bdi_writeback_thread(void *data) | |||
828 | 816 | ||
829 | if (pages_written) | 817 | if (pages_written) |
830 | wb->last_active = jiffies; | 818 | wb->last_active = jiffies; |
831 | else if (wait_jiffies != -1UL) { | ||
832 | unsigned long max_idle; | ||
833 | |||
834 | /* | ||
835 | * Longest period of inactivity that we tolerate. If we | ||
836 | * see dirty data again later, the thread will get | ||
837 | * recreated automatically. | ||
838 | */ | ||
839 | max_idle = max(5UL * 60 * HZ, wait_jiffies); | ||
840 | if (time_after(jiffies, max_idle + wb->last_active)) | ||
841 | break; | ||
842 | } | ||
843 | 819 | ||
844 | set_current_state(TASK_INTERRUPTIBLE); | 820 | set_current_state(TASK_INTERRUPTIBLE); |
845 | if (!list_empty(&bdi->work_list)) { | 821 | if (!list_empty(&bdi->work_list)) { |
@@ -847,21 +823,15 @@ int bdi_writeback_thread(void *data) | |||
847 | continue; | 823 | continue; |
848 | } | 824 | } |
849 | 825 | ||
850 | if (dirty_writeback_interval) { | 826 | if (dirty_writeback_interval) |
851 | wait_jiffies = msecs_to_jiffies(dirty_writeback_interval * 10); | 827 | schedule_timeout(msecs_to_jiffies(dirty_writeback_interval * 10)); |
852 | schedule_timeout(wait_jiffies); | 828 | else |
853 | } else | ||
854 | schedule(); | 829 | schedule(); |
855 | 830 | ||
856 | try_to_freeze(); | 831 | try_to_freeze(); |
857 | } | 832 | } |
858 | 833 | ||
859 | wb->task = NULL; | 834 | /* Flush any work that raced with us exiting */ |
860 | |||
861 | /* | ||
862 | * Flush any work that raced with us exiting. No new work | ||
863 | * will be added, since this bdi isn't discoverable anymore. | ||
864 | */ | ||
865 | if (!list_empty(&bdi->work_list)) | 835 | if (!list_empty(&bdi->work_list)) |
866 | wb_do_writeback(wb, 1); | 836 | wb_do_writeback(wb, 1); |
867 | 837 | ||
diff --git a/mm/backing-dev.c b/mm/backing-dev.c index e104e32c2ee8..9c1c199f88ce 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c | |||
@@ -316,6 +316,18 @@ static void sync_supers_timer_fn(unsigned long unused) | |||
316 | bdi_arm_supers_timer(); | 316 | bdi_arm_supers_timer(); |
317 | } | 317 | } |
318 | 318 | ||
319 | /* | ||
320 | * Calculate the longest interval (jiffies) bdi threads are allowed to be | ||
321 | * inactive. | ||
322 | */ | ||
323 | static unsigned long bdi_longest_inactive(void) | ||
324 | { | ||
325 | unsigned long interval; | ||
326 | |||
327 | interval = msecs_to_jiffies(dirty_writeback_interval * 10); | ||
328 | return max(5UL * 60 * HZ, interval); | ||
329 | } | ||
330 | |||
319 | static int bdi_forker_thread(void *ptr) | 331 | static int bdi_forker_thread(void *ptr) |
320 | { | 332 | { |
321 | struct bdi_writeback *me = ptr; | 333 | struct bdi_writeback *me = ptr; |
@@ -329,11 +341,12 @@ static int bdi_forker_thread(void *ptr) | |||
329 | set_user_nice(current, 0); | 341 | set_user_nice(current, 0); |
330 | 342 | ||
331 | for (;;) { | 343 | for (;;) { |
332 | struct task_struct *task; | 344 | struct task_struct *task = NULL; |
333 | struct backing_dev_info *bdi; | 345 | struct backing_dev_info *bdi; |
334 | enum { | 346 | enum { |
335 | NO_ACTION, /* Nothing to do */ | 347 | NO_ACTION, /* Nothing to do */ |
336 | FORK_THREAD, /* Fork bdi thread */ | 348 | FORK_THREAD, /* Fork bdi thread */ |
349 | KILL_THREAD, /* Kill inactive bdi thread */ | ||
337 | } action = NO_ACTION; | 350 | } action = NO_ACTION; |
338 | 351 | ||
339 | /* | 352 | /* |
@@ -346,10 +359,6 @@ static int bdi_forker_thread(void *ptr) | |||
346 | spin_lock_bh(&bdi_lock); | 359 | spin_lock_bh(&bdi_lock); |
347 | set_current_state(TASK_INTERRUPTIBLE); | 360 | set_current_state(TASK_INTERRUPTIBLE); |
348 | 361 | ||
349 | /* | ||
350 | * Check if any existing bdi's have dirty data without | ||
351 | * a thread registered. If so, set that up. | ||
352 | */ | ||
353 | list_for_each_entry(bdi, &bdi_list, bdi_list) { | 362 | list_for_each_entry(bdi, &bdi_list, bdi_list) { |
354 | bool have_dirty_io; | 363 | bool have_dirty_io; |
355 | 364 | ||
@@ -376,6 +385,25 @@ static int bdi_forker_thread(void *ptr) | |||
376 | action = FORK_THREAD; | 385 | action = FORK_THREAD; |
377 | break; | 386 | break; |
378 | } | 387 | } |
388 | |||
389 | spin_lock(&bdi->wb_lock); | ||
390 | /* | ||
391 | * If there is no work to do and the bdi thread was | ||
392 | * inactive long enough - kill it. The wb_lock is taken | ||
393 | * to make sure no-one adds more work to this bdi and | ||
394 | * wakes the bdi thread up. | ||
395 | */ | ||
396 | if (bdi->wb.task && !have_dirty_io && | ||
397 | time_after(jiffies, bdi->wb.last_active + | ||
398 | bdi_longest_inactive())) { | ||
399 | task = bdi->wb.task; | ||
400 | bdi->wb.task = NULL; | ||
401 | spin_unlock(&bdi->wb_lock); | ||
402 | set_bit(BDI_pending, &bdi->state); | ||
403 | action = KILL_THREAD; | ||
404 | break; | ||
405 | } | ||
406 | spin_unlock(&bdi->wb_lock); | ||
379 | } | 407 | } |
380 | spin_unlock_bh(&bdi_lock); | 408 | spin_unlock_bh(&bdi_lock); |
381 | 409 | ||
@@ -394,8 +422,20 @@ static int bdi_forker_thread(void *ptr) | |||
394 | * the bdi from the thread. | 422 | * the bdi from the thread. |
395 | */ | 423 | */ |
396 | bdi_flush_io(bdi); | 424 | bdi_flush_io(bdi); |
397 | } else | 425 | } else { |
426 | /* | ||
427 | * The spinlock makes sure we do not lose | ||
428 | * wake-ups when racing with 'bdi_queue_work()'. | ||
429 | */ | ||
430 | spin_lock(&bdi->wb_lock); | ||
398 | bdi->wb.task = task; | 431 | bdi->wb.task = task; |
432 | spin_unlock(&bdi->wb_lock); | ||
433 | } | ||
434 | break; | ||
435 | |||
436 | case KILL_THREAD: | ||
437 | __set_current_state(TASK_RUNNING); | ||
438 | kthread_stop(task); | ||
399 | break; | 439 | break; |
400 | 440 | ||
401 | case NO_ACTION: | 441 | case NO_ACTION: |
@@ -407,6 +447,13 @@ static int bdi_forker_thread(void *ptr) | |||
407 | /* Back to the main loop */ | 447 | /* Back to the main loop */ |
408 | continue; | 448 | continue; |
409 | } | 449 | } |
450 | |||
451 | /* | ||
452 | * Clear pending bit and wakeup anybody waiting to tear us down. | ||
453 | */ | ||
454 | clear_bit(BDI_pending, &bdi->state); | ||
455 | smp_mb__after_clear_bit(); | ||
456 | wake_up_bit(&bdi->state, BDI_pending); | ||
410 | } | 457 | } |
411 | 458 | ||
412 | return 0; | 459 | return 0; |
@@ -490,15 +537,15 @@ static void bdi_wb_shutdown(struct backing_dev_info *bdi) | |||
490 | return; | 537 | return; |
491 | 538 | ||
492 | /* | 539 | /* |
493 | * If setup is pending, wait for that to complete first | 540 | * Make sure nobody finds us on the bdi_list anymore |
494 | */ | 541 | */ |
495 | wait_on_bit(&bdi->state, BDI_pending, bdi_sched_wait, | 542 | bdi_remove_from_list(bdi); |
496 | TASK_UNINTERRUPTIBLE); | ||
497 | 543 | ||
498 | /* | 544 | /* |
499 | * Make sure nobody finds us on the bdi_list anymore | 545 | * If setup is pending, wait for that to complete first |
500 | */ | 546 | */ |
501 | bdi_remove_from_list(bdi); | 547 | wait_on_bit(&bdi->state, BDI_pending, bdi_sched_wait, |
548 | TASK_UNINTERRUPTIBLE); | ||
502 | 549 | ||
503 | /* | 550 | /* |
504 | * Finally, kill the kernel thread. We don't need to be RCU | 551 | * Finally, kill the kernel thread. We don't need to be RCU |