--- /dev/null
+From 1166fde6a923c30f4351515b6a9a1efc513e7d00 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+Date: Mon, 25 Mar 2013 11:23:40 -0400
+Subject: SUNRPC: Add barriers to ensure read ordering in rpc_wake_up_task_queue_locked
+
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+
+commit 1166fde6a923c30f4351515b6a9a1efc513e7d00 upstream.
+
+We need to be careful when testing task->tk_waitqueue in
+rpc_wake_up_task_queue_locked, because it can be changed while we
+are holding the queue->lock.
+By adding appropriate memory barriers, we can ensure that it is safe to
+test task->tk_waitqueue for equality if the RPC_TASK_QUEUED bit is set.
+
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/sunrpc/sched.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/net/sunrpc/sched.c
++++ b/net/sunrpc/sched.c
+@@ -135,6 +135,8 @@ static void __rpc_add_wait_queue(struct
+ list_add_tail(&task->u.tk_wait.list, &queue->tasks[0]);
+ task->tk_waitqueue = queue;
+ queue->qlen++;
++ /* barrier matches the read in rpc_wake_up_task_queue_locked() */
++ smp_wmb();
+ rpc_set_queued(task);
+
+ dprintk("RPC: %5u added to queue %p \"%s\"\n",
+@@ -369,8 +371,11 @@ static void __rpc_do_wake_up_task(struct
+ */
+ static void rpc_wake_up_task_queue_locked(struct rpc_wait_queue *queue, struct rpc_task *task)
+ {
+- if (RPC_IS_QUEUED(task) && task->tk_waitqueue == queue)
+- __rpc_do_wake_up_task(queue, task);
++ if (RPC_IS_QUEUED(task)) {
++ smp_rmb();
++ if (task->tk_waitqueue == queue)
++ __rpc_do_wake_up_task(queue, task);
++ }
+ }
+
+ /*