|
@@ -89,16 +89,29 @@ static inline struct inode *wb_inode(struct list_head *head)
|
|
|
#define CREATE_TRACE_POINTS
|
|
|
#include <trace/events/writeback.h>
|
|
|
|
|
|
+static void bdi_wakeup_thread(struct backing_dev_info *bdi)
|
|
|
+{
|
|
|
+ spin_lock_bh(&bdi->wb_lock);
|
|
|
+ if (test_bit(BDI_registered, &bdi->state))
|
|
|
+ mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0);
|
|
|
+ spin_unlock_bh(&bdi->wb_lock);
|
|
|
+}
|
|
|
+
|
|
|
static void bdi_queue_work(struct backing_dev_info *bdi,
|
|
|
struct wb_writeback_work *work)
|
|
|
{
|
|
|
trace_writeback_queue(bdi, work);
|
|
|
|
|
|
spin_lock_bh(&bdi->wb_lock);
|
|
|
+ if (!test_bit(BDI_registered, &bdi->state)) {
|
|
|
+ if (work->done)
|
|
|
+ complete(work->done);
|
|
|
+ goto out_unlock;
|
|
|
+ }
|
|
|
list_add_tail(&work->list, &bdi->work_list);
|
|
|
- spin_unlock_bh(&bdi->wb_lock);
|
|
|
-
|
|
|
mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0);
|
|
|
+out_unlock:
|
|
|
+ spin_unlock_bh(&bdi->wb_lock);
|
|
|
}
|
|
|
|
|
|
static void
|
|
@@ -114,7 +127,7 @@ __bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages,
|
|
|
work = kzalloc(sizeof(*work), GFP_ATOMIC);
|
|
|
if (!work) {
|
|
|
trace_writeback_nowork(bdi);
|
|
|
- mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0);
|
|
|
+ bdi_wakeup_thread(bdi);
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -161,7 +174,7 @@ void bdi_start_background_writeback(struct backing_dev_info *bdi)
|
|
|
* writeback as soon as there is no other work to do.
|
|
|
*/
|
|
|
trace_writeback_wake_background(bdi);
|
|
|
- mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0);
|
|
|
+ bdi_wakeup_thread(bdi);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -1017,7 +1030,7 @@ void bdi_writeback_workfn(struct work_struct *work)
|
|
|
current->flags |= PF_SWAPWRITE;
|
|
|
|
|
|
if (likely(!current_is_workqueue_rescuer() ||
|
|
|
- list_empty(&bdi->bdi_list))) {
|
|
|
+ !test_bit(BDI_registered, &bdi->state))) {
|
|
|
/*
|
|
|
* The normal path. Keep writing back @bdi until its
|
|
|
* work_list is empty. Note that this path is also taken
|