This is a note to let you know that I've just added the patch titled

    RPC: killing RPC tasks races fixed

to the 2.6.38-stable tree which can be found at:
    
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     rpc-killing-rpc-tasks-races-fixed.patch
and it can be found in the queue-2.6.38 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <[email protected]> know about it.


>From 8e26de238fd794c8ea56a5c98bf67c40cfeb051d Mon Sep 17 00:00:00 2001
From: Stanislav Kinsbursky <[email protected]>
Date: Thu, 17 Mar 2011 18:54:23 +0300
Subject: RPC: killing RPC tasks races fixed

From: Stanislav Kinsbursky <[email protected]>

commit 8e26de238fd794c8ea56a5c98bf67c40cfeb051d upstream.

RPC task RPC_TASK_QUEUED bit is set must be checked before trying to wake up
task rpc_killall_tasks() because task->tk_waitqueue can not be set (equal to
NULL).
Also, as Trond Myklebust mentioned, such approach (instead of checking
tk_waitqueue to NULL) allows us to "optimise away the call to
rpc_wake_up_queued_task() altogether for those
tasks that aren't queued".

Here is an example of dereferencing of tk_waitqueue equal to NULL:

CPU 0                   CPU 1                           CPU 2
--------------------    ---------------------   --------------------------
nfs4_run_open_task
rpc_run_task
rpc_execute
rpc_set_active
rpc_make_runnable
(waiting)
                        rpc_async_schedule
                        nfs4_open_prepare
                        nfs_wait_on_sequence
                                                nfs_umount_begin
                                                rpc_killall_tasks
                                                rpc_wake_up_task
                                                rpc_wake_up_queued_task
                                                spin_lock(tk_waitqueue == NULL)
                                                BUG()
                        rpc_sleep_on
                        spin_lock(&q->lock)
                        __rpc_sleep_on
                        task->tk_waitqueue = q

Signed-off-by: Stanislav Kinsbursky <[email protected]>
Signed-off-by: Trond Myklebust <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
 net/sunrpc/clnt.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -436,7 +436,9 @@ void rpc_killall_tasks(struct rpc_clnt *
                if (!(rovr->tk_flags & RPC_TASK_KILLED)) {
                        rovr->tk_flags |= RPC_TASK_KILLED;
                        rpc_exit(rovr, -EIO);
-                       rpc_wake_up_queued_task(rovr->tk_waitqueue, rovr);
+                       if (RPC_IS_QUEUED(rovr))
+                               rpc_wake_up_queued_task(rovr->tk_waitqueue,
+                                                       rovr);
                }
        }
        spin_unlock(&clnt->cl_lock);


Patches currently in stable-queue which might be from [email protected] 
are

queue-2.6.38/rpc-killing-rpc-tasks-races-fixed.patch

_______________________________________________
stable mailing list
[email protected]
http://linux.kernel.org/mailman/listinfo/stable

Reply via email to