Commit 43ac3f2961b8616da26114ec6dc76ac2a61f76ad
1 parent
c42de9dd67
Exists in
master
and in
7 other branches
SUNRPC: Fix memory barriers for req->rq_received
We need to ensure that all writes to the XDR buffers are done before req->rq_received is visible to other processors. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Showing 2 changed files with 7 additions and 1 deletions Side-by-side Diff
net/sunrpc/clnt.c
... | ... | @@ -1069,6 +1069,11 @@ |
1069 | 1069 | return; |
1070 | 1070 | } |
1071 | 1071 | |
1072 | + /* | |
1073 | + * Ensure that we see all writes made by xprt_complete_rqst() | |
1074 | + * before it changed req->rq_received. | |
1075 | + */ | |
1076 | + smp_rmb(); | |
1072 | 1077 | req->rq_rcv_buf.len = req->rq_private_buf.len; |
1073 | 1078 | |
1074 | 1079 | /* Check that the softirq receive buffer is valid */ |
net/sunrpc/xprt.c
... | ... | @@ -651,6 +651,8 @@ |
651 | 651 | task->tk_rtt = (long)jiffies - req->rq_xtime; |
652 | 652 | |
653 | 653 | list_del_init(&req->rq_list); |
654 | + /* Ensure all writes are done before we update req->rq_received */ | |
655 | + smp_wmb(); | |
654 | 656 | req->rq_received = req->rq_private_buf.len = copied; |
655 | 657 | rpc_wake_up_task(task); |
656 | 658 | } |
... | ... | @@ -727,7 +729,6 @@ |
727 | 729 | |
728 | 730 | dprintk("RPC: %4d xprt_transmit(%u)\n", task->tk_pid, req->rq_slen); |
729 | 731 | |
730 | - smp_rmb(); | |
731 | 732 | if (!req->rq_received) { |
732 | 733 | if (list_empty(&req->rq_list)) { |
733 | 734 | spin_lock_bh(&xprt->transport_lock); |