FAILED: patch "[PATCH] io_uring/rw: end write accounting from ->ki_complete" failed to apply to 6.1-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.1-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-6.1.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 '2026091625-maturing-defog-33c9@gregkh' --subject-prefix 'PATCH 6.1.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/rw.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-)
io_uring/rw.c +13 -8
@@ -235,14 +235,15 @@ 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. +* accounting for inline completions. */ -static void io_req_io_end (struct io_kiocb *req) +static void io_req_io_end (struct io_kiocb *req,bool end_write) { struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw);if (rw->kiocb.ki_flags &IOCB_WRITE ) { -io_req_end_write (req); +if (end_write) +io_req_end_write (req);fsnotify_modify (req->file); }else {fsnotify_access (req->file);
@@ -255,10 +256,10 @@ static bool __io_complete_rw_common(struct io_kiocb *req, long res)if ((res == -EAGAIN || res == -EOPNOTSUPP ) &&io_rw_should_reissue (req)) {/* -* Reissue will start accounting again, finish the -* current cycle. +* Write accounting is already finished by +* io_complete_rw(). */ -io_req_io_end (req); +io_req_io_end (req, false); req->flags |=REQ_F_REISSUE |REQ_F_PARTIAL_IO ;return true; }
@@ -284,7 +285,7 @@ static inline int io_fixup_rw_res(struct io_kiocb *req, long res)static void io_req_rw_complete (struct io_kiocb *req,bool *locked) { -io_req_io_end (req); +io_req_io_end (req, false);io_req_task_complete (req, locked); }
@@ -293,6 +294,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); +if (__io_complete_rw_common (req, res))return ;io_req_set_res (req,io_fixup_rw_res (req, res),0 );
@@ -333,7 +338,7 @@ static int kiocb_done(struct io_kiocb *req, ssize_t ret,* Safe to call io_end from here as we're inline * from the submission path. */ -io_req_io_end (req); +io_req_io_end (req, true);io_req_set_res (req, final_ret,io_put_kbuf (req, issue_flags));return IOU_OK ;
Signature · 1 line
2.53.0