Merge tag 'nfs-rdma-for-4.16-2' of git://git.linux-nfs.org/projects/anna/linux-nfs
authorTrond Myklebust <trond.myklebust@primarydata.com>
Tue, 6 Feb 2018 21:06:27 +0000 (16:06 -0500)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Tue, 6 Feb 2018 21:06:27 +0000 (16:06 -0500)
NFS-over-RDMA client fixes for Linux 4.16 #2

Stable fixes:
- Fix calculating ri_max_send_sges, which can oops if max_sge is too small
- Fix a BUG after device removal if freed resources haven't been allocated yet

net/sunrpc/xprtrdma/rpc_rdma.c
net/sunrpc/xprtrdma/verbs.c

index 162e5dd82466b7d00e32e969547e56732b8c76e2..f0855a959a278dac5c8e6459cd94df244f87ee2c 100644 (file)
@@ -143,7 +143,7 @@ static bool rpcrdma_args_inline(struct rpcrdma_xprt *r_xprt,
        if (xdr->page_len) {
                remaining = xdr->page_len;
                offset = offset_in_page(xdr->page_base);
-               count = 0;
+               count = RPCRDMA_MIN_SEND_SGES;
                while (remaining) {
                        remaining -= min_t(unsigned int,
                                           PAGE_SIZE - offset, remaining);
index f4eb63e8e6892516e04eee8b6ebf1be487b9a689..e6f84a6434a049e41d83092a0764668a21416d4c 100644 (file)
@@ -505,7 +505,7 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
                pr_warn("rpcrdma: HCA provides only %d send SGEs\n", max_sge);
                return -ENOMEM;
        }
-       ia->ri_max_send_sges = max_sge - RPCRDMA_MIN_SEND_SGES;
+       ia->ri_max_send_sges = max_sge;
 
        if (ia->ri_device->attrs.max_qp_wr <= RPCRDMA_BACKWARD_WRS) {
                dprintk("RPC:       %s: insufficient wqe's available\n",
@@ -1502,6 +1502,9 @@ __rpcrdma_dma_map_regbuf(struct rpcrdma_ia *ia, struct rpcrdma_regbuf *rb)
 static void
 rpcrdma_dma_unmap_regbuf(struct rpcrdma_regbuf *rb)
 {
+       if (!rb)
+               return;
+
        if (!rpcrdma_regbuf_is_mapped(rb))
                return;
 
@@ -1517,9 +1520,6 @@ rpcrdma_dma_unmap_regbuf(struct rpcrdma_regbuf *rb)
 void
 rpcrdma_free_regbuf(struct rpcrdma_regbuf *rb)
 {
-       if (!rb)
-               return;
-
        rpcrdma_dma_unmap_regbuf(rb);
        kfree(rb);
 }