Skip to content

Commit

Permalink
writeback: track number of inodes under writeback
Browse files Browse the repository at this point in the history
Patch series "writeback: Fix bandwidth estimates", v4.

Fix estimate of writeback throughput when device is not fully busy doing
writeback.  Michael Stapelberg has reported that such workload (e.g.
generated by linking) tends to push estimated throughput down to 0 and as
a result writeback on the device is practically stalled.

The first three patches fix the reported issue, the remaining two patches
are unrelated cleanups of problems I've noticed when reading the code.

This patch (of 4):

Track number of inodes under writeback for each bdi_writeback structure.
We will use this to decide whether wb does any IO and so we can estimate
its writeback throughput.  In principle we could use number of pages under
writeback (WB_WRITEBACK counter) for this however normal percpu counter
reads are too inaccurate for our purposes and summing the counter is too
expensive.

Link: https://lkml.kernel.org/r/[email protected]
Link: https://lkml.kernel.org/r/[email protected]
Signed-off-by: Jan Kara <[email protected]>
Cc: Wu Fengguang <[email protected]>
Cc: Michael Stapelberg <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
jankara authored and torvalds committed Sep 3, 2021
1 parent eb2169c commit 633a2ab
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 2 deletions.
5 changes: 5 additions & 0 deletions fs/fs-writeback.c
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,11 @@ static bool inode_do_switch_wbs(struct inode *inode,
inc_wb_stat(new_wb, WB_WRITEBACK);
}

if (mapping_tagged(mapping, PAGECACHE_TAG_WRITEBACK)) {
atomic_dec(&old_wb->writeback_inodes);
atomic_inc(&new_wb->writeback_inodes);
}

wb_get(new_wb);

/*
Expand Down
1 change: 1 addition & 0 deletions include/linux/backing-dev-defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ struct bdi_writeback {
struct list_head b_dirty_time; /* time stamps are dirty */
spinlock_t list_lock; /* protects the b_* lists */

atomic_t writeback_inodes; /* number of inodes under writeback */
struct percpu_counter stat[NR_WB_STAT_ITEMS];

unsigned long congested; /* WB_[a]sync_congested flags */
Expand Down
1 change: 1 addition & 0 deletions mm/backing-dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ static int wb_init(struct bdi_writeback *wb, struct backing_dev_info *bdi,
INIT_LIST_HEAD(&wb->b_dirty_time);
spin_lock_init(&wb->list_lock);

atomic_set(&wb->writeback_inodes, 0);
wb->bw_time_stamp = jiffies;
wb->balanced_dirty_ratelimit = INIT_BW;
wb->dirty_ratelimit = INIT_BW;
Expand Down
22 changes: 20 additions & 2 deletions mm/page-writeback.c
Original file line number Diff line number Diff line change
Expand Up @@ -2731,6 +2731,16 @@ int clear_page_dirty_for_io(struct page *page)
}
EXPORT_SYMBOL(clear_page_dirty_for_io);

static void wb_inode_writeback_start(struct bdi_writeback *wb)
{
atomic_inc(&wb->writeback_inodes);
}

static void wb_inode_writeback_end(struct bdi_writeback *wb)
{
atomic_dec(&wb->writeback_inodes);
}

int test_clear_page_writeback(struct page *page)
{
struct address_space *mapping = page_mapping(page);
Expand All @@ -2752,6 +2762,9 @@ int test_clear_page_writeback(struct page *page)

dec_wb_stat(wb, WB_WRITEBACK);
__wb_writeout_inc(wb);
if (!mapping_tagged(mapping,
PAGECACHE_TAG_WRITEBACK))
wb_inode_writeback_end(wb);
}
}

Expand Down Expand Up @@ -2794,8 +2807,13 @@ int __test_set_page_writeback(struct page *page, bool keep_write)
PAGECACHE_TAG_WRITEBACK);

xas_set_mark(&xas, PAGECACHE_TAG_WRITEBACK);
if (bdi->capabilities & BDI_CAP_WRITEBACK_ACCT)
inc_wb_stat(inode_to_wb(inode), WB_WRITEBACK);
if (bdi->capabilities & BDI_CAP_WRITEBACK_ACCT) {
struct bdi_writeback *wb = inode_to_wb(inode);

inc_wb_stat(wb, WB_WRITEBACK);
if (!on_wblist)
wb_inode_writeback_start(wb);
}

/*
* We can come through here when swapping anonymous
Expand Down

0 comments on commit 633a2ab

Please sign in to comment.