Linux XFS filesystem development
 help / color / mirror / Atom feed
From: Christoph Hellwig <hch@lst.de>
To: Dave Chinner <dgc@kernel.org>
Cc: Ran Hongyun <ranhongyun1@huawei.com>,
	catherine.hoang@oracle.com, chandan.babu@oracle.com,
	djwong@kernel.org, hch@lst.de, linux-xfs@vger.kernel.org,
	linux-kernel@vger.kernel.org, chengzhihao1@huawei.com,
	yangerkun@huawei.com, yi.zhang@huawei.com,
	Wangyang Guo <wangyang.guo@intel.com>,
	Tim Chen <tim.c.chen@linux.intel.com>,
	Lai Jiangshan <jiangshanlai@gmail.com>,
	Chuck Lever <cel@kernel.org>
Subject: Re: [QUESTION] xfs: Can we remove flush_workqueue from xlog_cil_push_now?
Date: Wed, 2 Sep 2026 09:35:56 +0200	[thread overview]
Message-ID: <20260902073556.GA27223@lst.de> (raw)
In-Reply-To: <apSnC9p0X04cKxDj@dread>

On Mon, Aug 31, 2026 at 07:56:27AM +1000, Dave Chinner wrote:
> > nr_cpus pool_workqueue entries, instead of per-NUMA nodes. On large SMP
> > systems (e.g. 128 CPUs, 4 NUMA nodes), this adds significant overhead.
> > Even after 85f0d8e39aff ("workqueue: Reduce expensive locks for unbound
> > workqueue") reduced lock cost, the per-CPU iteration remains costly.
> > This seems contrary to the original performance intent of the flush.

Adding the authors/reviwers and maintainers relevant to this commit and
Chuck as he has been looking into different unbound workqueue overhead
lately.

> > 
> > Below is a bpftrace test result on a 128-CPU system with 4 NUMA nodes,
> > 16 threads doing sequential writes with fsync per write.
> > 
> > Function                    remove flush          with flush
> >                             per-CPU pwqs     per-CPU      per-NUMA
> > -------------------------  --------------   ----------   -----------
> > xfs_fsync_flush_log          32-256 us      256-1000 us    32-256 us
> > flush_workqueue_prep_pwqs      N/A           2-64 us        2-8 us
> > 
> > With flush_workqueue() removed, xfs_fsync_flush_log latency drops
> > back to the per‑NUMA range (32‑256 us).
> 
> Ok, but how does the IO performance change? Does this result in a
> measurable increase in RWF_OSYNC write throughput? (write + fsync ==
> pwritev2(RWF_OSYNC)).
> 
> However, behavioural changes like this seem like an infrastructure
> regression, and trying to modify callers to hide that regression is
> a bandaid. This affects all UNBOUND workqueues, not just this one,
> and we do not need per-cpu scheduling for workqueues with such low
> work and concurrency counts - there can only be 4 pushs scheduled
> and running concurrently at any time on this work queue. Hence we
> don't even need NUMA queuing - a single global queue would work just
> fine...

Yeah, a lot of the recent workqueue changes had a lot of adverse effects.
We really need to come up with a way to queue work to task context (or a
different task context) that doesn't require reverse engineering "smart"
behavior in the backend.  This has become a never ending whack-a-mole
unfortunately.

Not sure what we can do here, but a simply "just queue things up on a
fixed queue" interface would be really helpful.  Even better with just a
double or even singly linked list as overhead, as the work_struct is
way to big due to the function pointer not even needed in most cases
as typically every item in the queue uses the same one.

[leaving the rest of the context in place for the new readers]


> Hence it seems to me that this overhead problem should be fixed at
> the WQ infra level, not worked around in the caller context...
> 
> > The removal relies on the assumption that flush_workqueue is just a
> > performance optimization, not a correctness requirement. Without it,
> > xlog_cil_force_seq already provides a reliable completion guarantee via
> > xlog_wait(&cil->xc_commit_wait), which blocks until the target sequence
> > has been committed. The caller will eventually observe the completion
> > regardless of whether flush_workqueue was called. In addition, ordering
> > is enforced by xlog_cil_order_write, which ensures all records are
> > written in strict sequence order. Therefore, removing flush_workqueue
> > does not weaken any ordering or completion semantics.
> 
> And wait latency goes up because now there is nothing to expedidite
> the scheduling of the work we are waiting to complete.
> 
> i.e. you might see a drop in CPU time in flush heavy workloads by
> removing it, but the trade off is an increase in wait time variance
> and long tail latencies, especially under light load.
> 
> > If this analysis is correct, the change can be applied broadly to all
> > sync force callers through xlog_cil_push_now(), as they all share the
> > same completion and ordering guarantees provided by the existing CIL
> > infrastructure. The per-CPU iteration overhead would be eliminated on
> > every sync log force without affecting correctness.
> > 
> > But there are several concerns I'd like to confirm:
> > 
> > Is flush_workqueue just about performance, or does it hide any
> > correctness dependency I'm missing?
> 
> It may well hide implicit correctness bugs.
> 
> > Without it, the "if (!ctx->commit_lsn) { goto restart; }" loop in
> > xlog_cil_force_seq may be triggered more often. Is that acceptable,
> > or is it a concern?
> 
> That's additional context switches and latency. i.e. CPU overhead
> that we are trying to avoid...
> 
> > Are there any ordering guarantees provided by flush_workqueue that
> > xc_push_lock + waitqueues don't already provide?
> 
> Removing the flush will change the order in which concurrent push
> pipelines order in the journal. This could change the inherent order
> of checkpoints in the journal, so there could be visible artifacts
> during crash recovery compared to an flushing implementaiton. None
> of that would be a correctness issue, but from an application POV it
> would be like the concurrent fsync operations completing in a
> different order across different kernel versions.
> 
> A lakc of flushing could also simply move the ordering latency
> bottleneck to journal IO completion where checkpoints have to be
> completed in ascending LSN order. Whether that causes a problem or
> not is a complete unknown, but it could increase overall wait times
> as waiting seqeunces always get woken in ascending order, and hence
> everything will wait if a low sequeunce flush submission gets held
> up because the kworker isn't scheduled immediately...
> 
> > I'd appreciate any thoughts on whether this change is safe.
> 
> Probably safe, but there is lots of potential for performance
> regressions by removing it. Better would be to provide a low
> overhead work queue implementation for callers that don't need
> scale-out performance from their unbound workqueues....
> 
> -Dave.
> -- 
> Dave Chinner
> dgc@kernel.org
---end quoted text---

  reply	other threads:[~2026-09-02  7:36 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-27  3:36 [QUESTION] xfs: Can we remove flush_workqueue from xlog_cil_push_now? Ran Hongyun
2026-08-30 21:56 ` Dave Chinner
2026-09-02  7:35   ` Christoph Hellwig [this message]
2026-09-02 14:23     ` Chuck Lever
2026-09-02 16:50       ` Tejun Heo

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=20260902073556.GA27223@lst.de \
    --to=hch@lst.de \
    --cc=catherine.hoang@oracle.com \
    --cc=cel@kernel.org \
    --cc=chandan.babu@oracle.com \
    --cc=chengzhihao1@huawei.com \
    --cc=dgc@kernel.org \
    --cc=djwong@kernel.org \
    --cc=jiangshanlai@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-xfs@vger.kernel.org \
    --cc=ranhongyun1@huawei.com \
    --cc=tim.c.chen@linux.intel.com \
    --cc=wangyang.guo@intel.com \
    --cc=yangerkun@huawei.com \
    --cc=yi.zhang@huawei.com \
    /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