Skip to content

Commit e797291

Browse files
htejunaxboe
authored andcommitted
writeback: don't issue wb_writeback_work if clean
There are several places in fs/fs-writeback.c which queues wb_writeback_work without checking whether the target wb (bdi_writeback) has dirty inodes or not. The only thing wb_writeback_work does is writing back the dirty inodes for the target wb and queueing a work item for a clean wb is essentially noop. There are some side effects such as bandwidth stats being updated and triggering tracepoints but these don't affect the operation in any meaningful way. This patch makes all writeback_inodes_sb_nr() and sync_inodes_sb() skip wb_queue_work() if the target bdi is clean. Also, it moves dirtiness check from wakeup_flusher_threads() to __wb_start_writeback() so that all its callers benefit from the check. While the overhead incurred by scheduling a noop work isn't currently significant, the overhead may be higher with cgroup writeback support as we may end up issuing noop work items to a lot of clean wb's. Signed-off-by: Tejun Heo <[email protected]> Cc: Jens Axboe <[email protected]> Cc: Jan Kara <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 95a46c6 commit e797291

File tree

1 file changed

+10
-8
lines changed

1 file changed

+10
-8
lines changed

fs/fs-writeback.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,9 @@ static void __wb_start_writeback(struct bdi_writeback *wb, long nr_pages,
189189
{
190190
struct wb_writeback_work *work;
191191

192+
if (!wb_has_dirty_io(wb))
193+
return;
194+
192195
/*
193196
* This is WB_SYNC_NONE writeback, so if allocation fails just
194197
* wakeup the thread for old dirty data writeback
@@ -1215,11 +1218,8 @@ void wakeup_flusher_threads(long nr_pages, enum wb_reason reason)
12151218
nr_pages = get_nr_dirty_pages();
12161219

12171220
rcu_read_lock();
1218-
list_for_each_entry_rcu(bdi, &bdi_list, bdi_list) {
1219-
if (!bdi_has_dirty_io(bdi))
1220-
continue;
1221+
list_for_each_entry_rcu(bdi, &bdi_list, bdi_list)
12211222
__wb_start_writeback(&bdi->wb, nr_pages, false, reason);
1222-
}
12231223
rcu_read_unlock();
12241224
}
12251225

@@ -1512,11 +1512,12 @@ void writeback_inodes_sb_nr(struct super_block *sb,
15121512
.nr_pages = nr,
15131513
.reason = reason,
15141514
};
1515+
struct backing_dev_info *bdi = sb->s_bdi;
15151516

1516-
if (sb->s_bdi == &noop_backing_dev_info)
1517+
if (!bdi_has_dirty_io(bdi) || bdi == &noop_backing_dev_info)
15171518
return;
15181519
WARN_ON(!rwsem_is_locked(&sb->s_umount));
1519-
wb_queue_work(&sb->s_bdi->wb, &work);
1520+
wb_queue_work(&bdi->wb, &work);
15201521
wait_for_completion(&done);
15211522
}
15221523
EXPORT_SYMBOL(writeback_inodes_sb_nr);
@@ -1594,13 +1595,14 @@ void sync_inodes_sb(struct super_block *sb)
15941595
.reason = WB_REASON_SYNC,
15951596
.for_sync = 1,
15961597
};
1598+
struct backing_dev_info *bdi = sb->s_bdi;
15971599

15981600
/* Nothing to do? */
1599-
if (sb->s_bdi == &noop_backing_dev_info)
1601+
if (!bdi_has_dirty_io(bdi) || bdi == &noop_backing_dev_info)
16001602
return;
16011603
WARN_ON(!rwsem_is_locked(&sb->s_umount));
16021604

1603-
wb_queue_work(&sb->s_bdi->wb, &work);
1605+
wb_queue_work(&bdi->wb, &work);
16041606
wait_for_completion(&done);
16051607

16061608
wait_sb_inodes(sb);

0 commit comments

Comments
 (0)