diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-05-20 23:00:18 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-06-06 16:24:38 -0400 |
commit | a76580fbf09e6e19c2040c08969af5137e064eda (patch) | |
tree | efd3497a42cbf571916ac57037b3b326bbf1fa25 | |
parent | 5cc2216db844beac6ce78c3e48137cd58911b297 (diff) | |
download | op-kernel-dev-a76580fbf09e6e19c2040c08969af5137e064eda.zip op-kernel-dev-a76580fbf09e6e19c2040c08969af5137e064eda.tar.gz |
SUNRPC: Fix a potential race in rpc_execute
If the rpc_task is asynchronous, it could theoretically finish executing
on the workqueue it was assigned by rpc_make_runnable() before we get
round to testing RPC_IS_ASYNC() in rpc_execute.
In practice, however, all the existing callers hold a reference to the
rpc_task, so this can't happen today...
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | net/sunrpc/sched.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 5356b12..849ca41 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -825,9 +825,11 @@ static void __rpc_execute(struct rpc_task *task) */ void rpc_execute(struct rpc_task *task) { + bool is_async = RPC_IS_ASYNC(task); + rpc_set_active(task); rpc_make_runnable(task); - if (!RPC_IS_ASYNC(task)) + if (!is_async) __rpc_execute(task); } |