diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-03-18 07:52:21 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-03-25 08:25:41 +0100 |
commit | f9f635c04769bae7014e2ff3f86f9c4f1d4d184c (patch) | |
tree | 2931d7930c8c9a7e07e81404cc5966ad620bd8e3 /fs/cifs/file.c | |
parent | 384e15fc4226551a45b54226dc57bca7e23db9d8 (diff) |
locks: reinstate locks_delete_block optimization
[ Upstream commit dcf23ac3e846ca0cf626c155a0e3fcbbcf4fae8a ]
There is measurable performance impact in some synthetic tests due to
commit 6d390e4b5d48 (locks: fix a potential use-after-free problem when
wakeup a waiter). Fix the race condition instead by clearing the
fl_blocker pointer after the wake_up, using explicit acquire/release
semantics.
This does mean that we can no longer use the clearing of fl_blocker as
the wait condition, so switch the waiters over to checking whether the
fl_blocked_member list_head is empty.
Reviewed-by: yangerkun <yangerkun@huawei.com>
Reviewed-by: NeilBrown <neilb@suse.de>
Fixes: 6d390e4b5d48 (locks: fix a potential use-after-free problem when wakeup a waiter)
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r-- | fs/cifs/file.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 0dbe47e89720..35c55cf38a35 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1173,7 +1173,8 @@ try_again: rc = posix_lock_file(file, flock, NULL); up_write(&cinode->lock_sem); if (rc == FILE_LOCK_DEFERRED) { - rc = wait_event_interruptible(flock->fl_wait, !flock->fl_blocker); + rc = wait_event_interruptible(flock->fl_wait, + list_empty(&flock->fl_blocked_member)); if (!rc) goto try_again; locks_delete_block(flock); |