summaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2013-05-20 23:00:18 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2013-06-06 16:24:38 -0400
commita76580fbf09e6e19c2040c08969af5137e064eda (patch)
treeefd3497a42cbf571916ac57037b3b326bbf1fa25 /net/sunrpc
parent5cc2216db844beac6ce78c3e48137cd58911b297 (diff)
downloadlinux-a76580fbf09e6e19c2040c08969af5137e064eda.tar.gz
linux-a76580fbf09e6e19c2040c08969af5137e064eda.tar.bz2
linux-a76580fbf09e6e19c2040c08969af5137e064eda.zip
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>
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/sched.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 5356b120dbf8..849ca413522c 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);
}