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 f0b5c5f2f629..a8ec4b1eec58 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); |