IB/core: Add netdev to path record
authorMatan Barak <matanb@mellanox.com>
Thu, 15 Oct 2015 15:38:47 +0000 (18:38 +0300)
committerDoug Ledford <dledford@redhat.com>
Thu, 22 Oct 2015 03:48:17 +0000 (23:48 -0400)
In order to find the sgid_index, one could just query the IB cache
with the correct GID and netdevice. Therefore, instead of storing
the L2 attributes directly in the path, we only store the
ifindex and net and use them later to get the sgid_index.
The vlan_id and smac L2 attributes are removed in a later patch.

Signed-off-by: Matan Barak <matanb@mellanox.com>
Reviewed-By: Devesh Sharma <devesh.sharma@avagotech.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/core/sa_query.c
drivers/infiniband/core/uverbs_marshall.c
include/rdma/ib_sa.h

index 9a4e7891ada20ad7b72bc20fcb31defa5f6808ad..c9d9d7afcdb42ba1a372ea16a8c3fe9439041e56 100644 (file)
@@ -1007,18 +1007,25 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
        force_grh = rdma_cap_eth_ah(device, port_num);
 
        if (rec->hop_limit > 1 || force_grh) {
+               struct net_device *ndev = ib_get_ndev_from_path(rec);
+
                ah_attr->ah_flags = IB_AH_GRH;
                ah_attr->grh.dgid = rec->dgid;
 
-               ret = ib_find_cached_gid(device, &rec->sgid, NULL, &port_num,
+               ret = ib_find_cached_gid(device, &rec->sgid, ndev, &port_num,
                                         &gid_index);
-               if (ret)
+               if (ret) {
+                       if (ndev)
+                               dev_put(ndev);
                        return ret;
+               }
 
                ah_attr->grh.sgid_index    = gid_index;
                ah_attr->grh.flow_label    = be32_to_cpu(rec->flow_label);
                ah_attr->grh.hop_limit     = rec->hop_limit;
                ah_attr->grh.traffic_class = rec->traffic_class;
+               if (ndev)
+                       dev_put(ndev);
        }
        if (force_grh) {
                memcpy(ah_attr->dmac, rec->dmac, ETH_ALEN);
@@ -1151,6 +1158,8 @@ static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query,
                ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table),
                          mad->data, &rec);
                rec.vlan_id = 0xffff;
+               rec.net = NULL;
+               rec.ifindex = 0;
                memset(rec.dmac, 0, ETH_ALEN);
                memset(rec.smac, 0, ETH_ALEN);
                query->callback(status, &rec, query->context);
index abd97247443e437ffff62e8238610657ca355394..484698c94d7f9e7435bd752f65b0c06a0526e051 100644 (file)
@@ -144,5 +144,7 @@ void ib_copy_path_rec_from_user(struct ib_sa_path_rec *dst,
        memset(dst->smac, 0, sizeof(dst->smac));
        memset(dst->dmac, 0, sizeof(dst->dmac));
        dst->vlan_id = 0xffff;
+       dst->net = NULL;
+       dst->ifindex = 0;
 }
 EXPORT_SYMBOL(ib_copy_path_rec_from_user);
index 7e071a6abb34cb977ad26c304bddfcf22a89903a..406ecf177f21b7ed703c286c743103315ef15788 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/compiler.h>
 
 #include <linux/atomic.h>
+#include <linux/netdevice.h>
 
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_mad.h>
@@ -157,8 +158,17 @@ struct ib_sa_path_rec {
        u8           smac[ETH_ALEN];
        u8           dmac[ETH_ALEN];
        u16          vlan_id;
+       /* ignored in IB */
+       int          ifindex;
+       /* ignored in IB */
+       struct net  *net;
 };
 
+static inline struct net_device *ib_get_ndev_from_path(struct ib_sa_path_rec *rec)
+{
+       return rec->net ? dev_get_by_index(rec->net, rec->ifindex) : NULL;
+}
+
 #define IB_SA_MCMEMBER_REC_MGID                                IB_SA_COMP_MASK( 0)
 #define IB_SA_MCMEMBER_REC_PORT_GID                    IB_SA_COMP_MASK( 1)
 #define IB_SA_MCMEMBER_REC_QKEY                                IB_SA_COMP_MASK( 2)