FAILED: patch "[PATCH] io_uring/rw: end write accounting from ->ki_complete" failed to apply to 5.15-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x 796aa0547557e63338657ed1c487906f9fac4c73
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026091626-pacify-aluminum-bcbd@gregkh' --subject-prefix 'PATCH 5.15.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 796aa0547557e63338657ed1c487906f9fac4c73 Mon Sep 17 00:00:00 2001
From: Jens Axboe <[email protected]>
Date: Tue, 8 Sep 2026 17:53:20 -0600
Subject: [PATCH] io_uring/rw: end write accounting from ->ki_complete
Commit b000145e9907 moved both the fsnotify calls and the write accounting out of the kiocb completion handler and into the io_req_rw_complete() task_work. However, only the fsnotify part actually needed to move as it may sleep. Ending the write accounting is just a percpu_up_read() on the superblock writers sem.
Deferring it is a problem, because it makes dropping SB_FREEZE_WRITE protection depend on the ring owner getting to running task_work. But the task may be blocked in freeze_super(), causing it to never get to that:
task io-wq worker
--------------------------------------------------------------
io_write()
io_kiocb_start_write() (takes sb_writers, hidden from
lockdep by __sb_writers_release)
write_iter() -> -EIOCBQUEUED
ioctl(FS_IOC_SHUTDOWN)
bdev_freeze()
freeze_super()
percpu_down_write() <- waits for the reader above
io_write()
kiocb_start_write()
percpu_down_read() <- queued
behind the writer
<bio completes>
io_complete_rw()
queues io_req_rw_complete() <- never runs, task is in D state
End the write from io_complete_rw() instead, and leave only the fsnotify calls in task_work.
io_uring/rw.c +19 -10
@@ -517,20 +517,25 @@ static void io_req_end_write(struct io_kiocb *req) } } -/* -* Trigger the notifications after having done some IO, and finish the write -* accounting, if any. -*/ +/* Trigger the notifications after having done some IO. */ +static void io_req_io_notify (struct io_kiocb *req) +{ + struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw); + +if (rw->kiocb.ki_flags &IOCB_WRITE ) +fsnotify_modify (req->file); +else +fsnotify_access (req->file); +} + +/* Finish write accounting and notify, for inline completions only. */ static void io_req_io_end (struct io_kiocb *req) { struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw); -if (rw->kiocb.ki_flags &IOCB_WRITE ) { +if (rw->kiocb.ki_flags &IOCB_WRITE )io_req_end_write (req); -fsnotify_modify (req->file); - }else { -fsnotify_access (req->file); - } +io_req_io_notify (req); }static void __io_complete_rw_common (struct io_kiocb *req,long res)
@@ -563,7 +568,7 @@ void io_req_rw_complete(struct io_tw_req tw_req, io_tw_token_t tw) {struct io_kiocb *req = tw_req.req; -io_req_io_end (req); +io_req_io_notify (req);if (req->flags & (REQ_F_BUFFER_SELECTED |REQ_F_BUFFER_RING )) req->cqe.flags |=io_put_kbuf (req,max (req->cqe.res,0 ),NULL );
@@ -577,6 +582,10 @@ static void io_complete_rw(struct kiocb *kiocb, long res) struct io_rw *rw = container_of(kiocb, struct io_rw, kiocb);struct io_kiocb *req =cmd_to_io_kiocb (rw); +/* ring owner may block in freeze_super() before task_work runs */ +if (kiocb->ki_flags &IOCB_WRITE ) +io_req_end_write (req); +__io_complete_rw_common (req, res);io_req_set_res (req,io_fixup_rw_res (req, res),0 ); req->io_task_work.func = io_req_rw_complete;
Sasha Levin
maintainerPATCH 1/1 io_uring/rw: end write accounting from ->ki_complete
From: Jens Axboe <[email protected]>
[ Upstream commit 796aa0547557e63338657ed1c487906f9fac4c73 ]
Commit b000145e9907 moved both the fsnotify calls and the write accounting out of the kiocb completion handler and into the io_req_rw_complete() task_work. However, only the fsnotify part actually needed to move as it may sleep. Ending the write accounting is just a percpu_up_read() on the superblock writers sem.
Deferring it is a problem, because it makes dropping SB_FREEZE_WRITE protection depend on the ring owner getting to running task_work. But the task may be blocked in freeze_super(), causing it to never get to that:
task io-wq worker
--------------------------------------------------------------
io_write()
io_kiocb_start_write() (takes sb_writers, hidden from
lockdep by __sb_writers_release)
write_iter() -> -EIOCBQUEUED
ioctl(FS_IOC_SHUTDOWN)
bdev_freeze()
freeze_super()
percpu_down_write() <- waits for the reader above
io_write()
kiocb_start_write()
percpu_down_read() <- queued
behind the writer
<bio completes>
io_complete_rw()
queues io_req_rw_complete() <- never runs, task is in D state
End the write from io_complete_rw() instead, and leave only the fsnotify calls in task_work.
--- io_uring/io_uring.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
io_uring/io_uring.c +8 -1
@@ -2797,7 +2797,10 @@ static void io_req_task_complete(struct io_kiocb *req, bool *locked)static void io_req_rw_complete (struct io_kiocb *req,bool *locked) { -io_req_io_end (req); +if (req->rw.kiocb.ki_flags &IOCB_WRITE ) +fsnotify_modify (req->file); +else +fsnotify_access (req->file);io_req_task_complete (req, locked); }
@@ -2807,6 +2810,10 @@ static void io_complete_rw(struct kiocb *kiocb, long res, long res2)if (__io_complete_rw_common (req, res))return ; +/* ring owner may block in freeze_super() before task_work runs */ +if (kiocb->ki_flags &IOCB_WRITE ) +io_req_end_write (req); + req->result =io_fixup_rw_res (req, res); req->io_task_work.func = io_req_rw_complete;io_req_task_work_add (req);
Signature · 1 line
2.53.0