FAILED: patch "[PATCH] fuse: fix blocked_waitq wakeup" failed to apply to 3.18-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 3.18-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
Quoted 1 line
From
908a572b80f6e9577b45e81b3dfe2e22111286b8Mon Sep 17 00:00:00 2001
From: Miklos Szeredi <[email protected]>
Date: Fri, 28 Sep 2018 16:43:22 +0200
Subject: [PATCH] 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.
fs/fuse/dev.c +11 -4
@@ -391,12 +391,19 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)if (test_bit (FR_BACKGROUND , &req->flags)) {spin_lock (&fc->lock);clear_bit (FR_BACKGROUND , &req->flags); -if (fc->num_background == fc->max_background) +if (fc->num_background == fc->max_background) { fc->blocked =0 ; - -/* Wake up next waiter, if any */ -if (!fc->blocked &&waitqueue_active (&fc->blocked_waitq))wake_up (&fc->blocked_waitq); + }else if (!fc->blocked) { +/* +* Wake up next waiter, if any. It's okay to use +* waitqueue_active(), as we've already synced up +* fc->blocked with waiters with the wake_up() call +* above. +*/ +if (waitqueue_active (&fc->blocked_waitq)) +wake_up (&fc->blocked_waitq); + }if (fc->num_background == fc->congestion_threshold && fc->sb) {clear_bdi_congested (fc->sb->s_bdi,BLK_RW_SYNC );