diff options
author | Trond Myklebust <trond.myklebust@hammerspace.com> | 2019-02-25 08:39:26 -0500 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@hammerspace.com> | 2019-02-25 09:35:49 -0500 |
commit | 06b5fc3ad94eebf25d5abc07f84e16b8b33dcf8c (patch) | |
tree | e96f320b5e934978571c8b7d9553ef10fc87b149 /net/sunrpc/xprtsock.c | |
parent | 5085607d209102b37b169bc94d0aa39566a9842a (diff) | |
parent | 2c94b8eca1a26cd46010d6e73a23da5f2e93a19d (diff) |
Merge tag 'nfs-rdma-for-5.1-1' of git://git.linux-nfs.org/projects/anna/linux-nfs
NFSoRDMA client updates for 5.1
New features:
- Convert rpc auth layer to use xdr_streams
- Config option to disable insecure enctypes
- Reduce size of RPC receive buffers
Bugfixes and cleanups:
- Fix sparse warnings
- Check inline size before providing a write chunk
- Reduce the receive doorbell rate
- Various tracepoint improvements
[Trond: Fix up merge conflicts]
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Diffstat (limited to 'net/sunrpc/xprtsock.c')
-rw-r--r-- | net/sunrpc/xprtsock.c | 99 |
1 files changed, 67 insertions, 32 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 8fa74c8a4fd8..53de72d2dded 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -769,6 +769,29 @@ static int xs_send_pagedata(struct socket *sock, struct msghdr *msg, struct xdr_ | |||
769 | return xs_sendmsg(sock, msg, base + xdr->page_base); | 769 | return xs_sendmsg(sock, msg, base + xdr->page_base); |
770 | } | 770 | } |
771 | 771 | ||
772 | #define xs_record_marker_len() sizeof(rpc_fraghdr) | ||
773 | |||
774 | /* Common case: | ||
775 | * - stream transport | ||
776 | * - sending from byte 0 of the message | ||
777 | * - the message is wholly contained in @xdr's head iovec | ||
778 | */ | ||
779 | static int xs_send_rm_and_kvec(struct socket *sock, struct msghdr *msg, | ||
780 | rpc_fraghdr marker, struct kvec *vec, size_t base) | ||
781 | { | ||
782 | struct kvec iov[2] = { | ||
783 | [0] = { | ||
784 | .iov_base = &marker, | ||
785 | .iov_len = sizeof(marker) | ||
786 | }, | ||
787 | [1] = *vec, | ||
788 | }; | ||
789 | size_t len = iov[0].iov_len + iov[1].iov_len; | ||
790 | |||
791 | iov_iter_kvec(&msg->msg_iter, WRITE, iov, 2, len); | ||
792 | return xs_sendmsg(sock, msg, base); | ||
793 | } | ||
794 | |||
772 | /** | 795 | /** |
773 | * xs_sendpages - write pages directly to a socket | 796 | * xs_sendpages - write pages directly to a socket |
774 | * @sock: socket to send on | 797 | * @sock: socket to send on |
@@ -776,34 +799,42 @@ static int xs_send_pagedata(struct socket *sock, struct msghdr *msg, struct xdr_ | |||
776 | * @addrlen: UDP only -- length of destination address | 799 | * @addrlen: UDP only -- length of destination address |
777 | * @xdr: buffer containing this request | 800 | * @xdr: buffer containing this request |
778 | * @base: starting position in the buffer | 801 | * @base: starting position in the buffer |
802 | * @rm: stream record marker field | ||
779 | * @sent_p: return the total number of bytes successfully queued for sending | 803 | * @sent_p: return the total number of bytes successfully queued for sending |
780 | * | 804 | * |
781 | */ | 805 | */ |
782 | static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base, int *sent_p) | 806 | static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base, rpc_fraghdr rm, int *sent_p) |
783 | { | 807 | { |
784 | struct msghdr msg = { | 808 | struct msghdr msg = { |
785 | .msg_name = addr, | 809 | .msg_name = addr, |
786 | .msg_namelen = addrlen, | 810 | .msg_namelen = addrlen, |
787 | .msg_flags = XS_SENDMSG_FLAGS | MSG_MORE, | 811 | .msg_flags = XS_SENDMSG_FLAGS | MSG_MORE, |
788 | }; | 812 | }; |
789 | unsigned int remainder = xdr->len - base; | 813 | unsigned int rmsize = rm ? sizeof(rm) : 0; |
814 | unsigned int remainder = rmsize + xdr->len - base; | ||
815 | unsigned int want; | ||
790 | int err = 0; | 816 | int err = 0; |
791 | 817 | ||
792 | if (unlikely(!sock)) | 818 | if (unlikely(!sock)) |
793 | return -ENOTSOCK; | 819 | return -ENOTSOCK; |
794 | 820 | ||
795 | if (base < xdr->head[0].iov_len) { | 821 | want = xdr->head[0].iov_len + rmsize; |
796 | unsigned int len = xdr->head[0].iov_len - base; | 822 | if (base < want) { |
823 | unsigned int len = want - base; | ||
797 | remainder -= len; | 824 | remainder -= len; |
798 | if (remainder == 0) | 825 | if (remainder == 0) |
799 | msg.msg_flags &= ~MSG_MORE; | 826 | msg.msg_flags &= ~MSG_MORE; |
800 | err = xs_send_kvec(sock, &msg, &xdr->head[0], base); | 827 | if (rmsize) |
828 | err = xs_send_rm_and_kvec(sock, &msg, rm, | ||
829 | &xdr->head[0], base); | ||
830 | else | ||
831 | err = xs_send_kvec(sock, &msg, &xdr->head[0], base); | ||
801 | if (remainder == 0 || err != len) | 832 | if (remainder == 0 || err != len) |
802 | goto out; | 833 | goto out; |
803 | *sent_p += err; | 834 | *sent_p += err; |
804 | base = 0; | 835 | base = 0; |
805 | } else | 836 | } else |
806 | base -= xdr->head[0].iov_len; | 837 | base -= want; |
807 | 838 | ||
808 | if (base < xdr->page_len) { | 839 | if (base < xdr->page_len) { |
809 | unsigned int len = xdr->page_len - base; | 840 | unsigned int len = xdr->page_len - base; |
@@ -891,13 +922,14 @@ xs_send_request_was_aborted(struct sock_xprt *transport, struct rpc_rqst *req) | |||
891 | } | 922 | } |
892 | 923 | ||
893 | /* | 924 | /* |
894 | * Construct a stream transport record marker in @buf. | 925 | * Return the stream record marker field for a record of length < 2^31-1 |
895 | */ | 926 | */ |
896 | static inline void xs_encode_stream_record_marker(struct xdr_buf *buf) | 927 | static rpc_fraghdr |
928 | xs_stream_record_marker(struct xdr_buf *xdr) | ||
897 | { | 929 | { |
898 | u32 reclen = buf->len - sizeof(rpc_fraghdr); | 930 | if (!xdr->len) |
899 | rpc_fraghdr *base = buf->head[0].iov_base; | 931 | return 0; |
900 | *base = cpu_to_be32(RPC_LAST_STREAM_FRAGMENT | reclen); | 932 | return cpu_to_be32(RPC_LAST_STREAM_FRAGMENT | (u32)xdr->len); |
901 | } | 933 | } |
902 | 934 | ||
903 | /** | 935 | /** |
@@ -926,14 +958,13 @@ static int xs_local_send_request(struct rpc_rqst *req) | |||
926 | return -ENOTCONN; | 958 | return -ENOTCONN; |
927 | } | 959 | } |
928 | 960 | ||
929 | xs_encode_stream_record_marker(&req->rq_snd_buf); | ||
930 | |||
931 | xs_pktdump("packet data:", | 961 | xs_pktdump("packet data:", |
932 | req->rq_svec->iov_base, req->rq_svec->iov_len); | 962 | req->rq_svec->iov_base, req->rq_svec->iov_len); |
933 | 963 | ||
934 | req->rq_xtime = ktime_get(); | 964 | req->rq_xtime = ktime_get(); |
935 | status = xs_sendpages(transport->sock, NULL, 0, xdr, | 965 | status = xs_sendpages(transport->sock, NULL, 0, xdr, |
936 | transport->xmit.offset, | 966 | transport->xmit.offset, |
967 | xs_stream_record_marker(xdr), | ||
937 | &sent); | 968 | &sent); |
938 | dprintk("RPC: %s(%u) = %d\n", | 969 | dprintk("RPC: %s(%u) = %d\n", |
939 | __func__, xdr->len - transport->xmit.offset, status); | 970 | __func__, xdr->len - transport->xmit.offset, status); |
@@ -1001,7 +1032,7 @@ static int xs_udp_send_request(struct rpc_rqst *req) | |||
1001 | 1032 | ||
1002 | req->rq_xtime = ktime_get(); | 1033 | req->rq_xtime = ktime_get(); |
1003 | status = xs_sendpages(transport->sock, xs_addr(xprt), xprt->addrlen, | 1034 | status = xs_sendpages(transport->sock, xs_addr(xprt), xprt->addrlen, |
1004 | xdr, 0, &sent); | 1035 | xdr, 0, 0, &sent); |
1005 | 1036 | ||
1006 | dprintk("RPC: xs_udp_send_request(%u) = %d\n", | 1037 | dprintk("RPC: xs_udp_send_request(%u) = %d\n", |
1007 | xdr->len, status); | 1038 | xdr->len, status); |
@@ -1076,8 +1107,6 @@ static int xs_tcp_send_request(struct rpc_rqst *req) | |||
1076 | return -ENOTCONN; | 1107 | return -ENOTCONN; |
1077 | } | 1108 | } |
1078 | 1109 | ||
1079 | xs_encode_stream_record_marker(&req->rq_snd_buf); | ||
1080 | |||
1081 | xs_pktdump("packet data:", | 1110 | xs_pktdump("packet data:", |
1082 | req->rq_svec->iov_base, | 1111 | req->rq_svec->iov_base, |
1083 | req->rq_svec->iov_len); | 1112 | req->rq_svec->iov_len); |
@@ -1093,6 +1122,7 @@ static int xs_tcp_send_request(struct rpc_rqst *req) | |||
1093 | sent = 0; | 1122 | sent = 0; |
1094 | status = xs_sendpages(transport->sock, NULL, 0, xdr, | 1123 | status = xs_sendpages(transport->sock, NULL, 0, xdr, |
1095 | transport->xmit.offset, | 1124 | transport->xmit.offset, |
1125 | xs_stream_record_marker(xdr), | ||
1096 | &sent); | 1126 | &sent); |
1097 | 1127 | ||
1098 | dprintk("RPC: xs_tcp_send_request(%u) = %d\n", | 1128 | dprintk("RPC: xs_tcp_send_request(%u) = %d\n", |
@@ -2547,26 +2577,35 @@ static int bc_sendto(struct rpc_rqst *req) | |||
2547 | { | 2577 | { |
2548 | int len; | 2578 | int len; |
2549 | struct xdr_buf *xbufp = &req->rq_snd_buf; | 2579 | struct xdr_buf *xbufp = &req->rq_snd_buf; |
2550 | struct rpc_xprt *xprt = req->rq_xprt; | ||
2551 | struct sock_xprt *transport = | 2580 | struct sock_xprt *transport = |
2552 | container_of(xprt, struct sock_xprt, xprt); | 2581 | container_of(req->rq_xprt, struct sock_xprt, xprt); |
2553 | struct socket *sock = transport->sock; | ||
2554 | unsigned long headoff; | 2582 | unsigned long headoff; |
2555 | unsigned long tailoff; | 2583 | unsigned long tailoff; |
2584 | struct page *tailpage; | ||
2585 | struct msghdr msg = { | ||
2586 | .msg_flags = MSG_MORE | ||
2587 | }; | ||
2588 | rpc_fraghdr marker = cpu_to_be32(RPC_LAST_STREAM_FRAGMENT | | ||
2589 | (u32)xbufp->len); | ||
2590 | struct kvec iov = { | ||
2591 | .iov_base = &marker, | ||
2592 | .iov_len = sizeof(marker), | ||
2593 | }; | ||
2556 | 2594 | ||
2557 | xs_encode_stream_record_marker(xbufp); | 2595 | len = kernel_sendmsg(transport->sock, &msg, &iov, 1, iov.iov_len); |
2596 | if (len != iov.iov_len) | ||
2597 | return -EAGAIN; | ||
2558 | 2598 | ||
2599 | tailpage = NULL; | ||
2600 | if (xbufp->tail[0].iov_len) | ||
2601 | tailpage = virt_to_page(xbufp->tail[0].iov_base); | ||
2559 | tailoff = (unsigned long)xbufp->tail[0].iov_base & ~PAGE_MASK; | 2602 | tailoff = (unsigned long)xbufp->tail[0].iov_base & ~PAGE_MASK; |
2560 | headoff = (unsigned long)xbufp->head[0].iov_base & ~PAGE_MASK; | 2603 | headoff = (unsigned long)xbufp->head[0].iov_base & ~PAGE_MASK; |
2561 | len = svc_send_common(sock, xbufp, | 2604 | len = svc_send_common(transport->sock, xbufp, |
2562 | virt_to_page(xbufp->head[0].iov_base), headoff, | 2605 | virt_to_page(xbufp->head[0].iov_base), headoff, |
2563 | xbufp->tail[0].iov_base, tailoff); | 2606 | tailpage, tailoff); |
2564 | 2607 | if (len != xbufp->len) | |
2565 | if (len != xbufp->len) { | 2608 | return -EAGAIN; |
2566 | printk(KERN_NOTICE "Error sending entire callback!\n"); | ||
2567 | len = -EAGAIN; | ||
2568 | } | ||
2569 | |||
2570 | return len; | 2609 | return len; |
2571 | } | 2610 | } |
2572 | 2611 | ||
@@ -2806,7 +2845,6 @@ static struct rpc_xprt *xs_setup_local(struct xprt_create *args) | |||
2806 | transport = container_of(xprt, struct sock_xprt, xprt); | 2845 | transport = container_of(xprt, struct sock_xprt, xprt); |
2807 | 2846 | ||
2808 | xprt->prot = 0; | 2847 | xprt->prot = 0; |
2809 | xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); | ||
2810 | xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; | 2848 | xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; |
2811 | 2849 | ||
2812 | xprt->bind_timeout = XS_BIND_TO; | 2850 | xprt->bind_timeout = XS_BIND_TO; |
@@ -2875,7 +2913,6 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args) | |||
2875 | transport = container_of(xprt, struct sock_xprt, xprt); | 2913 | transport = container_of(xprt, struct sock_xprt, xprt); |
2876 | 2914 | ||
2877 | xprt->prot = IPPROTO_UDP; | 2915 | xprt->prot = IPPROTO_UDP; |
2878 | xprt->tsh_size = 0; | ||
2879 | /* XXX: header size can vary due to auth type, IPv6, etc. */ | 2916 | /* XXX: header size can vary due to auth type, IPv6, etc. */ |
2880 | xprt->max_payload = (1U << 16) - (MAX_HEADER << 3); | 2917 | xprt->max_payload = (1U << 16) - (MAX_HEADER << 3); |
2881 | 2918 | ||
@@ -2955,7 +2992,6 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args) | |||
2955 | transport = container_of(xprt, struct sock_xprt, xprt); | 2992 | transport = container_of(xprt, struct sock_xprt, xprt); |
2956 | 2993 | ||
2957 | xprt->prot = IPPROTO_TCP; | 2994 | xprt->prot = IPPROTO_TCP; |
2958 | xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); | ||
2959 | xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; | 2995 | xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; |
2960 | 2996 | ||
2961 | xprt->bind_timeout = XS_BIND_TO; | 2997 | xprt->bind_timeout = XS_BIND_TO; |
@@ -3028,7 +3064,6 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args) | |||
3028 | transport = container_of(xprt, struct sock_xprt, xprt); | 3064 | transport = container_of(xprt, struct sock_xprt, xprt); |
3029 | 3065 | ||
3030 | xprt->prot = IPPROTO_TCP; | 3066 | xprt->prot = IPPROTO_TCP; |
3031 | xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); | ||
3032 | xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; | 3067 | xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; |
3033 | xprt->timeout = &xs_tcp_default_timeout; | 3068 | xprt->timeout = &xs_tcp_default_timeout; |
3034 | 3069 | ||