This is a note to let you know that I've just added the patch titled SUNRPC: Fix a race between work-queue and rpc_killall_tasks
to the 2.6.33-longterm tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/longterm/longterm-queue-2.6.33.git;a=summary The filename of the patch is: sunrpc-fix-a-race-between-work-queue-and-rpc_killall_tasks.patch and it can be found in the queue-2.6.33 subdirectory. If you, or anyone else, feels it should not be added to the 2.6.33 longterm tree, please let <sta...@kernel.org> know about it. >From b55c59892e1f3b6c7d4b9ccffb4263e1486fb990 Mon Sep 17 00:00:00 2001 From: Trond Myklebust <trond.mykleb...@netapp.com> Date: Wed, 6 Jul 2011 19:58:23 -0400 Subject: SUNRPC: Fix a race between work-queue and rpc_killall_tasks From: Trond Myklebust <trond.mykleb...@netapp.com> commit b55c59892e1f3b6c7d4b9ccffb4263e1486fb990 upstream. Since rpc_killall_tasks may modify the rpc_task's tk_action field without any locking, we need to be careful when dereferencing it. Reported-by: Ben Greear <gree...@candelatech.com> Tested-by: Ben Greear <gree...@candelatech.com> Signed-off-by: Trond Myklebust <trond.mykleb...@netapp.com> Signed-off-by: Greg Kroah-Hartman <gre...@suse.de> --- net/sunrpc/sched.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -628,30 +628,25 @@ static void __rpc_execute(struct rpc_tas BUG_ON(RPC_IS_QUEUED(task)); for (;;) { + void (*do_action)(struct rpc_task *); /* - * Execute any pending callback. + * Execute any pending callback first. */ - if (task->tk_callback) { - void (*save_callback)(struct rpc_task *); - - /* - * We set tk_callback to NULL before calling it, - * in case it sets the tk_callback field itself: - */ - save_callback = task->tk_callback; - task->tk_callback = NULL; - save_callback(task); - } else { + do_action = task->tk_callback; + task->tk_callback = NULL; + if (do_action == NULL) { /* * Perform the next FSM step. - * tk_action may be NULL when the task has been killed - * by someone else. + * tk_action may be NULL if the task has been killed. + * In particular, note that rpc_killall_tasks may + * do this at any time, so beware when dereferencing. */ - if (task->tk_action == NULL) + do_action = task->tk_action; + if (do_action == NULL) break; - task->tk_action(task); } + do_action(task); /* * Lockless check for whether task is sleeping or not. Patches currently in longterm-queue-2.6.33 which might be from trond.mykleb...@netapp.com are /home/gregkh/linux/longterm/longterm-queue-2.6.33/queue-2.6.33/sunrpc-fix-use-of-static-variable-in-rpcb_getport_async.patch /home/gregkh/linux/longterm/longterm-queue-2.6.33/queue-2.6.33/sunrpc-fix-a-race-between-work-queue-and-rpc_killall_tasks.patch _______________________________________________ stable mailing list stable@linux.kernel.org http://linux.kernel.org/mailman/listinfo/stable