diff options
| -rw-r--r-- | net/sunrpc/xprtrdma/svc_rdma_transport.c | 76 |
1 files changed, 70 insertions, 6 deletions
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c index f0b5c5f2f62..a8ec4b1eec5 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c | |||
| @@ -807,6 +807,8 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt) | |||
| 807 | struct rdma_conn_param conn_param; | 807 | struct rdma_conn_param conn_param; |
| 808 | struct ib_qp_init_attr qp_attr; | 808 | struct ib_qp_init_attr qp_attr; |
| 809 | struct ib_device_attr devattr; | 809 | struct ib_device_attr devattr; |
| 810 | int dma_mr_acc; | ||
| 811 | int need_dma_mr; | ||
| 810 | int ret; | 812 | int ret; |
| 811 | int i; | 813 | int i; |
| 812 | 814 | ||
| @@ -922,15 +924,77 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt) | |||
| 922 | } | 924 | } |
| 923 | newxprt->sc_qp = newxprt->sc_cm_id->qp; | 925 | newxprt->sc_qp = newxprt->sc_cm_id->qp; |
| 924 | 926 | ||
| 925 | /* Register all of physical memory */ | 927 | /* |
| 926 | newxprt->sc_phys_mr = ib_get_dma_mr(newxprt->sc_pd, | 928 | * Use the most secure set of MR resources based on the |
| 927 | IB_ACCESS_LOCAL_WRITE | | 929 | * transport type and available memory management features in |
| 928 | IB_ACCESS_REMOTE_WRITE); | 930 | * the device. Here's the table implemented below: |
| 929 | if (IS_ERR(newxprt->sc_phys_mr)) { | 931 | * |
| 930 | dprintk("svcrdma: Failed to create DMA MR ret=%d\n", ret); | 932 | * Fast Global DMA Remote WR |
| 933 | * Reg LKEY MR Access | ||
| 934 | * Sup'd Sup'd Needed Needed | ||
| 935 | * | ||
| 936 | * IWARP N N Y Y | ||
| 937 | * N Y Y Y | ||
| 938 | * Y N Y N | ||
| 939 | * Y Y N - | ||
| 940 | * | ||
| 941 | * IB N N Y N | ||
| 942 | * N Y N - | ||
| 943 | * Y N Y N | ||
| 944 | * Y Y N - | ||
| 945 | * | ||
| 946 | * NB: iWARP requires remote write access for the data sink | ||
| 947 | * of an RDMA_READ. IB does not. | ||
| 948 | */ | ||
| 949 | if (devattr.device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) { | ||
| 950 | newxprt->sc_frmr_pg_list_len = | ||
| 951 | devattr.max_fast_reg_page_list_len; | ||
| 952 | newxprt->sc_dev_caps |= SVCRDMA_DEVCAP_FAST_REG; | ||
| 953 | } | ||
| 954 | |||
| 955 | /* | ||
| 956 | * Determine if a DMA MR is required and if so, what privs are required | ||
| 957 | */ | ||
| 958 | switch (rdma_node_get_transport(newxprt->sc_cm_id->device->node_type)) { | ||
| 959 | case RDMA_TRANSPORT_IWARP: | ||
| 960 | newxprt->sc_dev_caps |= SVCRDMA_DEVCAP_READ_W_INV; | ||
| 961 | if (!(newxprt->sc_dev_caps & SVCRDMA_DEVCAP_FAST_REG)) { | ||
| 962 | need_dma_mr = 1; | ||
| 963 | dma_mr_acc = | ||
| 964 | (IB_ACCESS_LOCAL_WRITE | | ||
| 965 | IB_ACCESS_REMOTE_WRITE); | ||
| 966 | } else if (!(devattr.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY)) { | ||
| 967 | need_dma_mr = 1; | ||
| 968 | dma_mr_acc = IB_ACCESS_LOCAL_WRITE; | ||
| 969 | } else | ||
| 970 | need_dma_mr = 0; | ||
| 971 | break; | ||
| 972 | case RDMA_TRANSPORT_IB: | ||
| 973 | if (!(devattr.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY)) { | ||
| 974 | need_dma_mr = 1; | ||
| 975 | dma_mr_acc = IB_ACCESS_LOCAL_WRITE; | ||
| 976 | } else | ||
| 977 | need_dma_mr = 0; | ||
| 978 | break; | ||
| 979 | default: | ||
| 931 | goto errout; | 980 | goto errout; |
| 932 | } | 981 | } |
| 933 | 982 | ||
| 983 | /* Create the DMA MR if needed, otherwise, use the DMA LKEY */ | ||
| 984 | if (need_dma_mr) { | ||
| 985 | /* Register all of physical memory */ | ||
| 986 | newxprt->sc_phys_mr = | ||
| 987 | ib_get_dma_mr(newxprt->sc_pd, dma_mr_acc); | ||
| 988 | if (IS_ERR(newxprt->sc_phys_mr)) { | ||
| 989 | dprintk("svcrdma: Failed to create DMA MR ret=%d\n", | ||
| 990 | ret); | ||
| 991 | goto errout; | ||
| 992 | } | ||
| 993 | newxprt->sc_dma_lkey = newxprt->sc_phys_mr->lkey; | ||
| 994 | } else | ||
| 995 | newxprt->sc_dma_lkey = | ||
| 996 | newxprt->sc_cm_id->device->local_dma_lkey; | ||
| 997 | |||
| 934 | /* Post receive buffers */ | 998 | /* Post receive buffers */ |
| 935 | for (i = 0; i < newxprt->sc_max_requests; i++) { | 999 | for (i = 0; i < newxprt->sc_max_requests; i++) { |
| 936 | ret = svc_rdma_post_recv(newxprt); | 1000 | ret = svc_rdma_post_recv(newxprt); |
