|
@@ -359,6 +359,17 @@ static unsigned long bdi_longest_inactive(void)
|
|
|
return max(5UL * 60 * HZ, interval);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Clear pending bit and wakeup anybody waiting for flusher thread creation or
|
|
|
+ * shutdown
|
|
|
+ */
|
|
|
+static void bdi_clear_pending(struct backing_dev_info *bdi)
|
|
|
+{
|
|
|
+ clear_bit(BDI_pending, &bdi->state);
|
|
|
+ smp_mb__after_clear_bit();
|
|
|
+ wake_up_bit(&bdi->state, BDI_pending);
|
|
|
+}
|
|
|
+
|
|
|
static int bdi_forker_thread(void *ptr)
|
|
|
{
|
|
|
struct bdi_writeback *me = ptr;
|
|
@@ -469,11 +480,13 @@ static int bdi_forker_thread(void *ptr)
|
|
|
spin_unlock_bh(&bdi->wb_lock);
|
|
|
wake_up_process(task);
|
|
|
}
|
|
|
+ bdi_clear_pending(bdi);
|
|
|
break;
|
|
|
|
|
|
case KILL_THREAD:
|
|
|
__set_current_state(TASK_RUNNING);
|
|
|
kthread_stop(task);
|
|
|
+ bdi_clear_pending(bdi);
|
|
|
break;
|
|
|
|
|
|
case NO_ACTION:
|
|
@@ -489,16 +502,8 @@ static int bdi_forker_thread(void *ptr)
|
|
|
else
|
|
|
schedule_timeout(msecs_to_jiffies(dirty_writeback_interval * 10));
|
|
|
try_to_freeze();
|
|
|
- /* Back to the main loop */
|
|
|
- continue;
|
|
|
+ break;
|
|
|
}
|
|
|
-
|
|
|
- /*
|
|
|
- * Clear pending bit and wakeup anybody waiting to tear us down.
|
|
|
- */
|
|
|
- clear_bit(BDI_pending, &bdi->state);
|
|
|
- smp_mb__after_clear_bit();
|
|
|
- wake_up_bit(&bdi->state, BDI_pending);
|
|
|
}
|
|
|
|
|
|
return 0;
|