diff options
| author | Baokun Li <libaokun@linux.alibaba.com> | 2026-08-01 16:24:51 +0800 |
|---|---|---|
| committer | Miklos Szeredi <mszeredi@redhat.com> | 2026-08-18 15:20:29 +0200 |
| commit | d1dbc59200b54944f00251ca4dfbb2b318beca13 (patch) | |
| tree | 99b169c4c1b9766509f4182e2ddc7ad92cf363e6 | |
| parent | b77334654027ef56583e257e26e6d8a6ed8f9830 (diff) | |
| download | linux-d1dbc59200b54944f00251ca4dfbb2b318beca13.tar.gz linux-d1dbc59200b54944f00251ca4dfbb2b318beca13.zip | |
fuse: wake one waiter per freed slot when raising max_background
fuse_get_req() parks background allocations on fch->blocked_waitq via
wait_event_state_exclusive(), so each wakeup releases exactly one
waiter. fuse_chan_max_background_set() clears fch->blocked when the
new limit exceeds num_background, but the accompanying wake_up()
releases a single waiter regardless of how many slots just became
available. Raising max_background from 10 to 100 therefore admits one
request instead of ninety.
The remaining waiters are not permanently stranded — the "else if
(!fch->blocked)" branch in fuse_request_end() wakes one more per
completion — but that only helps while requests keep completing.
Consider a fixed pool of threads doing readahead or async direct I/O
with the quota exhausted: every thread is either in flight or parked,
and each completion wakes one waiter while freeing one slot, a net
change of zero. num_background oscillates around the old limit and
the added quota is never taken up.
Waking one waiter per freed slot also preserves submission order:
once fch->blocked is clear, new callers of fuse_get_req() skip the
waitqueue entirely, overtaking waiters that parked before the limit
was raised.
Use wake_up_nr() with the number of slots that just became available.
Since the wakeup is guarded by !fch->blocked, num_background is
strictly below max_background, so the count is at least 1 and never
degenerates into wake_up_all().
Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
Reviewed-By: Horst Birthelmer <hbirthelmer@ddn.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
| -rw-r--r-- | fs/fuse/dev.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 3f498630f421..4fec31fc0b84 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -406,7 +406,8 @@ void fuse_chan_max_background_set(struct fuse_chan *fch, unsigned int val) fch->max_background = val; fch->blocked = fch->num_background >= fch->max_background; if (!fch->blocked) - wake_up(&fch->blocked_waitq); + wake_up_nr(&fch->blocked_waitq, + fch->max_background - fch->num_background); spin_unlock(&fch->bg_lock); } |
