All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] fuse: permit freezing while waiting for request answer
@ 2026-08-19  2:35 Sergey Senozhatsky
  2026-08-19 10:03 ` Miklos Szeredi
  0 siblings, 1 reply; 10+ messages in thread
From: Sergey Senozhatsky @ 2026-08-19  2:35 UTC (permalink / raw)
  To: Miklos Szeredi; +Cc: fuse-devel, linux-kernel, Sergey Senozhatsky

Suspend freezes tasks in random order and doesn't take into
consideration producer-consumer dependency that may exist
between tasks.  One example where this can cause issues is:
fuse server getting frozen ahead of clients, which then get
stuck waiting for req answers that never come (the server
is already frozen).

Make all wait-event calls in request_wait_answer() freezer-friendly.

This, however, doesn't address all cases.  E.g. in-place
PM-freeze of a request_wait_answer() task holding a contended
VFS lock still will block suspend.

Note: this uses TASK_FREEZABLE, not TASK_FREEZABLE_UNSAFE,
which may trigger debug_locks warning during suspend (if
request_wait_answer() task holds some locks at the time
of freeze.)

Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---

 fs/fuse/dev.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 34106f6e66a0..42098ddc2587 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -701,8 +701,9 @@ static void request_wait_answer(struct fuse_req *req)
 
 	if (!fch->no_interrupt) {
 		/* Any signal may interrupt this */
-		err = wait_event_interruptible(req->waitq,
-					test_bit(FR_FINISHED, &req->flags));
+		err = wait_event_state(req->waitq,
+				       test_bit(FR_FINISHED, &req->flags),
+				       (TASK_INTERRUPTIBLE | TASK_FREEZABLE));
 		if (!err)
 			return;
 
@@ -717,8 +718,9 @@ static void request_wait_answer(struct fuse_req *req)
 		bool removed;
 
 		/* Only fatal signals may interrupt this */
-		err = wait_event_killable(req->waitq,
-					test_bit(FR_FINISHED, &req->flags));
+		err = wait_event_state(req->waitq,
+				       test_bit(FR_FINISHED, &req->flags),
+				       (TASK_KILLABLE | TASK_FREEZABLE));
 		if (!err)
 			return;
 
@@ -740,7 +742,8 @@ static void request_wait_answer(struct fuse_req *req)
 	 * Either request is already in userspace, or it was forced.
 	 * Wait it out.
 	 */
-	wait_event(req->waitq, test_bit(FR_FINISHED, &req->flags));
+	wait_event_state(req->waitq, test_bit(FR_FINISHED, &req->flags),
+			 (TASK_UNINTERRUPTIBLE | TASK_FREEZABLE));
 }
 
 static void __fuse_request_send(struct fuse_req *req)
-- 
2.55.0.737.g08866a6d13-goog


^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-08-20 10:41 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-19  2:35 [PATCH v2] fuse: permit freezing while waiting for request answer Sergey Senozhatsky
2026-08-19 10:03 ` Miklos Szeredi
2026-08-20  4:57   ` Sergey Senozhatsky
2026-08-20  8:49   ` Peter Zijlstra
2026-08-20  9:07     ` Sergey Senozhatsky
2026-08-20  9:10       ` Peter Zijlstra
2026-08-20  9:24         ` Sergey Senozhatsky
2026-08-20  9:34           ` Peter Zijlstra
2026-08-20  9:47             ` Sergey Senozhatsky
2026-08-20 10:41               ` Peter Zijlstra

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.