[PATCH v1 0/2] writeback: bound foreign dirty flushing

From: Xin Yin

Date: Mon Sep 07 2026 - 23:25:06 EST


Hi,

We have seen production stalls where syncfs() and other writeback waiters
are blocked behind long-running WB_REASON_FOREIGN_FLUSH work on the same
bdi_writeback. The foreign work is best-effort writeback for memcg
foreign dirtying, but on busy multi-device systems it can be much larger
or longer-lived than the dirty pages that are actually relevant to the
selected target wb.

There are two parts to the problem. First, the foreign flush budget is
currently sized from the target memcg's global dirty counter, while the
queued work writes only one target wb. This can over-size a single-bdi
flush when the target memcg has dirty pages on other devices, or under-size
it when dirty pages on the target wb are charged to other memcgs.

Second, the work can keep extending itself under sustained dirtying. Even
though foreign flushes are best-effort WB_SYNC_NONE work, a large budget
plus continued dirtying can keep the target wb busy long enough to delay
later writeback work, including syncfs() on the same backing device.

This series keeps foreign flushing aligned with its best-effort reclaim
role:

1. size the work from the selected wb's reclaimable pages, with the
existing 25% headroom;
2. make each foreign flush operate on a bounded snapshot of dirty
inodes/pages, while preserving WB_SYNC_NONE semantics and the finite
work budget.

Later dirtying remains the responsibility of later foreign flushes, kupdate,
or background writeback. The changes are intended to bound one
foreign-flush work item without turning it into a data-integrity operation.

Xin Yin (2):
writeback: size foreign flushes by target wb dirty pages
writeback: snapshot foreign flush pages

fs/fs-writeback.c | 74 +++++++++++++++++++++++++++------------
include/linux/writeback.h | 1 +
2 files changed, 52 insertions(+), 23 deletions(-)


base-commit: 46b513250491a7bfc97d98791dbe6a10bcc8129d
--
2.20.1