From: Tejun Heo <tj@kernel.org>
To: Julian Sun <sunjunchao@bytedance.com>
Cc: linux-block@vger.kernel.org, cgroups@vger.kernel.org,
linux-mm@kvack.org, linux-fsdevel@vger.kernel.org,
axboe@kernel.dk, hannes@cmpxchg.org, mhocko@kernel.org,
roman.gushchin@linux.dev, shakeel.butt@linux.dev,
muchun.song@linux.dev, willy@infradead.org, jack@suse.cz,
tj@kernel.org, akpm@linux-foundation.org
Subject: Re: [PATCH v6 2/3] memcg,writeback: flush foreign bdev mappings separately from owner wbs
Date: Sun, 20 Sep 2026 02:37:56 -1000 [thread overview]
Message-ID: <73204ebd8b41871c263e99196ee7fbf1@kernel.org> (raw)
In-Reply-To: <20260917070119.2648123-1-sunjunchao@bytedance.com>
Hello, Julian.
On Thu, Sep 17, 2026 at 03:01:18PM +0800, Julian Sun wrote:
> Bdev foreign flushes can be triggered frequently. Use a dedicated
> workqueue to avoid interfering with tasks on existing workqueues. If
> allocation fails, retain the existing foreign-wb path.
Work items on an unbound workqueue don't interfere with each other beyond
max_active, so this isn't a reason for a dedicated workqueue. Wanting a
separate max_active pool for up to four long-blocking items per memcg is,
if that's the intent. Can you update the rationale?
> Use fixed per-memcg slots, with a shared lock protecting device records
> and in-flight state. Tracking is best effort: record only dev_t without
> holding device or inode references. Skip closed devices or devices whose
> open_mutex is busy. Device removal and device-number reuse may race with
> lookup.
Andrew asked why dev_t rather than a reference. The reasons you gave in the
thread belong here: the record is written under i_pages with IRQs off,
dropping a bdev reference can sleep, and a memcg that never throttles would
pin the device indefinitely.
It'd also help to say who this affects. Only filesystems that keep metadata
in the bdev page cache, so ext4 and the other buffer_head users but not
xfs, btrfs or f2fs. And that the decision is still blind to how much of the
memcg's dirty memory is actually in the bdev, so one dirty bitmap block
still flushes the whole mapping each time the memcg throttles.
> Fixes: 97b27821b485 ("writeback, memcg: Implement foreign dirty flushing")
This is new development rather than a fix. Maybe drop the tag? Patch 1
doesn't carry one, so a stable pick of this patch alone wouldn't build
anyway.
> +static void mem_cgroup_track_foreign_bdev(struct mem_cgroup *memcg, dev_t dev)
This lands above the "Foreign dirty flushing" overview, which now says
nothing about the bdev path. Can you move it below the overview and add a
sentence there?
> + /*
> + * Tracking is best effort, so losing hints when all slots are occupied
> + * is expected.
> + */
> + for (i = 0; i < MEMCG_CGWB_FRN_CNT; i++) {
> + ctx = &memcg->bdev_frn[i];
> + if (ctx->inflight)
> + continue;
> + if (slot < 0)
> + slot = i;
> + if (!ctx->dev) {
> + slot = i;
> + break;
> + }
> + }
When all four are occupied this always evicts slot 0, and the comment says
the new hint is dropped, which isn't what happens.
Why not follow the cgwb_frn style? A timestamp per slot gives oldest-first
replacement here, expiry in mem_cgroup_flush_foreign() so a record from
long ago doesn't fire a flush when the memcg finally throttles, and
re-arming when the mapping is dirtied while a flush is in flight, which the
worker currently forgets when it clears the slot. It could also drop
frn_lock. An atomic in-flight flag on the work gives the same guarantee
done.cnt does, and a torn read of dev or the stamp only costs a wrong
best-effort flush, which is already the deal.
> + if (memcg_bdev_frn_wq && bdev_inode &&
> + sb_is_blkdev_sb(bdev_inode->i_sb)) {
> + mem_cgroup_track_foreign_bdev(memcg, bdev_inode->i_rdev);
> + return;
> + }
Patch 3 moves the trace call below this. Might as well put it there here.
> + for (i = 0; i < MEMCG_CGWB_FRN_CNT; i++) {
> + struct bdev_frn_flush_ctx *ctx = &memcg->bdev_frn[i];
> + unsigned long flags;
> +
> + spin_lock_irqsave(&memcg->frn_lock, flags);
> + if (!ctx->inflight && ctx->dev) {
> + ctx->inflight = true;
> + queue_work(memcg_bdev_frn_wq, &ctx->work);
> + }
> + spin_unlock_irqrestore(&memcg->frn_lock, flags);
> + }
If the lock stays, one acquisition around the loop is enough.
> +#ifdef CONFIG_CGROUP_WRITEBACK
> + memcg_bdev_frn_wq = alloc_workqueue("memcg_bdev_frn_flusher",
> + WQ_UNBOUND | WQ_MEM_RECLAIM, 0);
> + WARN_ON(!memcg_bdev_frn_wq);
> +#endif
WQ_MEM_RECLAIM is for work items that memory reclaim depends on to make
forward progress. Nothing waits on these flushes. The throttled task just
sleeps and re-evaluates, and the bdi flusher remains the path that's
guaranteed to make progress. Can you drop the flag?
Thanks.
--
tejun
next prev parent reply other threads:[~2026-09-20 12:38 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-17 6:57 [PATCH v6 0/3] memcg,writeback: flush foreign bdev mappings separately Julian Sun
2026-09-17 6:57 ` [PATCH v6 1/3] block: introduce bdev_flush_by_dev() Julian Sun
2026-09-20 12:37 ` Tejun Heo
2026-09-17 7:01 ` [PATCH v6 2/3] memcg,writeback: flush foreign bdev mappings separately from owner wbs Julian Sun
2026-09-20 12:37 ` Tejun Heo [this message]
2026-09-17 7:01 ` [PATCH v6 3/3] writeback: record bdev targets in foreign writeback tracepoints Julian Sun
2026-09-17 22:53 ` [PATCH v6 0/3] memcg,writeback: flush foreign bdev mappings separately Andrew Morton
2026-09-18 4:57 ` Julian Sun
2026-09-18 5:12 ` Andrew Morton
2026-09-21 11:55 ` [PATCH v7 " Julian Sun
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=73204ebd8b41871c263e99196ee7fbf1@kernel.org \
--to=tj@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=axboe@kernel.dk \
--cc=cgroups@vger.kernel.org \
--cc=hannes@cmpxchg.org \
--cc=jack@suse.cz \
--cc=linux-block@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mhocko@kernel.org \
--cc=muchun.song@linux.dev \
--cc=roman.gushchin@linux.dev \
--cc=shakeel.butt@linux.dev \
--cc=sunjunchao@bytedance.com \
--cc=willy@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox