summaryrefslogtreecommitdiff
path: root/fs/btrfs/async-thread.c
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2021-11-27 00:54:16 +0100
committerLinus Walleij <linus.walleij@linaro.org>2021-11-27 00:54:16 +0100
commit2448eab44034d9603c97ca17760a53d4d6e4b60c (patch)
tree7f323cea55258e94e0c7c70b63d02c9effb00c1f /fs/btrfs/async-thread.c
parentdeee705a1c9cce9c7eb699d529f1c0b3c80d339d (diff)
parent136057256686de39cc3a07c2e39ef6bc43003ff6 (diff)
Merge tag 'v5.16-rc2' into devel
Linux 5.16-rc2 is needed because nonurgent fixes headed for next are strongly textually dependent on a fix that was applied for rc2. Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'fs/btrfs/async-thread.c')
-rw-r--r--fs/btrfs/async-thread.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c
index 309516e6a968..43c89952b7d2 100644
--- a/fs/btrfs/async-thread.c
+++ b/fs/btrfs/async-thread.c
@@ -234,6 +234,13 @@ static void run_ordered_work(struct __btrfs_workqueue *wq,
ordered_list);
if (!test_bit(WORK_DONE_BIT, &work->flags))
break;
+ /*
+ * Orders all subsequent loads after reading WORK_DONE_BIT,
+ * paired with the smp_mb__before_atomic in btrfs_work_helper
+ * this guarantees that the ordered function will see all
+ * updates from ordinary work function.
+ */
+ smp_rmb();
/*
* we are going to call the ordered done function, but
@@ -317,6 +324,13 @@ static void btrfs_work_helper(struct work_struct *normal_work)
thresh_exec_hook(wq);
work->func(work);
if (need_order) {
+ /*
+ * Ensures all memory accesses done in the work function are
+ * ordered before setting the WORK_DONE_BIT. Ensuring the thread
+ * which is going to executed the ordered work sees them.
+ * Pairs with the smp_rmb in run_ordered_work.
+ */
+ smp_mb__before_atomic();
set_bit(WORK_DONE_BIT, &work->flags);
run_ordered_work(wq, work);
} else {