]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
sif: ah: Fixed incorrect ipd setting
authorHakon Bugge <Haakon.Bugge@oracle.com>
Sun, 5 Jun 2016 16:02:42 +0000 (18:02 +0200)
committerKnut Omang <knut.omang@oracle.com>
Sun, 3 Jul 2016 14:01:41 +0000 (16:01 +0200)
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 <Haakon.Bugge@oracle.com>
Reviewed-by: Knut Omang <knut.omang@oracle.com>
drivers/infiniband/hw/sif/sif_ah.c
drivers/infiniband/hw/sif/sif_query.c

index 5a7f16761eafbfa665955649efcd7432fd579cae..cff5dd692d120c0de7d78709eee5d051f4c4db09 100644 (file)
@@ -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;
 
index dcb03e39b0d5a4913e4ff67577ed1298a8aa7a1f..60be5ee8f38403f8b74c3ffb16c9bc4ceddce55a 100644 (file)
@@ -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;