These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / net / sunrpc / svcsock.c
index 0c81202..1413cdc 100644 (file)
@@ -181,7 +181,7 @@ int svc_send_common(struct socket *sock, struct xdr_buf *xdr,
        struct page     **ppage = xdr->pages;
        size_t          base = xdr->page_base;
        unsigned int    pglen = xdr->page_len;
-       unsigned int    flags = MSG_MORE;
+       unsigned int    flags = MSG_MORE | MSG_SENDPAGE_NOTLAST;
        int             slen;
        int             len = 0;
 
@@ -399,6 +399,31 @@ static int svc_sock_secure_port(struct svc_rqst *rqstp)
        return svc_port_is_privileged(svc_addr(rqstp));
 }
 
+static bool sunrpc_waitqueue_active(wait_queue_head_t *wq)
+{
+       if (!wq)
+               return false;
+       /*
+        * There should normally be a memory * barrier here--see
+        * wq_has_sleeper().
+        *
+        * It appears that isn't currently necessary, though, basically
+        * because callers all appear to have sufficient memory barriers
+        * between the time the relevant change is made and the
+        * time they call these callbacks.
+        *
+        * The nfsd code itself doesn't actually explicitly wait on
+        * these waitqueues, but it may wait on them for example in
+        * sendpage() or sendmsg() calls.  (And those may be the only
+        * places, since it it uses nonblocking reads.)
+        *
+        * Maybe we should add the memory barriers anyway, but these are
+        * hot paths so we'd need to be convinced there's no sigificant
+        * penalty.
+        */
+       return waitqueue_active(wq);
+}
+
 /*
  * INET callback when data has been received on the socket.
  */
@@ -414,7 +439,7 @@ static void svc_udp_data_ready(struct sock *sk)
                set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
                svc_xprt_enqueue(&svsk->sk_xprt);
        }
-       if (wq && waitqueue_active(wq))
+       if (sunrpc_waitqueue_active(wq))
                wake_up_interruptible(wq);
 }
 
@@ -432,7 +457,7 @@ static void svc_write_space(struct sock *sk)
                svc_xprt_enqueue(&svsk->sk_xprt);
        }
 
-       if (wq && waitqueue_active(wq)) {
+       if (sunrpc_waitqueue_active(wq)) {
                dprintk("RPC svc_write_space: someone sleeping on %p\n",
                       svsk);
                wake_up_interruptible(wq);
@@ -787,7 +812,7 @@ static void svc_tcp_listen_data_ready(struct sock *sk)
        }
 
        wq = sk_sleep(sk);
-       if (wq && waitqueue_active(wq))
+       if (sunrpc_waitqueue_active(wq))
                wake_up_interruptible_all(wq);
 }
 
@@ -808,7 +833,7 @@ static void svc_tcp_state_change(struct sock *sk)
                set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
                svc_xprt_enqueue(&svsk->sk_xprt);
        }
-       if (wq && waitqueue_active(wq))
+       if (sunrpc_waitqueue_active(wq))
                wake_up_interruptible_all(wq);
 }
 
@@ -823,7 +848,7 @@ static void svc_tcp_data_ready(struct sock *sk)
                set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
                svc_xprt_enqueue(&svsk->sk_xprt);
        }
-       if (wq && waitqueue_active(wq))
+       if (sunrpc_waitqueue_active(wq))
                wake_up_interruptible(wq);
 }
 
@@ -1367,7 +1392,6 @@ EXPORT_SYMBOL_GPL(svc_sock_update_bufs);
 
 /*
  * Initialize socket for RPC use and create svc_sock struct
- * XXX: May want to setsockopt SO_SNDBUF and SO_RCVBUF.
  */
 static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
                                                struct socket *sock,
@@ -1594,7 +1618,7 @@ static void svc_sock_detach(struct svc_xprt *xprt)
        sk->sk_write_space = svsk->sk_owspace;
 
        wq = sk_sleep(sk);
-       if (wq && waitqueue_active(wq))
+       if (sunrpc_waitqueue_active(wq))
                wake_up_interruptible(wq);
 }