* Re: [PATCH] sched: flush plug in schedule_preempt_disabled() to prevent deadlock
From: Peter Zijlstra @ 2026-05-12 12:40 UTC (permalink / raw)
To: Ming Lei
Cc: Jens Axboe, linux-block, linux-kernel, Ingo Molnar, Juri Lelli,
Vincent Guittot, Michael Wu, Xiaosen He
In-Reply-To: <20260512120431.GC1889694@noisy.programming.kicks-ass.net>
On Tue, May 12, 2026 at 02:04:32PM +0200, Peter Zijlstra wrote:
> On Tue, May 12, 2026 at 04:59:39PM +0800, Ming Lei wrote:
> > On preemptible kernels, a deadlock can occur when a task with plugged IO
> > calls schedule_preempt_disabled():
> >
> > schedule_preempt_disabled()
> > sched_preempt_enable_no_resched() // preemption now enabled
> > schedule() // <-- preemption can happen here
> > sched_submit_work()
> > blk_flush_plug()
> >
> > After sched_preempt_enable_no_resched() re-enables preemption, the task
> > can be preempted (e.g., by a higher-priority RT task) before reaching
> > blk_flush_plug() in sched_submit_work(). Since the task's state is
> > already TASK_UNINTERRUPTIBLE (set by the mutex/rwsem slowpath caller),
> > requests in current->plug remain unflushed for an unbounded time.
> >
> > If another task depends on those plugged requests to make progress (e.g.,
> > to release a lock the sleeping task needs), a deadlock results:
> >
> > - Task A (writeback worker): holds plugged IO, preempted before
> > flushing, stuck on run queue behind higher-priority work
> > - Task B: waiting for IO completion from Task A's plug, holds a lock
> > that Task A needs to be woken up
> >
> > Both reported deadlocks involve mutex/rwsem slowpaths, which are the
> > primary callers of schedule_preempt_disabled() with non-running task
> > state.
> >
> > Fix by flushing the plug in schedule_preempt_disabled() while
> > preemption is still disabled. This ensures the plug is empty before the
> > preemption window opens.
>
> How is this different from any path calling schedule()? That would be
> subject to exactly the same issue.
>
> The patch cannot be correct.
Also, is there a reason io_schedule_prepare() has a blk_flush_plug()
call?
io_schedule()
token = io_schedule_prepare()
blk_flush_plug(current->plug, true);
schedule()
if (!task_is_running(tsk))
sched_submit_work()
blk_flush_plug(tsk->plug, true);
Why isn't the one in sched_submit_work() sufficient? This thing either
needs a comment justifying its existence, or get removed.
^ permalink raw reply
* Re: [PATCH] sched: flush plug in schedule_preempt_disabled() to prevent deadlock
From: Peter Zijlstra @ 2026-05-12 12:04 UTC (permalink / raw)
To: Ming Lei
Cc: Jens Axboe, linux-block, linux-kernel, Ingo Molnar, Juri Lelli,
Vincent Guittot, Michael Wu, Xiaosen He
In-Reply-To: <20260512085939.1107372-1-tom.leiming@gmail.com>
On Tue, May 12, 2026 at 04:59:39PM +0800, Ming Lei wrote:
> On preemptible kernels, a deadlock can occur when a task with plugged IO
> calls schedule_preempt_disabled():
>
> schedule_preempt_disabled()
> sched_preempt_enable_no_resched() // preemption now enabled
> schedule() // <-- preemption can happen here
> sched_submit_work()
> blk_flush_plug()
>
> After sched_preempt_enable_no_resched() re-enables preemption, the task
> can be preempted (e.g., by a higher-priority RT task) before reaching
> blk_flush_plug() in sched_submit_work(). Since the task's state is
> already TASK_UNINTERRUPTIBLE (set by the mutex/rwsem slowpath caller),
> requests in current->plug remain unflushed for an unbounded time.
>
> If another task depends on those plugged requests to make progress (e.g.,
> to release a lock the sleeping task needs), a deadlock results:
>
> - Task A (writeback worker): holds plugged IO, preempted before
> flushing, stuck on run queue behind higher-priority work
> - Task B: waiting for IO completion from Task A's plug, holds a lock
> that Task A needs to be woken up
>
> Both reported deadlocks involve mutex/rwsem slowpaths, which are the
> primary callers of schedule_preempt_disabled() with non-running task
> state.
>
> Fix by flushing the plug in schedule_preempt_disabled() while
> preemption is still disabled. This ensures the plug is empty before the
> preemption window opens.
How is this different from any path calling schedule()? That would be
subject to exactly the same issue.
The patch cannot be correct.
^ permalink raw reply
* Re: [PATCH] loop: Fix NULL pointer dereference by synchronizing lo_release and loop_queue_rq
From: Tetsuo Handa @ 2026-05-12 11:46 UTC (permalink / raw)
To: Bart Van Assche
Cc: Jens Axboe, linux-block, LKML, Christoph Hellwig, Damien Le Moal,
Andrew Morton
In-Reply-To: <f720dd8b-4aa3-48e4-a1bb-c0b43eb70f19@I-love.SAKURA.ne.jp>
Commit 99ebc509eef5 ("mm: memcontrol: fix rcu unbalance in get_non_dying_memcg_end()") fixed
RCU imbalance bug, and it seems that so far only trees without that commit is reproducing RCU
imbalance bug.
But since this NULL pointer dereference bug was reproduced in linux-next-20260508 which already
includes that commit, I suspect that some change in the block layer broke protection by RCU
synchronization or flushing of lo->workqueue.
Can you check that there was no commit that might break protection by RCU synchronization or
flushing of lo->workqueue?
On 2026/05/12 2:43, Tetsuo Handa wrote:
> Thank you for responding.
>
> Given it is protected by RCU, this might be yet another manifestation of
> "is trying to release lock (rcu_read_lock) at:" + "but there are no more locks to release!"-type of
> hidden RCU imbalance bugs recently introduced? Andrew, was any progress made for RCU imbalance bugs?
>
> On 2026/04/21 20:05, Tetsuo Handa wrote:
>> Since this problem started after the merge window opened, the culprit commit
>> might be in between commit a028739a4330 ("Merge tag 'block-7.0-20260305' of
>> git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux") and
>> commit 7fe6ac157b7e ("Merge tag 'for-7.1/block-20260411' of
>> git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux").
>> Also, syzbot was not testing changes in linux-next since next-20260403,
>> and found this problem in next-20260413.
>
> On 2026/05/12 0:58, Bart Van Assche wrote:
>> Why SRCU instead of RCU? The loop driver doesn't set BLK_MQ_F_BLOCKING
>> and hence must not sleep inside loop_queue_rq(). Additionally, the block
>> layer already holds an RCU lock around all loop_queue_rq() calls. From
>> block/blk-mq.h:
>>
>> /* run the code block in @dispatch_ops with rcu/srcu read lock held */
>> #define __blk_mq_run_dispatch_ops(q, check_sleep, dispatch_ops) \
>> do { \
>> if ((q)->tag_set->flags & BLK_MQ_F_BLOCKING) { \
>> struct blk_mq_tag_set *__tag_set = (q)->tag_set; \
>> int srcu_idx; \
>> \
>> might_sleep_if(check_sleep); \
>> srcu_idx = srcu_read_lock(__tag_set->srcu); \
>> (dispatch_ops); \
>> srcu_read_unlock(__tag_set->srcu, srcu_idx); \
>> } else { \
>> rcu_read_lock(); \
>> (dispatch_ops); \
>> rcu_read_unlock(); \
>> } \
>> } while (0)
^ permalink raw reply
* Re: [PATCH] lib: free pagelist on error in iov_iter_extract_pages()
From: Dmitry Antipov @ 2026-05-12 11:23 UTC (permalink / raw)
To: Caleb Sander Mateos
Cc: Jens Axboe, Andrew Morton, Christoph Hellwig, linux-block,
linux-fsdevel, lvc-project, Fedor Pchelkin
In-Reply-To: <CADUfDZpC5WOBY4_xvAy6ORtgQsxwFYj3Px81RdN7NKQZBFdJSQ@mail.gmail.com>
On Fri, 2026-05-08 at 11:33 -0700, Caleb Sander Mateos wrote:
> Callers seem to be inconsistent about whether they treat ret < 0
> or ret <= 0 as the error case, which is another argument not to
> handle freeing the pages array inside iov_iter_extract_pages().
Hmm... looking through iov_iter_extract_pages() innards, ret == 0 means something like
"no error but no data for further processing". Using iov_iter_extract_user_pages()
as an example, iov_iter_advance() is not called if pin_user_pages_fast() returns 0
and, since the pages array won't be touched anymore, it may be freed safely.
Dmitry
^ permalink raw reply
* Re: [LSF/MM/BPF RFC PATCH 00/13]
From: Leon Romanovsky @ 2026-05-12 10:34 UTC (permalink / raw)
To: Md Haris Iqbal
Cc: linux-block, linux-rdma, linux-kernel, axboe, bvanassche, hch,
jgg, jinpu.wang
In-Reply-To: <20260505074644.195453-1-haris.iqbal@ionos.com>
On Tue, May 05, 2026 at 09:46:12AM +0200, Md Haris Iqbal wrote:
> Following a conversation with Bart yesterday, I am sending the RMR+BRMR
> code through patch for easier review.
>
> The patches apply over the for-next branch of the block tree over commit
> 07dfa981ca3
>
> For context,
> RMR (Reliable Multicast over RTRS) is a kernel module that provides
> active-active block-level replication over RDMA. It guarantees delivery
> of IO to a group of storage nodes and handles resynchronization of data
> directly between storage nodes without involving the compute client.
>
> BRMR (Block device over RMR) sits on top of RMR and exposes a standard
> Linux block device (/dev/brmrX) backed by an RMR pool. Together, RMR and
> BRMR provide a single-hop replication and resynchronization solution for
> RDMA-connected storage clusters.
>
> My session is on Wednesday, at 12 in the storage room (Istanbul).
To summarize the discussion:
1. Move as much logic as possible into the block layer; RDMA should serve
strictly as a transport.
2. Identify another in‑kernel user of this functionality, and add support for
it if required. At least accommodate potential users elsewhere in the
kernel.
Thanks
^ permalink raw reply
* Re: [PATCH v3 00/10] Add dmabuf read/write via io_uring
From: Pavel Begunkov @ 2026-05-12 9:30 UTC (permalink / raw)
To: Ming Lei
Cc: Jens Axboe, Keith Busch, Christoph Hellwig, Sagi Grimberg,
Alexander Viro, Christian Brauner, Andrew Morton, Sumit Semwal,
Christian König, linux-block, linux-kernel, linux-nvme,
linux-fsdevel, io-uring, linux-media, dri-devel, linaro-mm-sig,
Nitesh Shetty, Kanchan Joshi, Anuj Gupta, Tushar Gohad,
William Power, Phil Cayton, Jason Gunthorpe
In-Reply-To: <afxgc4hizusnAA26@fedora>
On 5/7/26 10:50, Ming Lei wrote:
...
>>> BTW, inspired by this approach, I adds similar feature to ublk via UBLK_IO_F_SHMEM_ZC
>>> which can maintain long-term vfio dma mapping over registered user-place aligned buffer.
>>
>> Interesting, just too a glance, and it looks like what David Wei
>> was thinking to add to fuse, but IIUC he gave up exactly because the
>> client will need to cooperate and that could be troublesome.
>
> Here the cooperation is minimized, maybe one shmem/hugetlb path, or memfd,
> and it is one optimization and opt-in, and fallback to normal path
> if application doesn't cooperate.
My point is that with widely enough adopted interface the user will be
able to opportunistically use it without knowledge about the file, i.e.
not knowing whether it's ublk or something else. But as you mentioned
below, it'd be cooperative interface in either case.
>> Should we try to push everything under the same interface instead of
>> keeping a ublk specific one? Again to the point that it requires
>
> If generic interface can be figured out, it shouldn't be a big deal for
> ublk to switch to it, and the usage is simple actually.
Sure, you'd just need to maintain both as there is a mismatch between
interfaces.
> So far, ublk supports both FS and nvme block device.
>
> And cooperation can't be avoided for this usage no matter if generic or
> driver specific implementation is taken, for both fuse & ublk.
--
Pavel Begunkov
^ permalink raw reply
* Re: [PATCH v3 00/10] Add dmabuf read/write via io_uring
From: Pavel Begunkov @ 2026-05-12 9:30 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Jens Axboe, Keith Busch, Sagi Grimberg, Alexander Viro,
Christian Brauner, Andrew Morton, Sumit Semwal,
Christian König, linux-block, linux-kernel, linux-nvme,
linux-fsdevel, io-uring, linux-media, dri-devel, linaro-mm-sig,
Nitesh Shetty, Kanchan Joshi, Anuj Gupta, Tushar Gohad,
William Power, Phil Cayton, Jason Gunthorpe
In-Reply-To: <20260512070045.GA32030@lst.de>
On 5/12/26 08:00, Christoph Hellwig wrote:
> What tree is this against? I can't apply it against the usual
> candidates, even accounting for the time lag in getting to it.
It should've been a Jens' for-next
> Can you provide a git tree?
git: https://github.com/isilence/linux.git rw-dmabuf-v4
url: https://github.com/isilence/linux/tree/rw-dmabuf-v4
It's a wip branch, for now it's just v3 + 2 fixes.
--
Pavel Begunkov
^ permalink raw reply
* [PATCH] ublk: clear server ownership before aborting in-flight requests
From: ZhengYuan Huang @ 2026-05-12 9:15 UTC (permalink / raw)
To: tom.leiming, axboe, ushankar
Cc: linux-block, linux-kernel, baijiaju1990, r33s3n6, zzzccc427,
ZhengYuan Huang
[BUG]
A stale UBLK_IO_COMMIT_AND_FETCH_REQ can reach the normal completion path
after ublk has already aborted the in-flight request, leading to a
use-after-free in map/unmap mode:
BUG: KASAN: use-after-free in ublk_copy_io_pages drivers/block/ublk_drv.c:946 [inline]
BUG: KASAN: use-after-free in ublk_copy_user_pages+0x83c/0xcc0 drivers/block/ublk_drv.c:1013
Write of size 4096 at addr ffff88800ce2a000 by task ublk.fsfuzz/275
Call Trace:
...
ublk_copy_io_pages drivers/block/ublk_drv.c:946 [inline]
ublk_copy_user_pages+0x83c/0xcc0 drivers/block/ublk_drv.c:1013
ublk_unmap_io+0x2bb/0x350 drivers/block/ublk_drv.c:1076
__ublk_complete_rq drivers/block/ublk_drv.c:1188 [inline]
ublk_ch_uring_cmd_local+0x157c/0x2180 drivers/block/ublk_drv.c:2477
ublk_ch_uring_cmd+0x42/0x640 drivers/block/ublk_drv.c:2561
io_uring_cmd+0x26f/0x570 io_uring/uring_cmd.c:263
__io_issue_sqe+0xc2/0x760 io_uring/io_uring.c:1826
io_issue_sqe+0xdd/0x11e0 io_uring/io_uring.c:1849
io_queue_sqe io_uring/io_uring.c:2076 [inline]
io_submit_sqe io_uring/io_uring.c:2336 [inline]
io_submit_sqes+0x806/0x2390 io_uring/io_uring.c:2449
__do_sys_io_uring_enter+0x5c0/0x13a0 io_uring/io_uring.c:3516
__se_sys_io_uring_enter io_uring/io_uring.c:3455 [inline]
__x64_sys_io_uring_enter+0xe5/0x1c0 io_uring/io_uring.c:3455
x64_sys_call+0x2419/0x26a0 arch/x86/include/generated/asm/syscalls_64.h:427
...
[CAUSE]
commit e63d2228ef83 ("ublk: simplify aborting ublk request") removed the
abort-only completion state and now __ublk_fail_req() fails or requeues
the request without first revoking UBLK_IO_FLAG_OWNED_BY_SRV. That leaves
the tag looking as if it is still owned by the ublk server, so a stale
COMMIT_AND_FETCH_REQ can pass the ownership check, reuse io->req, and
call __ublk_complete_rq() after the request has already been ended. In map
mode that drives ublk_unmap_io() into freed request pages.
[FIX]
Clear UBLK_IO_FLAG_OWNED_BY_SRV as soon as abort starts in
__ublk_fail_req(). Once ownership is revoked, any stale
COMMIT_AND_FETCH_REQ fails before touching io->req, so the completion path
can no longer copy into freed bio pages.
Fixes: e63d2228ef83 ("ublk: simplify aborting ublk request")
Signed-off-by: ZhengYuan Huang <gality369@gmail.com>
---
drivers/block/ublk_drv.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index 57ec900f0ce0..4f16a1ce7d2a 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -2673,6 +2673,9 @@ static void __ublk_fail_req(struct ublk_device *ub, struct ublk_io *io,
WARN_ON_ONCE(!ublk_dev_support_batch_io(ub) &&
io->flags & UBLK_IO_FLAG_ACTIVE);
+ /* The ublk server no longer owns this request once abort starts. */
+ io->flags &= ~UBLK_IO_FLAG_OWNED_BY_SRV;
+
if (ublk_nosrv_should_reissue_outstanding(ub))
blk_mq_requeue_request(req, false);
else {
--
2.43.0
^ permalink raw reply related
* Re: [PATCH] lib: free pagelist on error in iov_iter_extract_pages()
From: Fedor Pchelkin @ 2026-05-12 9:07 UTC (permalink / raw)
To: Dmitry Antipov, Caleb Sander Mateos
Cc: Jens Axboe, Andrew Morton, Christoph Hellwig, linux-block,
linux-fsdevel, lvc-project
In-Reply-To: <89db3b52508cfb345317feec8fe066849abccc14.camel@yandex.ru>
On Tue, 12. May 11:12, Dmitry Antipov wrote:
> On Fri, 2026-05-08 at 11:33 -0700, Caleb Sander Mateos wrote:
>
> > Indeed, it looks like *all* callers of iov_iter_extract_pages()
> > pass a non-NULL struct page **.
>
> This is not true for 6.12.x at least (where this issue was initially discovered)
> where bio_map_user_iov() do the following:
The current upstream has a caller of iov_iter_extract_pages() in
block/bio-integrity.c where NULL *@pages argument can be passed.
>
> For 6.12.x and may be other stables, the simplest possible fix is
> https://lore.kernel.org/stable/20260505094529.406783-1-dmantipov@yandex.ru/T/#u.
Older kernels have this pattern inside block/blk-map.c as well which you
fix with the linked patch. But there's still the same error left in
block/bio-integrity.c in 6.12.x, too. All the places ideally should be
fixed and this can be done as a couple of patches for 6.12.x. I'm not
against a step-by-step approach, but think this problem relates to the API
contract and all the cases should be considered as a whole if being
touched anyway.
>
> For upstream, it may be better to tweak iov_iter_extract_pages() itself, but
> it may be required to adjust all of the callers.
Taken the point that callers seem to be inconsistent about whether they
treat ret < 0 or ret <= 0 as the error case, it's up to them to decide
depending on their own logic. Not sure if we can suddenly convert all
'< 0' to '<= 0', this doesn't look correct.
And I see now that my initial suggestion to fix the problem in the callees
isn't so sweet and simple as it seemed, and agree with Caleb's and your
initial proposal to adjust the callers' side then.
In that case it'd be good to add some comment to iov_iter_extract_pages()
explaining that the caller is responsible for freeing the allocated memory
if it passes NULL *@pages argument - _even_ if iov_iter_extract_pages()
fails.
^ permalink raw reply
* [PATCH] sched: flush plug in schedule_preempt_disabled() to prevent deadlock
From: Ming Lei @ 2026-05-12 8:59 UTC (permalink / raw)
To: Jens Axboe, linux-block, linux-kernel
Cc: Ingo Molnar, Peter Zijlstra, Juri Lelli, Vincent Guittot,
Ming Lei, Michael Wu, Xiaosen He
On preemptible kernels, a deadlock can occur when a task with plugged IO
calls schedule_preempt_disabled():
schedule_preempt_disabled()
sched_preempt_enable_no_resched() // preemption now enabled
schedule() // <-- preemption can happen here
sched_submit_work()
blk_flush_plug()
After sched_preempt_enable_no_resched() re-enables preemption, the task
can be preempted (e.g., by a higher-priority RT task) before reaching
blk_flush_plug() in sched_submit_work(). Since the task's state is
already TASK_UNINTERRUPTIBLE (set by the mutex/rwsem slowpath caller),
requests in current->plug remain unflushed for an unbounded time.
If another task depends on those plugged requests to make progress (e.g.,
to release a lock the sleeping task needs), a deadlock results:
- Task A (writeback worker): holds plugged IO, preempted before
flushing, stuck on run queue behind higher-priority work
- Task B: waiting for IO completion from Task A's plug, holds a lock
that Task A needs to be woken up
Both reported deadlocks involve mutex/rwsem slowpaths, which are the
primary callers of schedule_preempt_disabled() with non-running task
state.
Fix by flushing the plug in schedule_preempt_disabled() while
preemption is still disabled. This ensures the plug is empty before the
preemption window opens.
Fixes: 73c101011926 ("block: initial patch for on-stack per-task plugging")
Reported-by: Michael Wu <michael@allwinnertech.com>
Tested-by: Michael Wu <michael@allwinnertech.com>
Reported-by: Xiaosen He <xiaosen.he@oss.qualcomm.com>
Link: https://lore.kernel.org/linux-block/20260417082744.30124-1-michael@allwinnertech.com/
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
---
kernel/sched/core.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index b8871449d3c6..c1efe110c54d 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -7336,6 +7336,8 @@ asmlinkage __visible void __sched schedule_user(void)
*/
void __sched schedule_preempt_disabled(void)
{
+ if (!task_is_running(current))
+ blk_flush_plug(current->plug, true);
sched_preempt_enable_no_resched();
schedule();
preempt_disable();
--
2.53.0
^ permalink raw reply related
* Re: [PATCH] lib: free pagelist on error in iov_iter_extract_pages()
From: Dmitry Antipov @ 2026-05-12 8:12 UTC (permalink / raw)
To: Caleb Sander Mateos
Cc: Jens Axboe, Andrew Morton, Christoph Hellwig, linux-block,
linux-fsdevel, lvc-project, Fedor Pchelkin
In-Reply-To: <CADUfDZpC5WOBY4_xvAy6ORtgQsxwFYj3Px81RdN7NKQZBFdJSQ@mail.gmail.com>
On Fri, 2026-05-08 at 11:33 -0700, Caleb Sander Mateos wrote:
> Indeed, it looks like *all* callers of iov_iter_extract_pages()
> pass a non-NULL struct page **.
This is not true for 6.12.x at least (where this issue was initially discovered)
where bio_map_user_iov() do the following:
...
while (iov_iter_count(iter)) {
struct page *stack_pages[UIO_FASTIOV];
struct page **pages = stack_pages;
ssize_t bytes;
size_t offs;
int npages;
if (nr_vecs > ARRAY_SIZE(stack_pages))
/* Stack pages aren't enough, so set 'pages' to NULL
and force allocation by want_pages_array(). */
pages = NULL;
bytes = iov_iter_extract_pages(iter, &pages, LONG_MAX,
nr_vecs, extraction_flags, &offs);
if (unlikely(bytes <= 0)) {
/* If 'pages' was allocated (and so pages != stack_pages), memory leak here */
ret = bytes ? bytes : -EFAULT;
goto out_unmap;
}
For 6.12.x and may be other stables, the simplest possible fix is
https://lore.kernel.org/stable/20260505094529.406783-1-dmantipov@yandex.ru/T/#u.
For upstream, it may be better to tweak iov_iter_extract_pages() itself, but
it may be required to adjust all of the callers.
Dmitry
^ permalink raw reply
* Re: [PATCH] sched: disable preemption around blk_flush_plug in sched_submit_work
From: Ming Lei @ 2026-05-12 8:07 UTC (permalink / raw)
To: Xiaosen; +Cc: Jens Axboe, linux-block, linux-kernel, Michael Wu
In-Reply-To: <5660795d-87de-46f5-add4-7729a02225ef@oss.qualcomm.com>
On Tue, May 12, 2026 at 01:56:55PM +0800, Xiaosen wrote:
> There is another deadlock caused by preemption during calling
> blk_flush_plug() in sched_submit_work().
> blk_mq_dispatch_list
> percpu_ref_get(&this_hctx->queue->q_usage_counter)
> percpu_ref_get_many(ref, 1);
> rcu_read_lock()
> __rcu_read_lock()
> rcu_lock_acquire
> lock_acquire
> preempt_schedule_irq --> writeback worker got
> preempted here and be scheduled out in D state
>
> 1. task kworker/u32:6 had dirty pages from f2fs node inode submitted to
> block layer and the corresponding request was added to plug list of the
> current task.
> 2. task snpe-net-run acquired gc_lock waiting for the request that
> contained page from node inode to be completed.
> 3. task kworker/u32:6 needed to acquire gc_lock to perform foreground
> GC, since the gc_lock had already been acquired by task snpe-net-run, so
> it called blk_flush_plug() in sched_submit_work() before sleeping to
> avoid deadlocks, but task kworker/u32:6 got preempted in RCU critical
> section before running hw queue to issue plugged requests. so the
> plugged requests were pending in local request list. task kworker/u32:6
> was scheduled out waiting to be woken up by the release of gc_lock.
> 4. so, there is a deadlock to cause RCU STALL.
>
> I think task kworker/u32:6 should not be scheduled out before returning
> from blk_flush_plug(), and I think this patch should be able to fix such
> deadlocks.
This patch isn't enough, because the current task could be preempted
anytime before calling into blk_flush_plug(), even before schedule().
One quick way is to fix schedule_preempt_disabled(), I will prepare one
formal patch later.
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index b8871449d3c6..18ef6ed71b4f 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -7336,6 +7336,7 @@ asmlinkage __visible void __sched schedule_user(void)
*/
void __sched schedule_preempt_disabled(void)
{
+ blk_flush_plug(current->plug, true);
sched_preempt_enable_no_resched();
schedule();
preempt_disable();
Thanks,
Ming
^ permalink raw reply related
* [PATCH v3] zram: fix use-after-free in zram_writeback_endio
From: Richard Chang @ 2026-05-12 7:49 UTC (permalink / raw)
To: Minchan Kim, Sergey Senozhatsky, Jens Axboe, Andrew Morton
Cc: bgeffon, liumartin, linux-kernel, linux-block, linux-mm,
Richard Chang, stable
In-Reply-To: <af6ZT9oR7GGmMFSC@google.com>
A crash was observed in zram_writeback_endio due to a NULL pointer
dereference in wake_up. The root cause is a race condition between the
bio completion handler (zram_writeback_endio) and the writeback task.
In zram_writeback_endio, wake_up() is called on &wb_ctl->done_wait after
releasing wb_ctl->done_lock. This creates a race window where the
writeback task can see num_inflight become 0, return, and free wb_ctl
before zram_writeback_endio calls wake_up().
CPU 0 (zram_writeback_endio) CPU 1 (writeback_store)
============================ ============================
zram_writeback_slots
zram_submit_wb_request
zram_submit_wb_request
wait_event(wb_ctl->done_wait)
spin_lock(&wb_ctl->done_lock);
list_add(&req->entry, &wb_ctl->done_reqs);
spin_unlock(&wb_ctl->done_lock);
wake_up(&wb_ctl->done_wait);
zram_complete_done_reqs
spin_lock(&wb_ctl->done_lock);
list_add(&req->entry, &wb_ctl->done_reqs);
spin_unlock(&wb_ctl->done_lock);
while (num_inflight) > 0)
spin_lock(&wb_ctl->done_lock);
list_del(&req->entry);
spin_unlock(&wb_ctl->done_lock);
// num_inflight becomes 0
atomic_dec(num_inflight);
// Leave zram_writeback_slots
// Free wb_ctl
release_wb_ctl(wb_ctl);
// UAF crash!
wake_up(&wb_ctl->done_wait);
This patch fixes this race by using RCU. By protecting wb_ctl with
rcu_read_lock() in zram_writeback_endio and using kfree_rcu() to free
it, we ensure that wb_ctl remains valid during the execution of
zram_writeback_endio.
Fixes: f405066a1f0d ("zram: introduce writeback bio batching")
Cc: stable@vger.kernel.org
Suggested-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Suggested-by: Minchan Kim <minchan@kernel.org>
Signed-off-by: Richard Chang <richardycc@google.com>
---
V2: use RCU to manage the wb_ctl lifetime
V3: add stable tag
drivers/block/zram/zram_drv.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index aebc710f0d6a..07111455eecf 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -33,6 +33,7 @@
#include <linux/cpuhotplug.h>
#include <linux/part_stat.h>
#include <linux/kernel_read_file.h>
+#include <linux/rcupdate.h>
#include "zram_drv.h"
@@ -504,6 +505,7 @@ struct zram_wb_ctl {
wait_queue_head_t done_wait;
spinlock_t done_lock;
atomic_t num_inflight;
+ struct rcu_head rcu;
};
struct zram_wb_req {
@@ -847,7 +849,7 @@ static void release_wb_ctl(struct zram_wb_ctl *wb_ctl)
release_wb_req(req);
}
- kfree(wb_ctl);
+ kfree_rcu(wb_ctl, rcu);
}
static struct zram_wb_ctl *init_wb_ctl(struct zram *zram)
@@ -964,11 +966,13 @@ static void zram_writeback_endio(struct bio *bio)
struct zram_wb_ctl *wb_ctl = bio->bi_private;
unsigned long flags;
+ rcu_read_lock();
spin_lock_irqsave(&wb_ctl->done_lock, flags);
list_add(&req->entry, &wb_ctl->done_reqs);
spin_unlock_irqrestore(&wb_ctl->done_lock, flags);
wake_up(&wb_ctl->done_wait);
+ rcu_read_unlock();
}
static void zram_submit_wb_request(struct zram *zram,
--
2.54.0.563.g4f69b47b94-goog
^ permalink raw reply related
* Re: [PATCH 12/12] swap: move swap_info_struct to mm/swap.h
From: Damien Le Moal @ 2026-05-12 7:41 UTC (permalink / raw)
To: Christoph Hellwig, Andrew Morton, Chris Li, Kairui Song
Cc: Christian Brauner, Darrick J . Wong, Jens Axboe, David Sterba,
Theodore Ts'o, Jaegeuk Kim, Chao Yu, Trond Myklebust,
Anna Schumaker, Namjae Jeon, Hyunchul Lee, Steve French,
Paulo Alcantara, Carlos Maiolino, Naohiro Aota, linux-xfs,
linux-fsdevel, linux-doc, linux-mm, linux-block, linux-btrfs,
linux-ext4, linux-f2fs-devel, linux-nfs, linux-cifs
In-Reply-To: <20260512053625.2950900-13-hch@lst.de>
On 5/12/26 14:35, Christoph Hellwig wrote:
> swap_info_struct is now internal to the MM subsystem, so remove it from
> the public header.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Looks OK to me.
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply
* Re: [PATCH 11/12] swap: move struct swap_extent to swapfile.c
From: Damien Le Moal @ 2026-05-12 7:36 UTC (permalink / raw)
To: Christoph Hellwig, Andrew Morton, Chris Li, Kairui Song
Cc: Christian Brauner, Darrick J . Wong, Jens Axboe, David Sterba,
Theodore Ts'o, Jaegeuk Kim, Chao Yu, Trond Myklebust,
Anna Schumaker, Namjae Jeon, Hyunchul Lee, Steve French,
Paulo Alcantara, Carlos Maiolino, Naohiro Aota, linux-xfs,
linux-fsdevel, linux-doc, linux-mm, linux-block, linux-btrfs,
linux-ext4, linux-f2fs-devel, linux-nfs, linux-cifs
In-Reply-To: <20260512053625.2950900-12-hch@lst.de>
On 5/12/26 14:35, Christoph Hellwig wrote:
> struct swap_extent is only used inside of mm/swapfile.c, so move it
> there.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Looks OK to me.
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply
* Re: [PATCH 10/12] swap: add a swap_activate_fs_ops helper
From: Damien Le Moal @ 2026-05-12 7:36 UTC (permalink / raw)
To: Christoph Hellwig, Andrew Morton, Chris Li, Kairui Song
Cc: Christian Brauner, Darrick J . Wong, Jens Axboe, David Sterba,
Theodore Ts'o, Jaegeuk Kim, Chao Yu, Trond Myklebust,
Anna Schumaker, Namjae Jeon, Hyunchul Lee, Steve French,
Paulo Alcantara, Carlos Maiolino, Naohiro Aota, linux-xfs,
linux-fsdevel, linux-doc, linux-mm, linux-block, linux-btrfs,
linux-ext4, linux-f2fs-devel, linux-nfs, linux-cifs
In-Reply-To: <20260512053625.2950900-11-hch@lst.de>
On 5/12/26 14:35, Christoph Hellwig wrote:
> Add a helper abstracting away the low-level details of enabling
> fs_ops-based swapping. This prepares for taking swap_info_struct
> private.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Looks OK to me.
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply
* Re: [PATCH 09/12] swap: push down setting sis->bdev into ->swap_activate
From: Damien Le Moal @ 2026-05-12 7:34 UTC (permalink / raw)
To: Christoph Hellwig, Andrew Morton, Chris Li, Kairui Song
Cc: Christian Brauner, Darrick J . Wong, Jens Axboe, David Sterba,
Theodore Ts'o, Jaegeuk Kim, Chao Yu, Trond Myklebust,
Anna Schumaker, Namjae Jeon, Hyunchul Lee, Steve French,
Paulo Alcantara, Carlos Maiolino, Naohiro Aota, linux-xfs,
linux-fsdevel, linux-doc, linux-mm, linux-block, linux-btrfs,
linux-ext4, linux-f2fs-devel, linux-nfs, linux-cifs
In-Reply-To: <20260512053625.2950900-10-hch@lst.de>
On 5/12/26 14:35, Christoph Hellwig wrote:
> Only the file operation method knows what block device we'll swap
> to. So move down setting sis->bdev and the special blockdev flag
> into ->swap_activate.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
One nit below. Otherwise, looks OK to me.
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
> @@ -141,7 +141,6 @@ int generic_swap_activate(struct file *swap_file, struct swap_info_struct *sis)
> continue;
> }
> return 0;
> -
whiteline change.
> bad_bmap:
> pr_err("swapon: swapfile has holes\n");
> return -EINVAL;
--
Damien Le Moal
Western Digital Research
^ permalink raw reply
* Re: [PATCH 08/12] swap,iomap: simplify iomap_swapfile_iter
From: Damien Le Moal @ 2026-05-12 7:31 UTC (permalink / raw)
To: Christoph Hellwig, Andrew Morton, Chris Li, Kairui Song
Cc: Christian Brauner, Darrick J . Wong, Jens Axboe, David Sterba,
Theodore Ts'o, Jaegeuk Kim, Chao Yu, Trond Myklebust,
Anna Schumaker, Namjae Jeon, Hyunchul Lee, Steve French,
Paulo Alcantara, Carlos Maiolino, Naohiro Aota, linux-xfs,
linux-fsdevel, linux-doc, linux-mm, linux-block, linux-btrfs,
linux-ext4, linux-f2fs-devel, linux-nfs, linux-cifs
In-Reply-To: <20260512053625.2950900-9-hch@lst.de>
On 5/12/26 14:35, Christoph Hellwig wrote:
> add_swap_extent already coalesces multiple extents, no need to duplicate
> that in the caller.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Looks OK to me.
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply
* Re: [PATCH 07/12] swap,block: limit swap file size to device size
From: Christoph Hellwig @ 2026-05-12 7:23 UTC (permalink / raw)
To: Damien Le Moal
Cc: Christoph Hellwig, Andrew Morton, Chris Li, Kairui Song,
Christian Brauner, Darrick J . Wong, Jens Axboe, David Sterba,
Theodore Ts'o, Jaegeuk Kim, Chao Yu, Trond Myklebust,
Anna Schumaker, Namjae Jeon, Hyunchul Lee, Steve French,
Paulo Alcantara, Carlos Maiolino, Naohiro Aota, linux-xfs,
linux-fsdevel, linux-doc, linux-mm, linux-block, linux-btrfs,
linux-ext4, linux-f2fs-devel, linux-nfs, linux-cifs
In-Reply-To: <217f91d9-4d5f-47a6-ad20-0404968b8e08@kernel.org>
On Tue, May 12, 2026 at 04:21:47PM +0900, Damien Le Moal wrote:
> On 5/12/26 14:35, Christoph Hellwig wrote:
> > Don't blindly pass the value from the swap header to swap_add_extent,
> > but instead the device size rounded down to page granularity. This
> > activated the sanity checking in the core code that catches a too large
> > value in the swap header.
> >
> > Signed-off-by: Christoph Hellwig <hch@lst.de>
>
> Looks OK to me, though this maybe could be folded in the previous patch ?
I prefer to keep behavior changes as isolated as possible.
^ permalink raw reply
* Re: [PATCH 07/12] swap,block: limit swap file size to device size
From: Damien Le Moal @ 2026-05-12 7:21 UTC (permalink / raw)
To: Christoph Hellwig, Andrew Morton, Chris Li, Kairui Song
Cc: Christian Brauner, Darrick J . Wong, Jens Axboe, David Sterba,
Theodore Ts'o, Jaegeuk Kim, Chao Yu, Trond Myklebust,
Anna Schumaker, Namjae Jeon, Hyunchul Lee, Steve French,
Paulo Alcantara, Carlos Maiolino, Naohiro Aota, linux-xfs,
linux-fsdevel, linux-doc, linux-mm, linux-block, linux-btrfs,
linux-ext4, linux-f2fs-devel, linux-nfs, linux-cifs
In-Reply-To: <20260512053625.2950900-8-hch@lst.de>
On 5/12/26 14:35, Christoph Hellwig wrote:
> Don't blindly pass the value from the swap header to swap_add_extent,
> but instead the device size rounded down to page granularity. This
> activated the sanity checking in the core code that catches a too large
> value in the swap header.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Looks OK to me, though this maybe could be folded in the previous patch ?
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply
* Re: [PATCH 01/12] swap: remove the maxpages variable in sys_swapon
From: Christoph Hellwig @ 2026-05-12 7:20 UTC (permalink / raw)
To: Damien Le Moal
Cc: Christoph Hellwig, Andrew Morton, Chris Li, Kairui Song,
Christian Brauner, Darrick J . Wong, Jens Axboe, David Sterba,
Theodore Ts'o, Jaegeuk Kim, Chao Yu, Trond Myklebust,
Anna Schumaker, Namjae Jeon, Hyunchul Lee, Steve French,
Paulo Alcantara, Carlos Maiolino, Naohiro Aota, linux-xfs,
linux-fsdevel, linux-doc, linux-mm, linux-block, linux-btrfs,
linux-ext4, linux-f2fs-devel, linux-nfs, linux-cifs
In-Reply-To: <03dddf72-8755-4ebf-ba79-456377f0f25d@kernel.org>
On Tue, May 12, 2026 at 04:08:35PM +0900, Damien Le Moal wrote:
> On 5/12/26 14:35, Christoph Hellwig wrote:
> > Always use si->max which is updated setup_swap_extents instead of copying
> > into and out of maxpages.
>
> Checking mm/swapfile.c, I see s->max being set only in swapon(). Is this a typo
> or am I misunderstanding this sentence ?
It is updated by the file system methods or the generic implementation
called by setup_swap_extents currently. So the above is a bit imprecise.
The next patch then removes this confusing update.
^ permalink raw reply
* Re: [PATCH 06/12] swap,block: move the block device swapon code into block/fops.c
From: Damien Le Moal @ 2026-05-12 7:20 UTC (permalink / raw)
To: Christoph Hellwig, Andrew Morton, Chris Li, Kairui Song
Cc: Christian Brauner, Darrick J . Wong, Jens Axboe, David Sterba,
Theodore Ts'o, Jaegeuk Kim, Chao Yu, Trond Myklebust,
Anna Schumaker, Namjae Jeon, Hyunchul Lee, Steve French,
Paulo Alcantara, Carlos Maiolino, Naohiro Aota, linux-xfs,
linux-fsdevel, linux-doc, linux-mm, linux-block, linux-btrfs,
linux-ext4, linux-f2fs-devel, linux-nfs, linux-cifs
In-Reply-To: <20260512053625.2950900-7-hch@lst.de>
On 5/12/26 14:35, Christoph Hellwig wrote:
> Make use of the abstractions we have. This is a preparation for
> moving more special casing down into block/.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Looks OK to me.
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply
* Re: [PATCH 05/12] swap: cleanup setup_swap_extents
From: Damien Le Moal @ 2026-05-12 7:18 UTC (permalink / raw)
To: Christoph Hellwig, Andrew Morton, Chris Li, Kairui Song
Cc: Christian Brauner, Darrick J . Wong, Jens Axboe, David Sterba,
Theodore Ts'o, Jaegeuk Kim, Chao Yu, Trond Myklebust,
Anna Schumaker, Namjae Jeon, Hyunchul Lee, Steve French,
Paulo Alcantara, Carlos Maiolino, Naohiro Aota, linux-xfs,
linux-fsdevel, linux-doc, linux-mm, linux-block, linux-btrfs,
linux-ext4, linux-f2fs-devel, linux-nfs, linux-cifs
In-Reply-To: <20260512053625.2950900-6-hch@lst.de>
On 5/12/26 14:35, Christoph Hellwig wrote:
> Reflow setup_swap_extents so that the flag checking is not conditional on
> a swap_activate method. This is currently a no-op because the swapoff
> code still checks the presence of a swap_deactivate method, but it
> simplifies adding a new check, and also makes the SWP_ACTIVATED flag
> more consistent.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Looks OK to me.
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply
* Re: [PATCH 04/12] swap: restrict to regular files or block devices
From: Damien Le Moal @ 2026-05-12 7:17 UTC (permalink / raw)
To: Christoph Hellwig, Andrew Morton, Chris Li, Kairui Song
Cc: Christian Brauner, Darrick J . Wong, Jens Axboe, David Sterba,
Theodore Ts'o, Jaegeuk Kim, Chao Yu, Trond Myklebust,
Anna Schumaker, Namjae Jeon, Hyunchul Lee, Steve French,
Paulo Alcantara, Carlos Maiolino, Naohiro Aota, linux-xfs,
linux-fsdevel, linux-doc, linux-mm, linux-block, linux-btrfs,
linux-ext4, linux-f2fs-devel, linux-nfs, linux-cifs
In-Reply-To: <20260512053625.2950900-5-hch@lst.de>
On 5/12/26 14:35, Christoph Hellwig wrote:
> Various swap code assumes it runs either on a block device or on a
> regular file. Make this restriction explicit using checks right
> after opening the file.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply
* Re: [PATCH 03/12] swap,fs: move swapfile operations to struct file_operations
From: Damien Le Moal @ 2026-05-12 7:16 UTC (permalink / raw)
To: Christoph Hellwig, Andrew Morton, Chris Li, Kairui Song
Cc: Christian Brauner, Darrick J . Wong, Jens Axboe, David Sterba,
Theodore Ts'o, Jaegeuk Kim, Chao Yu, Trond Myklebust,
Anna Schumaker, Namjae Jeon, Hyunchul Lee, Steve French,
Paulo Alcantara, Carlos Maiolino, Naohiro Aota, linux-xfs,
linux-fsdevel, linux-doc, linux-mm, linux-block, linux-btrfs,
linux-ext4, linux-f2fs-devel, linux-nfs, linux-cifs
In-Reply-To: <20260512053625.2950900-4-hch@lst.de>
On 5/12/26 14:35, Christoph Hellwig wrote:
> The swap operations have nothing to do with the address_space, which is
> used for pagecache operations. Move them to struct file_operations
> instead. This will allow moving the block device special cases into
> block/fops.c subsequently.
>
> Pass struct file first to ->swap_activate as file operations typically
> get the file or iocb as first argument and use swap_activate instead of
> swapfile_activate in all names to be consistent.
>
> Note that while the trivial iomap wrappers are moved to a new file when
> applicable to keep them local to the file operation instances, complex
> implementation are kept in their existing place. It might be worth to
> move them in follow-on patches if the maintainers desire so.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Looks OK to me.
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox