aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Tucker <tom@opengridcomputing.com>2008-09-30 14:46:13 -0400
committerTom Tucker <tom@opengridcomputing.com>2008-10-06 15:45:45 -0400
commit3a5c63803d0552a3ad93b85c262f12cd86471443 (patch)
treeaec8f9e66b2ac4258a7e379be5ce9abd5670da49
parent64be8608c163bd480cf5ec4b34366f11e0f3c87f (diff)
svcrdma: Query device for Fast Reg support during connection setup
Query the device capabilities in the svc_rdma_accept function to determine what advanced memory management capabilities are supported by the device. Based on the query, select the most secure model available given the requirements of the transport and capabilities of the adapter. Signed-off-by: Tom Tucker <tom@opengridcomputing.com>
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_transport.c76
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);