io_uring: ensure RCU callback ordering with rcu_barrier()
authorJens Axboe <axboe@kernel.dk>
Mon, 9 Mar 2020 02:07:28 +0000 (20:07 -0600)
committerJens Axboe <axboe@kernel.dk>
Mon, 9 Mar 2020 02:07:28 +0000 (20:07 -0600)
commit805b13adde3964c78cba125a15527e88c19f87b3
treec79c1839ac977bc84f7b8f6bed0038bf3f95b8e2
parentf0e20b8943509d81200cef5e30af2adfddba0f5c
io_uring: ensure RCU callback ordering with rcu_barrier()

After more careful studying, Paul informs me that we cannot rely on
ordering of RCU callbacks in the way that the the tagged commit did.
The current construct looks like this:

void C(struct rcu_head *rhp)
{
do_something(rhp);
call_rcu(&p->rh, B);
}

call_rcu(&p->rh, A);
call_rcu(&p->rh, C);

and we're relying on ordering between A and B, which isn't guaranteed.
Make this explicit instead, and have a work item issue the rcu_barrier()
to ensure that A has run before we manually execute B.

While thorough testing never showed this issue, it's dependent on the
per-cpu load in terms of RCU callbacks. The updated method simplifies
the code as well, and eliminates the need to maintain an rcu_head in
the fileset data.

Fixes: c1e2148f8ecb ("io_uring: free fixed_file_data after RCU grace period")
Reported-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
fs/io_uring.c