Linux filesystem development
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: Miklos Szeredi <miklos@szeredi.hu>
Cc: Sergey Senozhatsky <senozhatsky@chromium.org>,
	fuse-devel@lists.linux.dev, linux-kernel@vger.kernel.org,
	"Rafael J. Wysocki" <rafael@kernel.org>,
	linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH v2] fuse: permit freezing while waiting for request answer
Date: Fri, 21 Aug 2026 10:30:00 +0200	[thread overview]
Message-ID: <20260821083000.GF687043@noisy.programming.kicks-ass.net> (raw)
In-Reply-To: <CAJfpegsSzOqs1zkhB9GZxsT5HT1zXDbHsZNEbA7P7mxe0w2dng@mail.gmail.com>

On Thu, Aug 20, 2026 at 06:11:40PM +0200, Miklos Szeredi wrote:
> On Thu, 20 Aug 2026 at 12:41, Peter Zijlstra <peterz@infradead.org> wrote:
> 
> > Also, you'd be putting suspend success in the hands of userspace, that
> > sounds like a mighty fail right there.
> 
> Freeze ordering is also a hard/impossible problem without the help of
> userspace.

In case of fuse, perhaps.

> One obvious heuristic is if task has a /dev/fuse fd open,
> it is a server.  This simple ordering between server and non-server
> tasks fails if
> 
>  - task X is a server of A, while also doing ops on B
> 
>  - task X is server, blocked on task Y which is not a server
> 
> What about adding a flag to mutex/rwsem that allows making them
> freezable at setup time?  Then fuse fs could set that flag for its
> locks (including VFS locks).

That would be adding conditionals to the mutex, something we all pay
for, always.

I was thinking it shouldn't be too hard to add a graph to the tasklist,
where each task has a list of other tasks that should be frozen before
it.

That way the task iteration in try_to_freeze_tasks() can be modified to
iterate this list (recursively; depth-first etc.) before it goes and
freezes the initial task.

Obviously adding a link to the graph needs to ensure the whole thing
stays free of cycles, but that is 'details' :-)

And while this is fairly straight forward to make work, I fear it is the
wrong shape for the problem, since the server is more of an 'after'
rather than a 'before' relation. You would have to add all clients to
the before of the server.

Another approach might be to have each task have a list of tasks that
needs to be done later, and have this relation be counted in the
destination task.

Then, on freeze, create a list of all tasks and start iteration, for
each task that has a non-zero count of prior tasks, move it to the tail.
This relies on freeze points being a location where a task has no
relations. Such that when a task is frozen, it has no dependencies.

Then, again assuming it was a non-cyclic graph, it will always finish
the freeze in an order that resolves the dependencies.

This might be a little more tricky to implement, but should be doable.

In both scenarios the tracking of the actual dependencies is of course
going to be key.

One way would be for each file op to be wrapped like 'link-$op-unlink'
such that the client (the task doing the file op) gets linked to the
server (the task responsible for satisfying the request) before it can
block, and unlinked once its done.

Link/unlink could be a simple as:

	struct task_struct *client, *server;

link;
	atomic_inc(&server->freezer_count);
	client->freezer_link = server;

unlink:

	atomic_dec(&client->freezer_link->freezer_count);
	client->freezer_link = NULL;

And the freezer should assert: !task->freezer_link, to ensure you
cannot be frozen while still having a link out, since this would keep
the link target's count elevated and inhibit freezer forever more.

This also deals with the server being a client of yet another fuse
filesystem. Creating cycles in fuse mounts would already be a recipe
for disaster today, without all this, so I'm assuming this all just
'works'.

Does any of that make sense?

  reply	other threads:[~2026-08-21  8:30 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20260819023542.561653-1-senozhatsky@chromium.org>
2026-08-19 10:03 ` [PATCH v2] fuse: permit freezing while waiting for request answer 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
2026-08-20 16:11                 ` Miklos Szeredi
2026-08-21  8:30                   ` Peter Zijlstra [this message]
2026-08-21 11:03                     ` Peter Zijlstra
2026-08-21 14:33                     ` Miklos Szeredi
2026-08-21 14:57                       ` Peter Zijlstra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260821083000.GF687043@noisy.programming.kicks-ass.net \
    --to=peterz@infradead.org \
    --cc=fuse-devel@lists.linux.dev \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    --cc=rafael@kernel.org \
    --cc=senozhatsky@chromium.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox