writeback: fix BDI_WRITTEN accounting disturbing bdi->completions
Subsystems (3)
PATCH 1/1 writeback: fix BDI_WRITTEN accounting disturbing bdi->completions
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.
--- mm/page-writeback.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
mm/page-writeback.c +2 -1
@@ -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); } }
Jan Kara
maintainerQuoted 11 lines · Wu Fengguang
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 increasingBDI_WRITTENtogether withbdi->completionsinside the same local irq disabling block,bdi_threshis found to go wild in the 1 disk + 1 usb stick writeback test case. Fix it by movingBDI_WRITTENaccounting out.
I don't understand this - the patch is just NOP. The change intest_clear_page_writeback() does absolutely nothing and the change in bdi_writeout_inc() just changes:
local_irq_save(flags);
__inc_bdi_stat(bdi); __prop_inc_percpu_max(&vm_completions, &bdi->completions,
bdi->max_prop_frac);
local_irq_restore(flags);
to:
local_irq_save(flags);
__inc_bdi_stat(bdi);
local_irq_restore(flags); local_irq_save(flags); __prop_inc_percpu_max(&vm_completions, &bdi->completions,
bdi->max_prop_frac);
local_irq_restore(flags);
So the difference must be in something else...
Honza
Quoted 32 lines
Signed-off-by Wu Fengguang <[email protected]>--- mm/page-writeback.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)mm/page-writeback.c +2
-1@@ -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); } }
Signature · 2 lines
Jan Kara <[email protected]> SUSE Labs, CR
Quoted 30 lines · Jan Kara
Quoted 11 lines · Wu Fengguang
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 increasingBDI_WRITTENtogether withbdi->completionsinside the same local irq disabling block,bdi_threshis found to go wild in the 1 disk + 1 usb stick writeback test case. Fix it by movingBDI_WRITTENaccounting out.I don't understand this - the patch is just NOP. The change in
test_clear_page_writeback()does absolutely nothing and the change inbdi_writeout_inc()just changes:
local_irq_save(flags);
__inc_bdi_stat(bdi); __prop_inc_percpu_max(&vm_completions,&bdi->completions,
bdi->max_prop_frac);
local_irq_restore(flags);to:
local_irq_save(flags);
__inc_bdi_stat(bdi);
local_irq_restore(flags);local_irq_save(flags); __prop_inc_percpu_max(&vm_completions,&bdi->completions,
bdi->max_prop_frac);
local_irq_restore(flags);
Quoted 1 line
So the difference must be in something else...
Yes you are right -- this patch is basically a NOP. I retried without this patch and it's now working fine again. Something mysterious to catch..
Thanks,
Fengguang