Peter, This is an amazing bug. I'm not sure how the accounting goes wrong in some tricky way. But you can compare the exact bdi proportions pattern before/after patch. The gray "bdi setpoint" lines are vastly different. --- When increasing BDI_WRITTEN together with bdi->completions inside the same local irq disabling block, bdi_thresh is found to go wild in the 1 disk + 1 usb stick writeback test case. Fix it by moving BDI_WRITTEN accounting out. Signed-off-by: Wu Fengguang --- mm/page-writeback.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) --- linux.orig/mm/page-writeback.c 2011-09-01 21:43:45.312000020 +0800 +++ linux/mm/page-writeback.c 2011-09-01 21:46:10.656000006 +0800 @@ -230,7 +230,6 @@ int dirty_bytes_handler(struct ctl_table */ static inline void __bdi_writeout_inc(struct backing_dev_info *bdi) { - __inc_bdi_stat(bdi, BDI_WRITTEN); __prop_inc_percpu_max(&vm_completions, &bdi->completions, bdi->max_prop_frac); } @@ -239,6 +238,7 @@ void bdi_writeout_inc(struct backing_dev { unsigned long flags; + inc_bdi_stat(bdi, BDI_WRITTEN); local_irq_save(flags); __bdi_writeout_inc(bdi); local_irq_restore(flags); @@ -1577,6 +1577,7 @@ int test_clear_page_writeback(struct pag PAGECACHE_TAG_WRITEBACK); if (bdi_cap_account_writeback(bdi)) { __dec_bdi_stat(bdi, BDI_WRITEBACK); + __inc_bdi_stat(bdi, BDI_WRITTEN); __bdi_writeout_inc(bdi); } }