X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lnet%2Fklnds%2Fo2iblnd%2Fo2iblnd.c;h=11a39f5521b63023aa9461a549d6857e0e9857f5;hp=b729fa509845f131290bd551460d464a0b9e4242;hb=50300e83e4cab3157149107eb735825cc4c3aff1;hpb=68c04b8fdd5dc5a7a19bc393182d3a8240a116c6 diff --git a/lnet/klnds/o2iblnd/o2iblnd.c b/lnet/klnds/o2iblnd/o2iblnd.c index b729fa5..11a39f5 100644 --- a/lnet/klnds/o2iblnd/o2iblnd.c +++ b/lnet/klnds/o2iblnd/o2iblnd.c @@ -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 @@ -3183,26 +3192,26 @@ static int kiblnd_dev_start_threads(struct kib_dev *dev, u32 *cpts, int ncpts) static int kiblnd_startup(struct lnet_ni *ni) { - char *ifname; + char *ifname; struct lnet_inetdev *ifaces = NULL; struct kib_dev *ibdev = NULL; struct kib_net *net; - unsigned long flags; - int rc; + unsigned long flags; + int rc; int i; - LASSERT (ni->ni_net->net_lnd == &the_o2iblnd); + LASSERT(ni->ni_net->net_lnd == &the_o2iblnd); - if (kiblnd_data.kib_init == IBLND_INIT_NOTHING) { + if (kiblnd_data.kib_init == IBLND_INIT_NOTHING) { rc = kiblnd_base_startup(ni->ni_net_ns); - if (rc != 0) - return rc; - } + if (rc != 0) + return rc; + } - LIBCFS_ALLOC(net, sizeof(*net)); - ni->ni_data = net; - if (net == NULL) - goto failed; + LIBCFS_ALLOC(net, sizeof(*net)); + ni->ni_data = net; + if (net == NULL) + goto failed; net->ibn_incarnation = ktime_get_real_ns() / NSEC_PER_USEC; @@ -3225,10 +3234,10 @@ kiblnd_startup(struct lnet_ni *ni) ifname = *kiblnd_tunables.kib_default_ipif; } - if (strlen(ifname) >= sizeof(ibdev->ibd_ifname)) { - CERROR("IPoIB interface name too long: %s\n", ifname); - goto failed; - } + if (strlen(ifname) >= sizeof(ibdev->ibd_ifname)) { + CERROR("IPoIB interface name too long: %s\n", ifname); + goto failed; + } rc = lnet_inet_enumerate(&ifaces, ni->ni_net_ns); if (rc < 0) @@ -3279,29 +3288,29 @@ kiblnd_startup(struct lnet_ni *ni) goto failed; rc = kiblnd_net_init_pools(net, ni, ni->ni_cpts, ni->ni_ncpts); - if (rc != 0) { - CERROR("Failed to initialize NI pools: %d\n", rc); - goto failed; - } + if (rc != 0) { + CERROR("Failed to initialize NI pools: %d\n", rc); + goto failed; + } write_lock_irqsave(&kiblnd_data.kib_global_lock, flags); ibdev->ibd_nnets++; list_add_tail(&net->ibn_list, &ibdev->ibd_nets); write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags); - net->ibn_init = IBLND_INIT_ALL; + net->ibn_init = IBLND_INIT_ALL; - return 0; + return 0; failed: if (net != NULL && net->ibn_dev == NULL && ibdev != NULL) - kiblnd_destroy_dev(ibdev); + kiblnd_destroy_dev(ibdev); kfree(ifaces); - kiblnd_shutdown(ni); + kiblnd_shutdown(ni); - CDEBUG(D_NET, "kiblnd_startup failed\n"); - return -ENETDOWN; + CDEBUG(D_NET, "kiblnd_startup failed\n"); + return -ENETDOWN; } static struct lnet_lnd the_o2iblnd = {