Skip to content

Commit 908a572

Browse files
author
Miklos Szeredi
committed
fuse: fix blocked_waitq wakeup
Using waitqueue_active() is racy. Make sure we issue a wake_up() unconditionally after storing into fc->blocked. After that it's okay to optimize with waitqueue_active() since the first wake up provides the necessary barrier for all waiters, not the just the woken one. Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> Fixes: 3c18ef8 ("fuse: optimize wake_up") Cc: <stable@vger.kernel.org> # v3.10
1 parent 4c316f2 commit 908a572

File tree

1 file changed

+11
-4
lines changed

1 file changed

+11
-4
lines changed

fs/fuse/dev.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -391,12 +391,19 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
391391
if (test_bit(FR_BACKGROUND, &req->flags)) {
392392
spin_lock(&fc->lock);
393393
clear_bit(FR_BACKGROUND, &req->flags);
394-
if (fc->num_background == fc->max_background)
394+
if (fc->num_background == fc->max_background) {
395395
fc->blocked = 0;
396-
397-
/* Wake up next waiter, if any */
398-
if (!fc->blocked && waitqueue_active(&fc->blocked_waitq))
399396
wake_up(&fc->blocked_waitq);
397+
} else if (!fc->blocked) {
398+
/*
399+
* Wake up next waiter, if any. It's okay to use
400+
* waitqueue_active(), as we've already synced up
401+
* fc->blocked with waiters with the wake_up() call
402+
* above.
403+
*/
404+
if (waitqueue_active(&fc->blocked_waitq))
405+
wake_up(&fc->blocked_waitq);
406+
}
400407

401408
if (fc->num_background == fc->congestion_threshold && fc->sb) {
402409
clear_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC);

0 commit comments

Comments
 (0)