diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-02-22 22:29:55 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-02-22 22:29:55 +0100 |
commit | 7c70f3a7488d2fa62d32849d138bf2b8420fe788 (patch) | |
tree | 2680c1fdf75458f9fff9c36e38612b167803f50f /net | |
parent | Merge tag 'ceph-for-5.12-rc1' of git://github.com/ceph/ceph-client (diff) | |
parent | SUNRPC: Further clean up svc_tcp_sendmsg() (diff) | |
download | linux-7c70f3a7488d2fa62d32849d138bf2b8420fe788.tar.xz linux-7c70f3a7488d2fa62d32849d138bf2b8420fe788.zip |
Merge tag 'nfsd-5.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux
Pull more nfsd updates from Chuck Lever:
"Here are a few additional NFSD commits for the merge window:
Optimization:
- Cork the socket while there are queued replies
Fixes:
- DRC shutdown ordering
- svc_rdma_accept() lockdep splat"
* tag 'nfsd-5.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux:
SUNRPC: Further clean up svc_tcp_sendmsg()
SUNRPC: Remove redundant socket flags from svc_tcp_sendmsg()
SUNRPC: Use TCP_CORK to optimise send performance on the server
svcrdma: Hold private mutex while invoking rdma_accept()
nfsd: register pernet ops last, unregister first
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/svcsock.c | 35 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/svc_rdma_transport.c | 6 |
2 files changed, 20 insertions, 21 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 5a809c64dc7b..2e2f007dfc9f 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -1078,9 +1078,8 @@ static int svc_tcp_send_kvec(struct socket *sock, const struct kvec *vec, * In addition, the logic assumes that * .bv_len is never larger * than PAGE_SIZE. */ -static int svc_tcp_sendmsg(struct socket *sock, struct msghdr *msg, - struct xdr_buf *xdr, rpc_fraghdr marker, - unsigned int *sentp) +static int svc_tcp_sendmsg(struct socket *sock, struct xdr_buf *xdr, + rpc_fraghdr marker, unsigned int *sentp) { const struct kvec *head = xdr->head; const struct kvec *tail = xdr->tail; @@ -1088,21 +1087,22 @@ static int svc_tcp_sendmsg(struct socket *sock, struct msghdr *msg, .iov_base = &marker, .iov_len = sizeof(marker), }; - int flags, ret; + struct msghdr msg = { + .msg_flags = 0, + }; + int ret; *sentp = 0; xdr_alloc_bvec(xdr, GFP_KERNEL); - msg->msg_flags = MSG_MORE; - ret = kernel_sendmsg(sock, msg, &rm, 1, rm.iov_len); + ret = kernel_sendmsg(sock, &msg, &rm, 1, rm.iov_len); if (ret < 0) return ret; *sentp += ret; if (ret != rm.iov_len) return -EAGAIN; - flags = head->iov_len < xdr->len ? MSG_MORE | MSG_SENDPAGE_NOTLAST : 0; - ret = svc_tcp_send_kvec(sock, head, flags); + ret = svc_tcp_send_kvec(sock, head, 0); if (ret < 0) return ret; *sentp += ret; @@ -1116,15 +1116,11 @@ static int svc_tcp_sendmsg(struct socket *sock, struct msghdr *msg, bvec = xdr->bvec + (xdr->page_base >> PAGE_SHIFT); offset = offset_in_page(xdr->page_base); remaining = xdr->page_len; - flags = MSG_MORE | MSG_SENDPAGE_NOTLAST; while (remaining > 0) { - if (remaining <= PAGE_SIZE && tail->iov_len == 0) - flags = 0; - len = min(remaining, bvec->bv_len - offset); ret = kernel_sendpage(sock, bvec->bv_page, bvec->bv_offset + offset, - len, flags); + len, 0); if (ret < 0) return ret; *sentp += ret; @@ -1163,26 +1159,28 @@ static int svc_tcp_sendto(struct svc_rqst *rqstp) struct xdr_buf *xdr = &rqstp->rq_res; rpc_fraghdr marker = cpu_to_be32(RPC_LAST_STREAM_FRAGMENT | (u32)xdr->len); - struct msghdr msg = { - .msg_flags = 0, - }; unsigned int sent; int err; svc_tcp_release_rqst(rqstp); + atomic_inc(&svsk->sk_sendqlen); mutex_lock(&xprt->xpt_mutex); if (svc_xprt_is_dead(xprt)) goto out_notconn; - err = svc_tcp_sendmsg(svsk->sk_sock, &msg, xdr, marker, &sent); + tcp_sock_set_cork(svsk->sk_sk, true); + err = svc_tcp_sendmsg(svsk->sk_sock, xdr, marker, &sent); xdr_free_bvec(xdr); trace_svcsock_tcp_send(xprt, err < 0 ? err : sent); if (err < 0 || sent != (xdr->len + sizeof(marker))) goto out_close; + if (atomic_dec_and_test(&svsk->sk_sendqlen)) + tcp_sock_set_cork(svsk->sk_sk, false); mutex_unlock(&xprt->xpt_mutex); return sent; out_notconn: + atomic_dec(&svsk->sk_sendqlen); mutex_unlock(&xprt->xpt_mutex); return -ENOTCONN; out_close: @@ -1192,6 +1190,7 @@ out_close: (err < 0) ? err : sent, xdr->len); set_bit(XPT_CLOSE, &xprt->xpt_flags); svc_xprt_enqueue(xprt); + atomic_dec(&svsk->sk_sendqlen); mutex_unlock(&xprt->xpt_mutex); return -EAGAIN; } @@ -1261,7 +1260,7 @@ static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv) svsk->sk_datalen = 0; memset(&svsk->sk_pages[0], 0, sizeof(svsk->sk_pages)); - tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF; + tcp_sock_set_nodelay(sk); set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); switch (sk->sk_state) { diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c index afba4e9d5425..c895f80df659 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c @@ -475,9 +475,6 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt) if (!svc_rdma_post_recvs(newxprt)) goto errout; - /* Swap out the handler */ - newxprt->sc_cm_id->event_handler = svc_rdma_cma_handler; - /* Construct RDMA-CM private message */ pmsg.cp_magic = rpcrdma_cmp_magic; pmsg.cp_version = RPCRDMA_CMP_VERSION; @@ -498,7 +495,10 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt) } conn_param.private_data = &pmsg; conn_param.private_data_len = sizeof(pmsg); + rdma_lock_handler(newxprt->sc_cm_id); + newxprt->sc_cm_id->event_handler = svc_rdma_cma_handler; ret = rdma_accept(newxprt->sc_cm_id, &conn_param); + rdma_unlock_handler(newxprt->sc_cm_id); if (ret) { trace_svcrdma_accept_err(newxprt, ret); goto errout; |