Whamcloud - gitweb
LU-12621 o2iblnd: cache max_qp_wr
[fs/lustre-release.git] / lnet / klnds / o2iblnd / o2iblnd.c
index eaf59fc..0d7b50a 100644 (file)
@@ -570,9 +570,9 @@ kiblnd_get_conn_by_idx(struct lnet_ni *ni, int index)
 static void
 kiblnd_debug_rx(struct kib_rx *rx)
 {
-        CDEBUG(D_CONSOLE, "      %p status %d msg_type %x cred %d\n",
-               rx, rx->rx_status, rx->rx_msg->ibm_type,
-               rx->rx_msg->ibm_credits);
+       CDEBUG(D_CONSOLE, "      %p msg_type %x cred %d\n",
+              rx, rx->rx_msg->ibm_type,
+              rx->rx_msg->ibm_credits);
 }
 
 static void
@@ -674,7 +674,7 @@ kiblnd_setup_mtu_locked(struct rdma_cm_id *cmid)
 static int
 kiblnd_get_completion_vector(struct kib_conn *conn, int cpt)
 {
-       cpumask_t       *mask;
+       cpumask_var_t   *mask;
        int             vectors;
        int             off;
        int             i;
@@ -688,8 +688,8 @@ kiblnd_get_completion_vector(struct kib_conn *conn, int cpt)
 
        /* hash NID to CPU id in this partition... */
        ibp_nid = conn->ibc_peer->ibp_nid;
-       off = do_div(ibp_nid, cpumask_weight(mask));
-       for_each_cpu(i, mask) {
+       off = do_div(ibp_nid, cpumask_weight(*mask));
+       for_each_cpu(i, *mask) {
                if (off-- == 0)
                        return i % vectors;
        }
@@ -734,16 +734,28 @@ static unsigned int kiblnd_send_wrs(struct kib_conn *conn)
         * One WR for the LNet message
         * And ibc_max_frags for the transfer WRs
         */
-       unsigned int ret = 1 + conn->ibc_max_frags;
+       int ret;
+       int multiplier = 1 + conn->ibc_max_frags;
        enum kib_dev_caps dev_caps = conn->ibc_hdev->ibh_dev->ibd_dev_caps;
 
        /* FastReg needs two extra WRs for map and invalidate */
        if (dev_caps & IBLND_DEV_CAPS_FASTREG_ENABLED)
-               ret += 2;
+               multiplier += 2;
 
        /* account for a maximum of ibc_queue_depth in-flight transfers */
-       ret *= conn->ibc_queue_depth;
-       return ret;
+       ret = multiplier * conn->ibc_queue_depth;
+
+       if (ret > conn->ibc_hdev->ibh_max_qp_wr) {
+               CDEBUG(D_NET, "peer_credits %u will result in send work "
+                      "request size %d larger than maximum %d device "
+                      "can handle\n", conn->ibc_queue_depth, ret,
+                      conn->ibc_hdev->ibh_max_qp_wr);
+               conn->ibc_queue_depth =
+                       conn->ibc_hdev->ibh_max_qp_wr / multiplier;
+       }
+
+       /* don't go beyond the maximum the device can handle */
+       return min(ret, conn->ibc_hdev->ibh_max_qp_wr);
 }
 
 struct kib_conn *
@@ -900,20 +912,14 @@ kiblnd_create_conn(struct kib_peer_ni *peer_ni, struct rdma_cm_id *cmid,
        init_qp_attr->qp_type = IB_QPT_RC;
        init_qp_attr->send_cq = cq;
        init_qp_attr->recv_cq = cq;
+       /*
+        * kiblnd_send_wrs() can change the connection's queue depth if
+        * the maximum work requests for the device is maxed out
+        */
+       init_qp_attr->cap.max_send_wr = kiblnd_send_wrs(conn);
+       init_qp_attr->cap.max_recv_wr = IBLND_RECV_WRS(conn);
 
-       conn->ibc_sched = sched;
-
-       do {
-               init_qp_attr->cap.max_send_wr = kiblnd_send_wrs(conn);
-               init_qp_attr->cap.max_recv_wr = IBLND_RECV_WRS(conn);
-
-               rc = rdma_create_qp(cmid, conn->ibc_hdev->ibh_pd, init_qp_attr);
-               if (!rc || conn->ibc_queue_depth < 2)
-                       break;
-
-               conn->ibc_queue_depth--;
-       } while (rc);
-
+       rc = rdma_create_qp(cmid, conn->ibc_hdev->ibh_pd, init_qp_attr);
        if (rc) {
                CERROR("Can't create QP: %d, send_wr: %d, recv_wr: %d, "
                       "send_sge: %d, recv_sge: %d\n",
@@ -924,6 +930,8 @@ kiblnd_create_conn(struct kib_peer_ni *peer_ni, struct rdma_cm_id *cmid,
                goto failed_2;
        }
 
+       conn->ibc_sched = sched;
+
        if (conn->ibc_queue_depth != peer_ni->ibp_queue_depth)
                CWARN("peer %s - queue depth reduced from %u to %u"
                      "  to allow for qp creation\n",
@@ -2562,6 +2570,7 @@ kiblnd_hdev_get_attr(struct kib_hca_dev *hdev)
 #endif
 
        hdev->ibh_mr_size = dev_attr->max_mr_size;
+       hdev->ibh_max_qp_wr = dev_attr->max_qp_wr;
 
        /* Setup device Memory Registration capabilities */
 #ifdef HAVE_IB_DEVICE_OPS
@@ -2590,9 +2599,7 @@ kiblnd_hdev_get_attr(struct kib_hca_dev *hdev)
                rc = -ENOSYS;
        }
 
-       if (rc == 0 && hdev->ibh_mr_size == ~0ULL)
-               hdev->ibh_mr_shift = 64;
-       else if (rc != 0)
+       if (rc != 0)
                rc = -EINVAL;
 
 #ifndef HAVE_IB_DEVICE_ATTRS
@@ -2665,7 +2672,7 @@ kiblnd_dummy_callback(struct rdma_cm_id *cmid, struct rdma_cm_event *event)
 }
 
 static int
-kiblnd_dev_need_failover(struct kib_dev *dev)
+kiblnd_dev_need_failover(struct kib_dev *dev, struct net *ns)
 {
         struct rdma_cm_id  *cmid;
         struct sockaddr_in  srcaddr;
@@ -2687,8 +2694,8 @@ kiblnd_dev_need_failover(struct kib_dev *dev)
          *
          * a. rdma_bind_addr(), it will conflict with listener cmid
          * b. rdma_resolve_addr() to zero addr */
-        cmid = kiblnd_rdma_create_id(kiblnd_dummy_callback, dev, RDMA_PS_TCP,
-                                     IB_QPT_RC);
+       cmid = kiblnd_rdma_create_id(ns, kiblnd_dummy_callback, dev,
+                                    RDMA_PS_TCP, IB_QPT_RC);
         if (IS_ERR(cmid)) {
                 rc = PTR_ERR(cmid);
                 CERROR("Failed to create cmid for failover: %d\n", rc);
@@ -2717,7 +2724,7 @@ kiblnd_dev_need_failover(struct kib_dev *dev)
 }
 
 int
-kiblnd_dev_failover(struct kib_dev *dev)
+kiblnd_dev_failover(struct kib_dev *dev, struct net *ns)
 {
        struct list_head    zombie_tpo = LIST_HEAD_INIT(zombie_tpo);
        struct list_head    zombie_ppo = LIST_HEAD_INIT(zombie_ppo);
@@ -2736,7 +2743,7 @@ kiblnd_dev_failover(struct kib_dev *dev)
                  dev->ibd_can_failover ||
                  dev->ibd_hdev == NULL);
 
-        rc = kiblnd_dev_need_failover(dev);
+       rc = kiblnd_dev_need_failover(dev, ns);
         if (rc <= 0)
                 goto out;
 
@@ -2757,8 +2764,8 @@ kiblnd_dev_failover(struct kib_dev *dev)
                 rdma_destroy_id(cmid);
         }
 
-        cmid = kiblnd_rdma_create_id(kiblnd_cm_callback, dev, RDMA_PS_TCP,
-                                     IB_QPT_RC);
+       cmid = kiblnd_rdma_create_id(ns, kiblnd_cm_callback, dev, RDMA_PS_TCP,
+                                    IB_QPT_RC);
         if (IS_ERR(cmid)) {
                 rc = PTR_ERR(cmid);
                 CERROR("Failed to create cmid for failover: %d\n", rc);
@@ -3024,7 +3031,7 @@ out:
 }
 
 static int
-kiblnd_base_startup(void)
+kiblnd_base_startup(struct net *ns)
 {
        struct kib_sched_info   *sched;
        int                     rc;
@@ -3097,7 +3104,7 @@ kiblnd_base_startup(void)
         }
 
        if (*kiblnd_tunables.kib_dev_failover != 0)
-               rc = kiblnd_thread_start(kiblnd_failover_thread, NULL,
+               rc = kiblnd_thread_start(kiblnd_failover_thread, ns,
                                         "kiblnd_failover");
 
         if (rc != 0) {
@@ -3196,7 +3203,7 @@ kiblnd_startup(struct lnet_ni *ni)
         LASSERT (ni->ni_net->net_lnd == &the_o2iblnd);
 
         if (kiblnd_data.kib_init == IBLND_INIT_NOTHING) {
-                rc = kiblnd_base_startup();
+               rc = kiblnd_base_startup(ni->ni_net_ns);
                 if (rc != 0)
                         return rc;
         }
@@ -3232,7 +3239,7 @@ kiblnd_startup(struct lnet_ni *ni)
                 goto failed;
         }
 
-       rc = lnet_inet_enumerate(&ifaces);
+       rc = lnet_inet_enumerate(&ifaces, ni->ni_net_ns);
        if (rc < 0)
                goto failed;
 
@@ -3263,7 +3270,7 @@ kiblnd_startup(struct lnet_ni *ni)
        INIT_LIST_HEAD(&ibdev->ibd_fail_list);
 
        /* initialize the device */
-       rc = kiblnd_dev_failover(ibdev);
+       rc = kiblnd_dev_failover(ibdev, ni->ni_net_ns);
        if (rc) {
                CERROR("ko2iblnd: Can't initialize device: rc = %d\n", rc);
                goto failed;