aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2015-10-08 21:44:07 -0400
committerJ. Bruce Fields <bfields@redhat.com>2015-11-10 17:02:47 -0500
commit0442f14b15f8e7a8b3778a9f8cf640ef89b2df26 (patch)
treedd7cae613d5d154bd945b9c140d4764074bbbe08
parent7fc0564e3a8d16df096f48c9c6425ba84d945c6e (diff)
svcrpc: document lack of some memory barriers
We're missing memory barriers in net/sunrpc/svcsock.c in some spots we'd expect them. But it doesn't appear they're necessary in our case, and this is likely a hot path--for now just document the odd behavior. Kosuke Tatsukawa found this issue while looking through the linux source code for places calling waitqueue_active() before wake_up*(), but without preceding memory barriers, after sending a patch to fix a similar issue in drivers/tty/n_tty.c (Details about the original issue can be found here: https://lkml.org/lkml/2015/9/28/849). Reported-by: Kosuke Tatsukawa <tatsu@ab.jp.nec.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r--net/sunrpc/svcsock.c37
1 files changed, 31 insertions, 6 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index e0c7b3355495..1413cdcc131c 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -399,6 +399,31 @@ static int svc_sock_secure_port(struct svc_rqst *rqstp)
399 return svc_port_is_privileged(svc_addr(rqstp)); 399 return svc_port_is_privileged(svc_addr(rqstp));
400} 400}
401 401
402static bool sunrpc_waitqueue_active(wait_queue_head_t *wq)
403{
404 if (!wq)
405 return false;
406 /*
407 * There should normally be a memory * barrier here--see
408 * wq_has_sleeper().
409 *
410 * It appears that isn't currently necessary, though, basically
411 * because callers all appear to have sufficient memory barriers
412 * between the time the relevant change is made and the
413 * time they call these callbacks.
414 *
415 * The nfsd code itself doesn't actually explicitly wait on
416 * these waitqueues, but it may wait on them for example in
417 * sendpage() or sendmsg() calls. (And those may be the only
418 * places, since it it uses nonblocking reads.)
419 *
420 * Maybe we should add the memory barriers anyway, but these are
421 * hot paths so we'd need to be convinced there's no sigificant
422 * penalty.
423 */
424 return waitqueue_active(wq);
425}
426
402/* 427/*
403 * INET callback when data has been received on the socket. 428 * INET callback when data has been received on the socket.
404 */ 429 */
@@ -414,7 +439,7 @@ static void svc_udp_data_ready(struct sock *sk)
414 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); 439 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
415 svc_xprt_enqueue(&svsk->sk_xprt); 440 svc_xprt_enqueue(&svsk->sk_xprt);
416 } 441 }
417 if (wq && waitqueue_active(wq)) 442 if (sunrpc_waitqueue_active(wq))
418 wake_up_interruptible(wq); 443 wake_up_interruptible(wq);
419} 444}
420 445
@@ -432,7 +457,7 @@ static void svc_write_space(struct sock *sk)
432 svc_xprt_enqueue(&svsk->sk_xprt); 457 svc_xprt_enqueue(&svsk->sk_xprt);
433 } 458 }
434 459
435 if (wq && waitqueue_active(wq)) { 460 if (sunrpc_waitqueue_active(wq)) {
436 dprintk("RPC svc_write_space: someone sleeping on %p\n", 461 dprintk("RPC svc_write_space: someone sleeping on %p\n",
437 svsk); 462 svsk);
438 wake_up_interruptible(wq); 463 wake_up_interruptible(wq);
@@ -787,7 +812,7 @@ static void svc_tcp_listen_data_ready(struct sock *sk)
787 } 812 }
788 813
789 wq = sk_sleep(sk); 814 wq = sk_sleep(sk);
790 if (wq && waitqueue_active(wq)) 815 if (sunrpc_waitqueue_active(wq))
791 wake_up_interruptible_all(wq); 816 wake_up_interruptible_all(wq);
792} 817}
793 818
@@ -808,7 +833,7 @@ static void svc_tcp_state_change(struct sock *sk)
808 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); 833 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
809 svc_xprt_enqueue(&svsk->sk_xprt); 834 svc_xprt_enqueue(&svsk->sk_xprt);
810 } 835 }
811 if (wq && waitqueue_active(wq)) 836 if (sunrpc_waitqueue_active(wq))
812 wake_up_interruptible_all(wq); 837 wake_up_interruptible_all(wq);
813} 838}
814 839
@@ -823,7 +848,7 @@ static void svc_tcp_data_ready(struct sock *sk)
823 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); 848 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
824 svc_xprt_enqueue(&svsk->sk_xprt); 849 svc_xprt_enqueue(&svsk->sk_xprt);
825 } 850 }
826 if (wq && waitqueue_active(wq)) 851 if (sunrpc_waitqueue_active(wq))
827 wake_up_interruptible(wq); 852 wake_up_interruptible(wq);
828} 853}
829 854
@@ -1593,7 +1618,7 @@ static void svc_sock_detach(struct svc_xprt *xprt)
1593 sk->sk_write_space = svsk->sk_owspace; 1618 sk->sk_write_space = svsk->sk_owspace;
1594 1619
1595 wq = sk_sleep(sk); 1620 wq = sk_sleep(sk);
1596 if (wq && waitqueue_active(wq)) 1621 if (sunrpc_waitqueue_active(wq))
1597 wake_up_interruptible(wq); 1622 wake_up_interruptible(wq);
1598} 1623}
1599 1624