Stanislav Kinsbursky 8e26de238f RPC: killing RPC tasks races fixed
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 <skinsbursky@openvz.org>
Cc: stable@kernel.org
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
2011-03-17 12:39:00 -04:00
..
2011-01-11 09:58:07 -06:00
2010-10-25 13:09:44 -07:00
2011-03-04 12:25:05 -08:00
2011-02-25 13:58:54 -08:00
2011-03-01 23:02:07 -08:00
2011-01-27 14:15:54 -08:00
2011-01-12 19:00:40 -08:00
2011-02-21 11:31:18 -08:00
2010-10-21 15:44:13 +02:00
2010-09-23 14:33:39 -07:00
2010-12-19 21:59:35 -08:00
2011-01-10 13:33:17 -08:00
2011-03-17 12:39:00 -04:00
2011-02-09 22:36:13 -08:00
2010-12-16 13:44:24 -08:00
2010-10-15 15:53:27 +02:00