diff options
| -rw-r--r-- | net/sunrpc/xprtrdma/fmr_ops.c | 51 | ||||
| -rw-r--r-- | net/sunrpc/xprtrdma/frwr_ops.c | 82 | ||||
| -rw-r--r-- | net/sunrpc/xprtrdma/physical_ops.c | 17 | ||||
| -rw-r--r-- | net/sunrpc/xprtrdma/rpc_rdma.c | 5 | ||||
| -rw-r--r-- | net/sunrpc/xprtrdma/verbs.c | 168 | ||||
| -rw-r--r-- | net/sunrpc/xprtrdma/xprt_rdma.h | 6 |
6 files changed, 160 insertions, 169 deletions
diff --git a/net/sunrpc/xprtrdma/fmr_ops.c b/net/sunrpc/xprtrdma/fmr_ops.c index eec266055b28..45fb646a6d36 100644 --- a/net/sunrpc/xprtrdma/fmr_ops.c +++ b/net/sunrpc/xprtrdma/fmr_ops.c | |||
| @@ -29,7 +29,58 @@ fmr_op_maxpages(struct rpcrdma_xprt *r_xprt) | |||
| 29 | rpcrdma_max_segments(r_xprt) * RPCRDMA_MAX_FMR_SGES); | 29 | rpcrdma_max_segments(r_xprt) * RPCRDMA_MAX_FMR_SGES); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | /* Use the ib_map_phys_fmr() verb to register a memory region | ||
| 33 | * for remote access via RDMA READ or RDMA WRITE. | ||
| 34 | */ | ||
| 35 | static int | ||
| 36 | fmr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, | ||
| 37 | int nsegs, bool writing) | ||
| 38 | { | ||
| 39 | struct rpcrdma_ia *ia = &r_xprt->rx_ia; | ||
| 40 | struct rpcrdma_mr_seg *seg1 = seg; | ||
| 41 | struct rpcrdma_mw *mw = seg1->rl_mw; | ||
| 42 | u64 physaddrs[RPCRDMA_MAX_DATA_SEGS]; | ||
| 43 | int len, pageoff, i, rc; | ||
| 44 | |||
| 45 | pageoff = offset_in_page(seg1->mr_offset); | ||
| 46 | seg1->mr_offset -= pageoff; /* start of page */ | ||
| 47 | seg1->mr_len += pageoff; | ||
| 48 | len = -pageoff; | ||
| 49 | if (nsegs > RPCRDMA_MAX_FMR_SGES) | ||
| 50 | nsegs = RPCRDMA_MAX_FMR_SGES; | ||
| 51 | for (i = 0; i < nsegs;) { | ||
| 52 | rpcrdma_map_one(ia, seg, writing); | ||
| 53 | physaddrs[i] = seg->mr_dma; | ||
| 54 | len += seg->mr_len; | ||
| 55 | ++seg; | ||
| 56 | ++i; | ||
| 57 | /* Check for holes */ | ||
| 58 | if ((i < nsegs && offset_in_page(seg->mr_offset)) || | ||
| 59 | offset_in_page((seg-1)->mr_offset + (seg-1)->mr_len)) | ||
| 60 | break; | ||
| 61 | } | ||
| 62 | |||
| 63 | rc = ib_map_phys_fmr(mw->r.fmr, physaddrs, i, seg1->mr_dma); | ||
| 64 | if (rc) | ||
| 65 | goto out_maperr; | ||
| 66 | |||
| 67 | seg1->mr_rkey = mw->r.fmr->rkey; | ||
| 68 | seg1->mr_base = seg1->mr_dma + pageoff; | ||
| 69 | seg1->mr_nsegs = i; | ||
| 70 | seg1->mr_len = len; | ||
| 71 | return i; | ||
| 72 | |||
| 73 | out_maperr: | ||
| 74 | dprintk("RPC: %s: ib_map_phys_fmr %u@0x%llx+%i (%d) status %i\n", | ||
| 75 | __func__, len, (unsigned long long)seg1->mr_dma, | ||
| 76 | pageoff, i, rc); | ||
| 77 | while (i--) | ||
| 78 | rpcrdma_unmap_one(ia, --seg); | ||
| 79 | return rc; | ||
| 80 | } | ||
| 81 | |||
| 32 | const struct rpcrdma_memreg_ops rpcrdma_fmr_memreg_ops = { | 82 | const struct rpcrdma_memreg_ops rpcrdma_fmr_memreg_ops = { |
| 83 | .ro_map = fmr_op_map, | ||
| 33 | .ro_maxpages = fmr_op_maxpages, | 84 | .ro_maxpages = fmr_op_maxpages, |
| 34 | .ro_displayname = "fmr", | 85 | .ro_displayname = "fmr", |
| 35 | }; | 86 | }; |
diff --git a/net/sunrpc/xprtrdma/frwr_ops.c b/net/sunrpc/xprtrdma/frwr_ops.c index 73a5ac898efc..23e4d99a2097 100644 --- a/net/sunrpc/xprtrdma/frwr_ops.c +++ b/net/sunrpc/xprtrdma/frwr_ops.c | |||
| @@ -29,7 +29,89 @@ frwr_op_maxpages(struct rpcrdma_xprt *r_xprt) | |||
| 29 | rpcrdma_max_segments(r_xprt) * ia->ri_max_frmr_depth); | 29 | rpcrdma_max_segments(r_xprt) * ia->ri_max_frmr_depth); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | /* Post a FAST_REG Work Request to register a memory region | ||
| 33 | * for remote access via RDMA READ or RDMA WRITE. | ||
| 34 | */ | ||
| 35 | static int | ||
| 36 | frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, | ||
| 37 | int nsegs, bool writing) | ||
| 38 | { | ||
| 39 | struct rpcrdma_ia *ia = &r_xprt->rx_ia; | ||
| 40 | struct rpcrdma_mr_seg *seg1 = seg; | ||
| 41 | struct rpcrdma_mw *mw = seg1->rl_mw; | ||
| 42 | struct rpcrdma_frmr *frmr = &mw->r.frmr; | ||
| 43 | struct ib_mr *mr = frmr->fr_mr; | ||
| 44 | struct ib_send_wr fastreg_wr, *bad_wr; | ||
| 45 | u8 key; | ||
| 46 | int len, pageoff; | ||
| 47 | int i, rc; | ||
| 48 | int seg_len; | ||
| 49 | u64 pa; | ||
| 50 | int page_no; | ||
| 51 | |||
| 52 | pageoff = offset_in_page(seg1->mr_offset); | ||
| 53 | seg1->mr_offset -= pageoff; /* start of page */ | ||
| 54 | seg1->mr_len += pageoff; | ||
| 55 | len = -pageoff; | ||
| 56 | if (nsegs > ia->ri_max_frmr_depth) | ||
| 57 | nsegs = ia->ri_max_frmr_depth; | ||
| 58 | for (page_no = i = 0; i < nsegs;) { | ||
| 59 | rpcrdma_map_one(ia, seg, writing); | ||
| 60 | pa = seg->mr_dma; | ||
| 61 | for (seg_len = seg->mr_len; seg_len > 0; seg_len -= PAGE_SIZE) { | ||
| 62 | frmr->fr_pgl->page_list[page_no++] = pa; | ||
| 63 | pa += PAGE_SIZE; | ||
| 64 | } | ||
| 65 | len += seg->mr_len; | ||
| 66 | ++seg; | ||
| 67 | ++i; | ||
| 68 | /* Check for holes */ | ||
| 69 | if ((i < nsegs && offset_in_page(seg->mr_offset)) || | ||
| 70 | offset_in_page((seg-1)->mr_offset + (seg-1)->mr_len)) | ||
| 71 | break; | ||
| 72 | } | ||
| 73 | dprintk("RPC: %s: Using frmr %p to map %d segments (%d bytes)\n", | ||
| 74 | __func__, mw, i, len); | ||
| 75 | |||
| 76 | frmr->fr_state = FRMR_IS_VALID; | ||
| 77 | |||
| 78 | memset(&fastreg_wr, 0, sizeof(fastreg_wr)); | ||
| 79 | fastreg_wr.wr_id = (unsigned long)(void *)mw; | ||
| 80 | fastreg_wr.opcode = IB_WR_FAST_REG_MR; | ||
| 81 | fastreg_wr.wr.fast_reg.iova_start = seg1->mr_dma + pageoff; | ||
| 82 | fastreg_wr.wr.fast_reg.page_list = frmr->fr_pgl; | ||
| 83 | fastreg_wr.wr.fast_reg.page_shift = PAGE_SHIFT; | ||
| 84 | fastreg_wr.wr.fast_reg.page_list_len = page_no; | ||
| 85 | fastreg_wr.wr.fast_reg.length = len; | ||
| 86 | fastreg_wr.wr.fast_reg.access_flags = writing ? | ||
| 87 | IB_ACCESS_REMOTE_WRITE | IB_ACCESS_LOCAL_WRITE : | ||
| 88 | IB_ACCESS_REMOTE_READ; | ||
| 89 | key = (u8)(mr->rkey & 0x000000FF); | ||
| 90 | ib_update_fast_reg_key(mr, ++key); | ||
| 91 | fastreg_wr.wr.fast_reg.rkey = mr->rkey; | ||
| 92 | |||
| 93 | DECR_CQCOUNT(&r_xprt->rx_ep); | ||
| 94 | rc = ib_post_send(ia->ri_id->qp, &fastreg_wr, &bad_wr); | ||
| 95 | if (rc) | ||
| 96 | goto out_senderr; | ||
| 97 | |||
| 98 | seg1->mr_rkey = mr->rkey; | ||
| 99 | seg1->mr_base = seg1->mr_dma + pageoff; | ||
| 100 | seg1->mr_nsegs = i; | ||
| 101 | seg1->mr_len = len; | ||
| 102 | return i; | ||
| 103 | |||
| 104 | out_senderr: | ||
| 105 | dprintk("RPC: %s: ib_post_send status %i\n", __func__, rc); | ||
| 106 | ib_update_fast_reg_key(mr, --key); | ||
| 107 | frmr->fr_state = FRMR_IS_INVALID; | ||
| 108 | while (i--) | ||
| 109 | rpcrdma_unmap_one(ia, --seg); | ||
| 110 | return rc; | ||
| 111 | } | ||
| 112 | |||
| 32 | const struct rpcrdma_memreg_ops rpcrdma_frwr_memreg_ops = { | 113 | const struct rpcrdma_memreg_ops rpcrdma_frwr_memreg_ops = { |
| 114 | .ro_map = frwr_op_map, | ||
| 33 | .ro_maxpages = frwr_op_maxpages, | 115 | .ro_maxpages = frwr_op_maxpages, |
| 34 | .ro_displayname = "frwr", | 116 | .ro_displayname = "frwr", |
| 35 | }; | 117 | }; |
diff --git a/net/sunrpc/xprtrdma/physical_ops.c b/net/sunrpc/xprtrdma/physical_ops.c index 28ade1943a57..5a284ee0e058 100644 --- a/net/sunrpc/xprtrdma/physical_ops.c +++ b/net/sunrpc/xprtrdma/physical_ops.c | |||
| @@ -28,7 +28,24 @@ physical_op_maxpages(struct rpcrdma_xprt *r_xprt) | |||
| 28 | rpcrdma_max_segments(r_xprt)); | 28 | rpcrdma_max_segments(r_xprt)); |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | /* The client's physical memory is already exposed for | ||
| 32 | * remote access via RDMA READ or RDMA WRITE. | ||
| 33 | */ | ||
| 34 | static int | ||
| 35 | physical_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, | ||
| 36 | int nsegs, bool writing) | ||
| 37 | { | ||
| 38 | struct rpcrdma_ia *ia = &r_xprt->rx_ia; | ||
| 39 | |||
| 40 | rpcrdma_map_one(ia, seg, writing); | ||
| 41 | seg->mr_rkey = ia->ri_bind_mem->rkey; | ||
| 42 | seg->mr_base = seg->mr_dma; | ||
| 43 | seg->mr_nsegs = 1; | ||
| 44 | return 1; | ||
| 45 | } | ||
| 46 | |||
| 31 | const struct rpcrdma_memreg_ops rpcrdma_physical_memreg_ops = { | 47 | const struct rpcrdma_memreg_ops rpcrdma_physical_memreg_ops = { |
| 48 | .ro_map = physical_op_map, | ||
| 32 | .ro_maxpages = physical_op_maxpages, | 49 | .ro_maxpages = physical_op_maxpages, |
| 33 | .ro_displayname = "physical", | 50 | .ro_displayname = "physical", |
| 34 | }; | 51 | }; |
diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c index 41456d9e5a7d..6ab1d03d7f3e 100644 --- a/net/sunrpc/xprtrdma/rpc_rdma.c +++ b/net/sunrpc/xprtrdma/rpc_rdma.c | |||
| @@ -187,6 +187,7 @@ rpcrdma_create_chunks(struct rpc_rqst *rqst, struct xdr_buf *target, | |||
| 187 | struct rpcrdma_write_array *warray = NULL; | 187 | struct rpcrdma_write_array *warray = NULL; |
| 188 | struct rpcrdma_write_chunk *cur_wchunk = NULL; | 188 | struct rpcrdma_write_chunk *cur_wchunk = NULL; |
| 189 | __be32 *iptr = headerp->rm_body.rm_chunks; | 189 | __be32 *iptr = headerp->rm_body.rm_chunks; |
| 190 | int (*map)(struct rpcrdma_xprt *, struct rpcrdma_mr_seg *, int, bool); | ||
| 190 | 191 | ||
| 191 | if (type == rpcrdma_readch || type == rpcrdma_areadch) { | 192 | if (type == rpcrdma_readch || type == rpcrdma_areadch) { |
| 192 | /* a read chunk - server will RDMA Read our memory */ | 193 | /* a read chunk - server will RDMA Read our memory */ |
| @@ -209,9 +210,9 @@ rpcrdma_create_chunks(struct rpc_rqst *rqst, struct xdr_buf *target, | |||
| 209 | if (nsegs < 0) | 210 | if (nsegs < 0) |
| 210 | return nsegs; | 211 | return nsegs; |
| 211 | 212 | ||
| 213 | map = r_xprt->rx_ia.ri_ops->ro_map; | ||
| 212 | do { | 214 | do { |
| 213 | n = rpcrdma_register_external(seg, nsegs, | 215 | n = map(r_xprt, seg, nsegs, cur_wchunk != NULL); |
| 214 | cur_wchunk != NULL, r_xprt); | ||
| 215 | if (n <= 0) | 216 | if (n <= 0) |
| 216 | goto out; | 217 | goto out; |
| 217 | if (cur_rchunk) { /* read */ | 218 | if (cur_rchunk) { /* read */ |
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index da55cda30568..4318c04e095c 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c | |||
| @@ -1858,8 +1858,8 @@ rpcrdma_free_regbuf(struct rpcrdma_ia *ia, struct rpcrdma_regbuf *rb) | |||
| 1858 | * Wrappers for chunk registration, shared by read/write chunk code. | 1858 | * Wrappers for chunk registration, shared by read/write chunk code. |
| 1859 | */ | 1859 | */ |
| 1860 | 1860 | ||
| 1861 | static void | 1861 | void |
| 1862 | rpcrdma_map_one(struct rpcrdma_ia *ia, struct rpcrdma_mr_seg *seg, int writing) | 1862 | rpcrdma_map_one(struct rpcrdma_ia *ia, struct rpcrdma_mr_seg *seg, bool writing) |
| 1863 | { | 1863 | { |
| 1864 | seg->mr_dir = writing ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | 1864 | seg->mr_dir = writing ? DMA_FROM_DEVICE : DMA_TO_DEVICE; |
| 1865 | seg->mr_dmalen = seg->mr_len; | 1865 | seg->mr_dmalen = seg->mr_len; |
| @@ -1879,7 +1879,7 @@ rpcrdma_map_one(struct rpcrdma_ia *ia, struct rpcrdma_mr_seg *seg, int writing) | |||
| 1879 | } | 1879 | } |
| 1880 | } | 1880 | } |
| 1881 | 1881 | ||
| 1882 | static void | 1882 | void |
| 1883 | rpcrdma_unmap_one(struct rpcrdma_ia *ia, struct rpcrdma_mr_seg *seg) | 1883 | rpcrdma_unmap_one(struct rpcrdma_ia *ia, struct rpcrdma_mr_seg *seg) |
| 1884 | { | 1884 | { |
| 1885 | if (seg->mr_page) | 1885 | if (seg->mr_page) |
| @@ -1891,89 +1891,6 @@ rpcrdma_unmap_one(struct rpcrdma_ia *ia, struct rpcrdma_mr_seg *seg) | |||
| 1891 | } | 1891 | } |
| 1892 | 1892 | ||
| 1893 | static int | 1893 | static int |
| 1894 | rpcrdma_register_frmr_external(struct rpcrdma_mr_seg *seg, | ||
| 1895 | int *nsegs, int writing, struct rpcrdma_ia *ia, | ||
| 1896 | struct rpcrdma_xprt *r_xprt) | ||
| 1897 | { | ||
| 1898 | struct rpcrdma_mr_seg *seg1 = seg; | ||
| 1899 | struct rpcrdma_mw *mw = seg1->rl_mw; | ||
| 1900 | struct rpcrdma_frmr *frmr = &mw->r.frmr; | ||
| 1901 | struct ib_mr *mr = frmr->fr_mr; | ||
| 1902 | struct ib_send_wr fastreg_wr, *bad_wr; | ||
| 1903 | u8 key; | ||
| 1904 | int len, pageoff; | ||
| 1905 | int i, rc; | ||
| 1906 | int seg_len; | ||
| 1907 | u64 pa; | ||
| 1908 | int page_no; | ||
| 1909 | |||
| 1910 | pageoff = offset_in_page(seg1->mr_offset); | ||
| 1911 | seg1->mr_offset -= pageoff; /* start of page */ | ||
| 1912 | seg1->mr_len += pageoff; | ||
| 1913 | len = -pageoff; | ||
| 1914 | if (*nsegs > ia->ri_max_frmr_depth) | ||
| 1915 | *nsegs = ia->ri_max_frmr_depth; | ||
| 1916 | for (page_no = i = 0; i < *nsegs;) { | ||
| 1917 | rpcrdma_map_one(ia, seg, writing); | ||
| 1918 | pa = seg->mr_dma; | ||
| 1919 | for (seg_len = seg->mr_len; seg_len > 0; seg_len -= PAGE_SIZE) { | ||
| 1920 | frmr->fr_pgl->page_list[page_no++] = pa; | ||
| 1921 | pa += PAGE_SIZE; | ||
| 1922 | } | ||
| 1923 | len += seg->mr_len; | ||
| 1924 | ++seg; | ||
| 1925 | ++i; | ||
| 1926 | /* Check for holes */ | ||
| 1927 | if ((i < *nsegs && offset_in_page(seg->mr_offset)) || | ||
| 1928 | offset_in_page((seg-1)->mr_offset + (seg-1)->mr_len)) | ||
| 1929 | break; | ||
| 1930 | } | ||
| 1931 | dprintk("RPC: %s: Using frmr %p to map %d segments (%d bytes)\n", | ||
| 1932 | __func__, mw, i, len); | ||
| 1933 | |||
| 1934 | frmr->fr_state = FRMR_IS_VALID; | ||
| 1935 | |||
| 1936 | memset(&fastreg_wr, 0, sizeof(fastreg_wr)); | ||
| 1937 | fastreg_wr.wr_id = (unsigned long)(void *)mw; | ||
| 1938 | fastreg_wr.opcode = IB_WR_FAST_REG_MR; | ||
| 1939 | fastreg_wr.wr.fast_reg.iova_start = seg1->mr_dma + pageoff; | ||
| 1940 | fastreg_wr.wr.fast_reg.page_list = frmr->fr_pgl; | ||
| 1941 | fastreg_wr.wr.fast_reg.page_list_len = page_no; | ||
| 1942 | fastreg_wr.wr.fast_reg.page_shift = PAGE_SHIFT; | ||
| 1943 | fastreg_wr.wr.fast_reg.length = len; | ||
| 1944 | |||
| 1945 | /* Bump the key */ | ||
| 1946 | key = (u8)(mr->rkey & 0x000000FF); | ||
| 1947 | ib_update_fast_reg_key(mr, ++key); | ||
| 1948 | |||
| 1949 | fastreg_wr.wr.fast_reg.access_flags = (writing ? | ||
| 1950 | IB_ACCESS_REMOTE_WRITE | IB_ACCESS_LOCAL_WRITE : | ||
| 1951 | IB_ACCESS_REMOTE_READ); | ||
| 1952 | fastreg_wr.wr.fast_reg.rkey = mr->rkey; | ||
| 1953 | DECR_CQCOUNT(&r_xprt->rx_ep); | ||
| 1954 | |||
| 1955 | rc = ib_post_send(ia->ri_id->qp, &fastreg_wr, &bad_wr); | ||
| 1956 | if (rc) { | ||
| 1957 | dprintk("RPC: %s: failed ib_post_send for register," | ||
| 1958 | " status %i\n", __func__, rc); | ||
| 1959 | ib_update_fast_reg_key(mr, --key); | ||
| 1960 | goto out_err; | ||
| 1961 | } else { | ||
| 1962 | seg1->mr_rkey = mr->rkey; | ||
| 1963 | seg1->mr_base = seg1->mr_dma + pageoff; | ||
| 1964 | seg1->mr_nsegs = i; | ||
| 1965 | seg1->mr_len = len; | ||
| 1966 | } | ||
| 1967 | *nsegs = i; | ||
| 1968 | return 0; | ||
| 1969 | out_err: | ||
| 1970 | frmr->fr_state = FRMR_IS_INVALID; | ||
| 1971 | while (i--) | ||
| 1972 | rpcrdma_unmap_one(ia, --seg); | ||
| 1973 | return rc; | ||
| 1974 | } | ||
| 1975 | |||
| 1976 | static int | ||
| 1977 | rpcrdma_deregister_frmr_external(struct rpcrdma_mr_seg *seg, | 1894 | rpcrdma_deregister_frmr_external(struct rpcrdma_mr_seg *seg, |
| 1978 | struct rpcrdma_ia *ia, struct rpcrdma_xprt *r_xprt) | 1895 | struct rpcrdma_ia *ia, struct rpcrdma_xprt *r_xprt) |
| 1979 | { | 1896 | { |
| @@ -2004,49 +1921,6 @@ rpcrdma_deregister_frmr_external(struct rpcrdma_mr_seg *seg, | |||
| 2004 | } | 1921 | } |
| 2005 | 1922 | ||
| 2006 | static int | 1923 | static int |
| 2007 | rpcrdma_register_fmr_external(struct rpcrdma_mr_seg *seg, | ||
| 2008 | int *nsegs, int writing, struct rpcrdma_ia *ia) | ||
| 2009 | { | ||
| 2010 | struct rpcrdma_mr_seg *seg1 = seg; | ||
| 2011 | u64 physaddrs[RPCRDMA_MAX_DATA_SEGS]; | ||
| 2012 | int len, pageoff, i, rc; | ||
| 2013 | |||
| 2014 | pageoff = offset_in_page(seg1->mr_offset); | ||
| 2015 | seg1->mr_offset -= pageoff; /* start of page */ | ||
| 2016 | seg1->mr_len += pageoff; | ||
| 2017 | len = -pageoff; | ||
| 2018 | if (*nsegs > RPCRDMA_MAX_DATA_SEGS) | ||
| 2019 | *nsegs = RPCRDMA_MAX_DATA_SEGS; | ||
| 2020 | for (i = 0; i < *nsegs;) { | ||
| 2021 | rpcrdma_map_one(ia, seg, writing); | ||
| 2022 | physaddrs[i] = seg->mr_dma; | ||
| 2023 | len += seg->mr_len; | ||
| 2024 | ++seg; | ||
| 2025 | ++i; | ||
| 2026 | /* Check for holes */ | ||
| 2027 | if ((i < *nsegs && offset_in_page(seg->mr_offset)) || | ||
| 2028 | offset_in_page((seg-1)->mr_offset + (seg-1)->mr_len)) | ||
| 2029 | break; | ||
| 2030 | } | ||
| 2031 | rc = ib_map_phys_fmr(seg1->rl_mw->r.fmr, physaddrs, i, seg1->mr_dma); | ||
| 2032 | if (rc) { | ||
| 2033 | dprintk("RPC: %s: failed ib_map_phys_fmr " | ||
| 2034 | "%u@0x%llx+%i (%d)... status %i\n", __func__, | ||
| 2035 | len, (unsigned long long)seg1->mr_dma, | ||
| 2036 | pageoff, i, rc); | ||
| 2037 | while (i--) | ||
| 2038 | rpcrdma_unmap_one(ia, --seg); | ||
| 2039 | } else { | ||
| 2040 | seg1->mr_rkey = seg1->rl_mw->r.fmr->rkey; | ||
| 2041 | seg1->mr_base = seg1->mr_dma + pageoff; | ||
| 2042 | seg1->mr_nsegs = i; | ||
| 2043 | seg1->mr_len = len; | ||
| 2044 | } | ||
| 2045 | *nsegs = i; | ||
| 2046 | return rc; | ||
| 2047 | } | ||
| 2048 | |||
| 2049 | static int | ||
| 2050 | rpcrdma_deregister_fmr_external(struct rpcrdma_mr_seg *seg, | 1924 | rpcrdma_deregister_fmr_external(struct rpcrdma_mr_seg *seg, |
| 2051 | struct rpcrdma_ia *ia) | 1925 | struct rpcrdma_ia *ia) |
| 2052 | { | 1926 | { |
| @@ -2067,42 +1941,6 @@ rpcrdma_deregister_fmr_external(struct rpcrdma_mr_seg *seg, | |||
| 2067 | } | 1941 | } |
| 2068 | 1942 | ||
| 2069 | int | 1943 | int |
| 2070 | rpcrdma_register_external(struct rpcrdma_mr_seg *seg, | ||
| 2071 | int nsegs, int writing, struct rpcrdma_xprt *r_xprt) | ||
| 2072 | { | ||
| 2073 | struct rpcrdma_ia *ia = &r_xprt->rx_ia; | ||
| 2074 | int rc = 0; | ||
| 2075 | |||
| 2076 | switch (ia->ri_memreg_strategy) { | ||
| 2077 | |||
| 2078 | case RPCRDMA_ALLPHYSICAL: | ||
| 2079 | rpcrdma_map_one(ia, seg, writing); | ||
| 2080 | seg->mr_rkey = ia->ri_bind_mem->rkey; | ||
| 2081 | seg->mr_base = seg->mr_dma; | ||
| 2082 | seg->mr_nsegs = 1; | ||
| 2083 | nsegs = 1; | ||
| 2084 | break; | ||
| 2085 | |||
| 2086 | /* Registration using frmr registration */ | ||
| 2087 | case RPCRDMA_FRMR: | ||
| 2088 | rc = rpcrdma_register_frmr_external(seg, &nsegs, writing, ia, r_xprt); | ||
| 2089 | break; | ||
| 2090 | |||
| 2091 | /* Registration using fmr memory registration */ | ||
| 2092 | case RPCRDMA_MTHCAFMR: | ||
| 2093 | rc = rpcrdma_register_fmr_external(seg, &nsegs, writing, ia); | ||
| 2094 | break; | ||
| 2095 | |||
| 2096 | default: | ||
| 2097 | return -EIO; | ||
| 2098 | } | ||
| 2099 | if (rc) | ||
| 2100 | return rc; | ||
| 2101 | |||
| 2102 | return nsegs; | ||
| 2103 | } | ||
| 2104 | |||
| 2105 | int | ||
| 2106 | rpcrdma_deregister_external(struct rpcrdma_mr_seg *seg, | 1944 | rpcrdma_deregister_external(struct rpcrdma_mr_seg *seg, |
| 2107 | struct rpcrdma_xprt *r_xprt) | 1945 | struct rpcrdma_xprt *r_xprt) |
| 2108 | { | 1946 | { |
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h index 59e627e96a0b..7bf077bf751d 100644 --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h | |||
| @@ -336,6 +336,8 @@ struct rpcrdma_stats { | |||
| 336 | */ | 336 | */ |
| 337 | struct rpcrdma_xprt; | 337 | struct rpcrdma_xprt; |
| 338 | struct rpcrdma_memreg_ops { | 338 | struct rpcrdma_memreg_ops { |
| 339 | int (*ro_map)(struct rpcrdma_xprt *, | ||
| 340 | struct rpcrdma_mr_seg *, int, bool); | ||
| 339 | size_t (*ro_maxpages)(struct rpcrdma_xprt *); | 341 | size_t (*ro_maxpages)(struct rpcrdma_xprt *); |
| 340 | const char *ro_displayname; | 342 | const char *ro_displayname; |
| 341 | }; | 343 | }; |
| @@ -403,8 +405,6 @@ void rpcrdma_buffer_put(struct rpcrdma_req *); | |||
| 403 | void rpcrdma_recv_buffer_get(struct rpcrdma_req *); | 405 | void rpcrdma_recv_buffer_get(struct rpcrdma_req *); |
| 404 | void rpcrdma_recv_buffer_put(struct rpcrdma_rep *); | 406 | void rpcrdma_recv_buffer_put(struct rpcrdma_rep *); |
| 405 | 407 | ||
| 406 | int rpcrdma_register_external(struct rpcrdma_mr_seg *, | ||
| 407 | int, int, struct rpcrdma_xprt *); | ||
| 408 | int rpcrdma_deregister_external(struct rpcrdma_mr_seg *, | 408 | int rpcrdma_deregister_external(struct rpcrdma_mr_seg *, |
| 409 | struct rpcrdma_xprt *); | 409 | struct rpcrdma_xprt *); |
| 410 | 410 | ||
| @@ -414,6 +414,8 @@ void rpcrdma_free_regbuf(struct rpcrdma_ia *, | |||
| 414 | struct rpcrdma_regbuf *); | 414 | struct rpcrdma_regbuf *); |
| 415 | 415 | ||
| 416 | unsigned int rpcrdma_max_segments(struct rpcrdma_xprt *); | 416 | unsigned int rpcrdma_max_segments(struct rpcrdma_xprt *); |
| 417 | void rpcrdma_map_one(struct rpcrdma_ia *, struct rpcrdma_mr_seg *, bool); | ||
| 418 | void rpcrdma_unmap_one(struct rpcrdma_ia *, struct rpcrdma_mr_seg *); | ||
| 417 | 419 | ||
| 418 | /* | 420 | /* |
| 419 | * RPC/RDMA connection management calls - xprtrdma/rpc_rdma.c | 421 | * RPC/RDMA connection management calls - xprtrdma/rpc_rdma.c |
