On Fri, 6 Jun 2025 at 07:57, Sergey Senozhatsky <senozhatsky@xxxxxxxxxxxx> wrote: > > Hi, > > We are seeing a number of cases when blocked fuse requests prevent > the system from suspending, which is a little important on laptops. > Usually something like this: > > [ 36.281038] Freezing user space processes > [ 56.284961] Freezing user space processes failed after 20.003 seconds (1 tasks refusing to freeze, wq_busy=0): > [ 56.285069] task:secagentd state:D stack:0 pid:1792 ppid:1711 flags:0x00004006 > [ 56.285084] Call Trace: > [ 56.285091] <TASK> > [ 56.285111] schedule+0x612/0x2230 > [ 56.285136] fuse_get_req+0x108/0x2d0 > [ 56.285179] fuse_simple_request+0x40/0x630 > [ 56.285203] fuse_getxattr+0x15d/0x1c0 > [...] > > Which looks like wait_event_killable_exclusive() in fuse_get_req(). > And we were wondering if we could do something about it. For example, > perhaps, something like: > > --- > > diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c > index f182a4ca1bb32..587cea3a0407d 100644 > --- a/fs/fuse/dev.c > +++ b/fs/fuse/dev.c > @@ -241,7 +241,7 @@ static struct fuse_req *fuse_get_req(struct fuse_conn *fc, bool for_background) > > if (fuse_block_alloc(fc, for_background)) { > err = -EINTR; > - if (wait_event_killable_exclusive(fc->blocked_waitq, > + if (wait_event_freezable_killable_exclusive(fc->blocked_waitq, > !fuse_block_alloc(fc, for_background))) > goto out; > } This looks fine. We can turn each wait into a freezable one inside fuse. But that still would leave core locks (inode lock, rename lock, page lock, etc) unfreezable. Turning those into freezable isn't realistic... But a partial solution might still be better than no solution. Thanks, Miklos