diff options
Diffstat (limited to 'fs/btrfs/async-thread.c')
| -rw-r--r-- | fs/btrfs/async-thread.c | 14 | 
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 { |