]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
SUNRPC: Remove rpc_xprt::tsh_size
authorChuck Lever <chuck.lever@oracle.com>
Mon, 11 Feb 2019 16:24:37 +0000 (11:24 -0500)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Wed, 13 Feb 2019 18:14:35 +0000 (13:14 -0500)
tsh_size was added to accommodate transports that send a pre-amble
before each RPC message. However, this assumes the pre-amble is
fixed in size, which isn't true for some transports. That makes
tsh_size not very generic.

Also I'd like to make the estimation of RPC send and receive
buffer sizes more precise. tsh_size doesn't currently appear to be
accounted for at all by call_allocate.

Therefore let's just remove the tsh_size concept, and make the only
transports that have a non-zero tsh_size employ a direct approach.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
include/linux/sunrpc/xprt.h
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/clnt.c
net/sunrpc/svc.c
net/sunrpc/xprtrdma/svc_rdma_backchannel.c
net/sunrpc/xprtrdma/transport.c
net/sunrpc/xprtsock.c

index ad7e910b119dff15bf09af1e614577e05499c9d3..3a391544299e8dc1c39f85cb4d81ff491391c7d5 100644 (file)
@@ -196,8 +196,6 @@ struct rpc_xprt {
 
        size_t                  max_payload;    /* largest RPC payload size,
                                                   in bytes */
-       unsigned int            tsh_size;       /* size of transport specific
-                                                  header */
 
        struct rpc_wait_queue   binding;        /* requests waiting on rpcbind */
        struct rpc_wait_queue   sending;        /* requests waiting to send */
@@ -362,11 +360,6 @@ struct rpc_xprt *  xprt_alloc(struct net *net, size_t size,
                                unsigned int max_req);
 void                   xprt_free(struct rpc_xprt *);
 
-static inline __be32 *xprt_skip_transport_header(struct rpc_xprt *xprt, __be32 *p)
-{
-       return p + xprt->tsh_size;
-}
-
 static inline int
 xprt_enable_swap(struct rpc_xprt *xprt)
 {
index a42672e81792ed911bc6bf1fbc7e71d7512d0996..4b52e2b11c58f8c326c2e7257c22ef42e3548044 100644 (file)
@@ -1563,8 +1563,7 @@ gss_marshal(struct rpc_task *task, __be32 *p)
 
        /* We compute the checksum for the verifier over the xdr-encoded bytes
         * starting with the xid and ending at the end of the credential: */
-       iov.iov_base = xprt_skip_transport_header(req->rq_xprt,
-                                       req->rq_snd_buf.head[0].iov_base);
+       iov.iov_base = req->rq_snd_buf.head[0].iov_base;
        iov.iov_len = (u8 *)p - (u8 *)iov.iov_base;
        xdr_buf_from_iov(&iov, &verf_buf);
 
index d7ec6132c046ec409db057d6ace332ab620fa88b..c4203f6138ef678a89bcd5940fb6d049a27f77e5 100644 (file)
@@ -2331,7 +2331,6 @@ rpc_encode_header(struct rpc_task *task)
 
        /* FIXME: check buffer size? */
 
-       p = xprt_skip_transport_header(req->rq_xprt, p);
        *p++ = req->rq_xid;             /* XID */
        *p++ = htonl(RPC_CALL);         /* CALL */
        *p++ = htonl(RPC_VERSION);      /* RPC version */
index e87ddb9f7feb1ce6385cec4d01e1f8270511d77e..dbd19697ee38e40d5670e31d2b0392beb66aea2e 100644 (file)
@@ -1144,17 +1144,6 @@ void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...)
 static __printf(2,3) void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) {}
 #endif
 
-/*
- * Setup response header for TCP, it has a 4B record length field.
- */
-static void svc_tcp_prep_reply_hdr(struct svc_rqst *rqstp)
-{
-       struct kvec *resv = &rqstp->rq_res.head[0];
-
-       /* tcp needs a space for the record length... */
-       svc_putnl(resv, 0);
-}
-
 /*
  * Common routine for processing the RPC request.
  */
@@ -1182,10 +1171,6 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
        set_bit(RQ_USEDEFERRAL, &rqstp->rq_flags);
        clear_bit(RQ_DROPME, &rqstp->rq_flags);
 
-       /* Setup reply header */
-       if (rqstp->rq_prot == IPPROTO_TCP)
-               svc_tcp_prep_reply_hdr(rqstp);
-
        svc_putu32(resv, rqstp->rq_xid);
 
        vers = svc_getnl(argv);
@@ -1443,6 +1428,10 @@ svc_process(struct svc_rqst *rqstp)
                goto out_drop;
        }
 
+       /* Reserve space for the record marker */
+       if (rqstp->rq_prot == IPPROTO_TCP)
+               svc_putnl(resv, 0);
+
        /* Returns 1 for send, 0 for drop */
        if (likely(svc_process_common(rqstp, argv, resv)))
                return svc_send(rqstp);
index b908f2ca08fd4d99f2a073655b984567fb598d4e..907464c2a9f038642f551a5874c90cd1759df18b 100644 (file)
@@ -304,7 +304,6 @@ xprt_setup_rdma_bc(struct xprt_create *args)
        xprt->idle_timeout = RPCRDMA_IDLE_DISC_TO;
 
        xprt->prot = XPRT_TRANSPORT_BC_RDMA;
-       xprt->tsh_size = 0;
        xprt->ops = &xprt_rdma_bc_procs;
 
        memcpy(&xprt->addr, args->dstaddr, args->addrlen);
index fbc171ebfe9172dd8eb9a29f35ce6ef3e9bdeea3..e7274dc10120a6fdee85a9afc4973996d562de5f 100644 (file)
@@ -332,7 +332,6 @@ xprt_setup_rdma(struct xprt_create *args)
        xprt->idle_timeout = RPCRDMA_IDLE_DISC_TO;
 
        xprt->resvport = 0;             /* privileged port not needed */
-       xprt->tsh_size = 0;             /* RPC-RDMA handles framing */
        xprt->ops = &xprt_rdma_procs;
 
        /*
index 7754aa3e434f405711cfce8d9bdfece972dfc75c..ae09d850cd11b3148f11ffd09db8fb31d900f6ae 100644 (file)
@@ -696,6 +696,40 @@ xs_stream_reset_connect(struct sock_xprt *transport)
 
 #define XS_SENDMSG_FLAGS       (MSG_DONTWAIT | MSG_NOSIGNAL)
 
+/* Common case:
+ *  - stream transport
+ *  - sending from byte 0 of the message
+ *  - the message is wholly contained in @xdr's head iovec
+ */
+static int xs_send_rm_and_kvec(struct socket *sock, struct xdr_buf *xdr,
+                              unsigned int remainder)
+{
+       struct msghdr msg = {
+               .msg_flags      = XS_SENDMSG_FLAGS | (remainder ? MSG_MORE : 0)
+       };
+       rpc_fraghdr marker = cpu_to_be32(RPC_LAST_STREAM_FRAGMENT |
+                                        (u32)xdr->len);
+       struct kvec iov[2] = {
+               {
+                       .iov_base       = &marker,
+                       .iov_len        = sizeof(marker)
+               },
+               {
+                       .iov_base       = xdr->head[0].iov_base,
+                       .iov_len        = xdr->head[0].iov_len
+               },
+       };
+       int ret;
+
+       ret = kernel_sendmsg(sock, &msg, iov, 2,
+                            iov[0].iov_len + iov[1].iov_len);
+       if (ret < 0)
+               return ret;
+       if (ret < iov[0].iov_len)
+               return -EPIPE;
+       return ret - iov[0].iov_len;
+}
+
 static int xs_send_kvec(struct socket *sock, struct sockaddr *addr, int addrlen, struct kvec *vec, unsigned int base, int more)
 {
        struct msghdr msg = {
@@ -779,7 +813,11 @@ static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen,
        if (base < xdr->head[0].iov_len || addr != NULL) {
                unsigned int len = xdr->head[0].iov_len - base;
                remainder -= len;
-               err = xs_send_kvec(sock, addr, addrlen, &xdr->head[0], base, remainder != 0);
+               if (!base && !addr)
+                       err = xs_send_rm_and_kvec(sock, xdr, remainder);
+               else
+                       err = xs_send_kvec(sock, addr, addrlen, &xdr->head[0],
+                                          base, remainder != 0);
                if (remainder == 0 || err != len)
                        goto out;
                *sent_p += err;
@@ -869,16 +907,6 @@ xs_send_request_was_aborted(struct sock_xprt *transport, struct rpc_rqst *req)
        return transport->xmit.offset != 0 && req->rq_bytes_sent == 0;
 }
 
-/*
- * Construct a stream transport record marker in @buf.
- */
-static inline void xs_encode_stream_record_marker(struct xdr_buf *buf)
-{
-       u32 reclen = buf->len - sizeof(rpc_fraghdr);
-       rpc_fraghdr *base = buf->head[0].iov_base;
-       *base = cpu_to_be32(RPC_LAST_STREAM_FRAGMENT | reclen);
-}
-
 /**
  * xs_local_send_request - write an RPC request to an AF_LOCAL socket
  * @req: pointer to RPC request
@@ -905,8 +933,6 @@ static int xs_local_send_request(struct rpc_rqst *req)
                return -ENOTCONN;
        }
 
-       xs_encode_stream_record_marker(&req->rq_snd_buf);
-
        xs_pktdump("packet data:",
                        req->rq_svec->iov_base, req->rq_svec->iov_len);
 
@@ -1057,8 +1083,6 @@ static int xs_tcp_send_request(struct rpc_rqst *req)
                return -ENOTCONN;
        }
 
-       xs_encode_stream_record_marker(&req->rq_snd_buf);
-
        xs_pktdump("packet data:",
                                req->rq_svec->iov_base,
                                req->rq_svec->iov_len);
@@ -2534,26 +2558,35 @@ static int bc_sendto(struct rpc_rqst *req)
 {
        int len;
        struct xdr_buf *xbufp = &req->rq_snd_buf;
-       struct rpc_xprt *xprt = req->rq_xprt;
        struct sock_xprt *transport =
-                               container_of(xprt, struct sock_xprt, xprt);
-       struct socket *sock = transport->sock;
+                       container_of(req->rq_xprt, struct sock_xprt, xprt);
        unsigned long headoff;
        unsigned long tailoff;
+       struct page *tailpage;
+       struct msghdr msg = {
+               .msg_flags      = MSG_MORE
+       };
+       rpc_fraghdr marker = cpu_to_be32(RPC_LAST_STREAM_FRAGMENT |
+                                        (u32)xbufp->len);
+       struct kvec iov = {
+               .iov_base       = &marker,
+               .iov_len        = sizeof(marker),
+       };
 
-       xs_encode_stream_record_marker(xbufp);
+       len = kernel_sendmsg(transport->sock, &msg, &iov, 1, iov.iov_len);
+       if (len != iov.iov_len)
+               return -EAGAIN;
 
+       tailpage = NULL;
+       if (xbufp->tail[0].iov_len)
+               tailpage = virt_to_page(xbufp->tail[0].iov_base);
        tailoff = (unsigned long)xbufp->tail[0].iov_base & ~PAGE_MASK;
        headoff = (unsigned long)xbufp->head[0].iov_base & ~PAGE_MASK;
-       len = svc_send_common(sock, xbufp,
+       len = svc_send_common(transport->sock, xbufp,
                              virt_to_page(xbufp->head[0].iov_base), headoff,
-                             xbufp->tail[0].iov_base, tailoff);
-
-       if (len != xbufp->len) {
-               printk(KERN_NOTICE "Error sending entire callback!\n");
-               len = -EAGAIN;
-       }
-
+                             tailpage, tailoff);
+       if (len != xbufp->len)
+               return -EAGAIN;
        return len;
 }
 
@@ -2793,7 +2826,6 @@ static struct rpc_xprt *xs_setup_local(struct xprt_create *args)
        transport = container_of(xprt, struct sock_xprt, xprt);
 
        xprt->prot = 0;
-       xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32);
        xprt->max_payload = RPC_MAX_FRAGMENT_SIZE;
 
        xprt->bind_timeout = XS_BIND_TO;
@@ -2862,7 +2894,6 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args)
        transport = container_of(xprt, struct sock_xprt, xprt);
 
        xprt->prot = IPPROTO_UDP;
-       xprt->tsh_size = 0;
        /* XXX: header size can vary due to auth type, IPv6, etc. */
        xprt->max_payload = (1U << 16) - (MAX_HEADER << 3);
 
@@ -2942,7 +2973,6 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args)
        transport = container_of(xprt, struct sock_xprt, xprt);
 
        xprt->prot = IPPROTO_TCP;
-       xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32);
        xprt->max_payload = RPC_MAX_FRAGMENT_SIZE;
 
        xprt->bind_timeout = XS_BIND_TO;
@@ -3015,7 +3045,6 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args)
        transport = container_of(xprt, struct sock_xprt, xprt);
 
        xprt->prot = IPPROTO_TCP;
-       xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32);
        xprt->max_payload = RPC_MAX_FRAGMENT_SIZE;
        xprt->timeout = &xs_tcp_default_timeout;