From: Hakon Bugge Date: Sun, 5 Jun 2016 16:02:42 +0000 (+0200) Subject: sif: ah: Fixed incorrect ipd setting X-Git-Tag: v4.1.12-92~129^2~31 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=b28a064543532b795e1cd46a51f5575d993dce9b;p=users%2Fjedix%2Flinux-maple.git sif: ah: Fixed incorrect ipd setting Use cached copies of active speed and width in order to fulfill ib_core locking rules. That is, create_ah() cannot sleep. Signed-off-by: Hakon Bugge Reviewed-by: Knut Omang --- diff --git a/drivers/infiniband/hw/sif/sif_ah.c b/drivers/infiniband/hw/sif/sif_ah.c index 5a7f16761eafb..cff5dd692d120 100644 --- a/drivers/infiniband/hw/sif/sif_ah.c +++ b/drivers/infiniband/hw/sif/sif_ah.c @@ -18,7 +18,7 @@ #include "sif_defs.h" #include "sif_base.h" #include "sif_ah.h" - +#include "sif_query.h" struct ib_ah *sif_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *ah_attr, struct ib_udata *udata) @@ -31,6 +31,7 @@ struct ib_ah *sif_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *ah_attr, volatile struct psif_ah *ah_p; struct psif_ah lah; int index; + u8 ipd = 0; sif_log(sdev, SIF_AH, "for pd %d", pd->idx); @@ -55,11 +56,13 @@ struct ib_ah *sif_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *ah_attr, lah.pd = pd->idx; lah.remote_lid = ah_attr->dlid; lah.local_lid_path = ah_attr->src_path_bits; - lah.ipd = ah_attr->static_rate; /* TBD: Encoding + is this right? */ lah.loopback = (sdev->port[lah.port].lid | lah.local_lid_path) == ah_attr->dlid ? LOOPBACK : NO_LOOPBACK; + /* If sif_calc_ipd() fails, we use zero */ + sif_calc_ipd(sdev, ah_attr->port_num, (enum ib_rate)ah_attr->static_rate, &ipd); + lah.ipd = ipd; if (ah_attr->ah_flags & IB_AH_GRH) { lah.use_grh = USE_GRH; @@ -132,6 +135,7 @@ int sif_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr) copy_conv_to_sw(&lah, &ah->d, sizeof(lah)); ah_attr->sl = lah.sl; ah_attr->port_num = lah.port + 1; + /* TBD: Convert from delay to rate */ ah_attr->static_rate = lah.ipd; ah_attr->dlid = lah.remote_lid; diff --git a/drivers/infiniband/hw/sif/sif_query.c b/drivers/infiniband/hw/sif/sif_query.c index dcb03e39b0d5a..60be5ee8f3840 100644 --- a/drivers/infiniband/hw/sif/sif_query.c +++ b/drivers/infiniband/hw/sif/sif_query.c @@ -161,8 +161,9 @@ static int epsc_query_port(struct sif_dev *sdev, u8 port, struct psif_epsc_port_ int sif_calc_ipd(struct sif_dev *sdev, u8 port, enum ib_rate static_rate, u8 *ipd) { int path = ib_rate_to_mult(static_rate); - int link, ret; - struct ib_port_attr lpa; + int link; + u8 active_speed = sdev->port[port - 1].active_speed; + u8 active_width = sdev->port[port - 1].active_width; if (static_rate == IB_RATE_PORT_CURRENT) { *ipd = 0; @@ -175,13 +176,13 @@ int sif_calc_ipd(struct sif_dev *sdev, u8 port, enum ib_rate static_rate, u8 *i return -EINVAL; } - ret = sif_query_port(&sdev->ib_dev, port, &lpa); - if (unlikely(ret != 0)) { - sif_log(sdev, SIF_INFO, "Failed to query port %u\n", port); - return ret; + if (unlikely(active_speed < (u8)IB_SPEED_SDR || active_width < (u8)IB_WIDTH_1X)) { + sif_log(sdev, SIF_INFO, "Failed to use cached port attributes for port %u\n", port); + return -EDEADLK; } + /* 2^active_width * active_speed */ - link = (1 << lpa.active_width)*lpa.active_speed; + link = (1 << active_width)*active_speed; if (path >= link) *ipd = 0;