summaryrefslogtreecommitdiff
path: root/mm
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2014-05-14 18:11:24 (GMT)
committerScott Wood <scottwood@freescale.com>2014-05-14 18:12:24 (GMT)
commitffb069a30665ec06c05916355bc3252e33fc863b (patch)
treeba7b82696000c0f2983672d22966b83112da874e /mm
parent8d5cd1658cb0c97d5429124f9fb5caa88c460186 (diff)
parent3756888c2a2da9c7291d39cacd1184171111b49d (diff)
downloadlinux-fsl-qoriq-ffb069a30665ec06c05916355bc3252e33fc863b.tar.xz
Merge remote-tracking branch 'stable/linux-3.12.y' into sdk-v1.6.x
Signed-off-by: Scott Wood <scottwood@freescale.com> Conflicts: arch/sparc/Kconfig drivers/tty/tty_buffer.c
Diffstat (limited to 'mm')
-rw-r--r--mm/backing-dev.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index ce682f7..09d9591 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -288,13 +288,19 @@ int bdi_has_dirty_io(struct backing_dev_info *bdi)
* Note, we wouldn't bother setting up the timer, but this function is on the
* fast-path (used by '__mark_inode_dirty()'), so we save few context switches
* by delaying the wake-up.
+ *
+ * We have to be careful not to postpone flush work if it is scheduled for
+ * earlier. Thus we use queue_delayed_work().
*/
void bdi_wakeup_thread_delayed(struct backing_dev_info *bdi)
{
unsigned long timeout;
timeout = msecs_to_jiffies(dirty_writeback_interval * 10);
- mod_delayed_work(bdi_wq, &bdi->wb.dwork, timeout);
+ spin_lock_bh(&bdi->wb_lock);
+ if (test_bit(BDI_registered, &bdi->state))
+ queue_delayed_work(bdi_wq, &bdi->wb.dwork, timeout);
+ spin_unlock_bh(&bdi->wb_lock);
}
/*
@@ -307,9 +313,6 @@ static void bdi_remove_from_list(struct backing_dev_info *bdi)
spin_unlock_bh(&bdi_lock);
synchronize_rcu_expedited();
-
- /* bdi_list is now unused, clear it to mark @bdi dying */
- INIT_LIST_HEAD(&bdi->bdi_list);
}
int bdi_register(struct backing_dev_info *bdi, struct device *parent,
@@ -360,6 +363,11 @@ static void bdi_wb_shutdown(struct backing_dev_info *bdi)
*/
bdi_remove_from_list(bdi);
+ /* Make sure nobody queues further work */
+ spin_lock_bh(&bdi->wb_lock);
+ clear_bit(BDI_registered, &bdi->state);
+ spin_unlock_bh(&bdi->wb_lock);
+
/*
* Drain work list and shutdown the delayed_work. At this point,
* @bdi->bdi_list is empty telling bdi_Writeback_workfn() that @bdi