]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/infiniband/hw/mlx4/qp.c
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma
[mirror_ubuntu-bionic-kernel.git] / drivers / infiniband / hw / mlx4 / qp.c
index 7d76f769233cfb5a58a2ce78717e758e8492363e..c34eebc7db65a9bbf4deb0ce611e6ec61e88af7f 100644 (file)
@@ -2420,11 +2420,31 @@ static u8 sl_to_vl(struct mlx4_ib_dev *dev, u8 sl, int port_num)
        return vl;
 }
 
+static int fill_gid_by_hw_index(struct mlx4_ib_dev *ibdev, u8 port_num,
+                               int index, union ib_gid *gid,
+                               enum ib_gid_type *gid_type)
+{
+       struct mlx4_ib_iboe *iboe = &ibdev->iboe;
+       struct mlx4_port_gid_table *port_gid_table;
+       unsigned long flags;
+
+       port_gid_table = &iboe->gids[port_num - 1];
+       spin_lock_irqsave(&iboe->lock, flags);
+       memcpy(gid, &port_gid_table->gids[index].gid, sizeof(*gid));
+       *gid_type = port_gid_table->gids[index].gid_type;
+       spin_unlock_irqrestore(&iboe->lock, flags);
+       if (!memcmp(gid, &zgid, sizeof(*gid)))
+               return -ENOENT;
+
+       return 0;
+}
+
 #define MLX4_ROCEV2_QP1_SPORT 0xC000
 static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_ud_wr *wr,
                            void *wqe, unsigned *mlx_seg_len)
 {
        struct ib_device *ib_dev = sqp->qp.ibqp.device;
+       struct mlx4_ib_dev *ibdev = to_mdev(ib_dev);
        struct mlx4_wqe_mlx_seg *mlx = wqe;
        struct mlx4_wqe_ctrl_seg *ctrl = wqe;
        struct mlx4_wqe_inline_seg *inl = wqe + sizeof *mlx;
@@ -2450,8 +2470,7 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_ud_wr *wr,
        is_eth = rdma_port_get_link_layer(sqp->qp.ibqp.device, sqp->qp.port) == IB_LINK_LAYER_ETHERNET;
        is_grh = mlx4_ib_ah_grh_present(ah);
        if (is_eth) {
-               struct ib_gid_attr gid_attr;
-
+               enum ib_gid_type gid_type;
                if (mlx4_is_mfunc(to_mdev(ib_dev)->dev)) {
                        /* When multi-function is enabled, the ib_core gid
                         * indexes don't necessarily match the hw ones, so
@@ -2462,18 +2481,11 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_ud_wr *wr,
                        if (err)
                                return err;
                } else  {
-                       err = ib_get_cached_gid(ib_dev,
-                                               be32_to_cpu(ah->av.ib.port_pd) >> 24,
-                                               ah->av.ib.gid_index, &sgid,
-                                               &gid_attr);
-                       if (!err) {
-                               if (gid_attr.ndev)
-                                       dev_put(gid_attr.ndev);
-                               if (!memcmp(&sgid, &zgid, sizeof(sgid)))
-                                       err = -ENOENT;
-                       }
+                       err = fill_gid_by_hw_index(ibdev, sqp->qp.port,
+                                           ah->av.ib.gid_index,
+                                           &sgid, &gid_type);
                        if (!err) {
-                               is_udp = gid_attr.gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP;
+                               is_udp = gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP;
                                if (is_udp) {
                                        if (ipv6_addr_v4mapped((struct in6_addr *)&sgid))
                                                ip_version = 4;
@@ -2951,21 +2963,17 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 
                if (sqp->roce_v2_gsi) {
                        struct mlx4_ib_ah *ah = to_mah(ud_wr(wr)->ah);
-                       struct ib_gid_attr gid_attr;
+                       enum ib_gid_type gid_type;
                        union ib_gid gid;
 
-                       if (!ib_get_cached_gid(ibqp->device,
-                                              be32_to_cpu(ah->av.ib.port_pd) >> 24,
-                                              ah->av.ib.gid_index, &gid,
-                                              &gid_attr)) {
-                               if (gid_attr.ndev)
-                                       dev_put(gid_attr.ndev);
-                               qp = (gid_attr.gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP) ?
-                                       to_mqp(sqp->roce_v2_gsi) : qp;
-                       } else {
+                       if (!fill_gid_by_hw_index(mdev, sqp->qp.port,
+                                          ah->av.ib.gid_index,
+                                          &gid, &gid_type))
+                               qp = (gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP) ?
+                                               to_mqp(sqp->roce_v2_gsi) : qp;
+                       else
                                pr_err("Failed to get gid at index %d. RoCEv2 will not work properly\n",
                                       ah->av.ib.gid_index);
-                       }
                }
        }