]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
RDMA/mana_ib: Set correct device into ib
authorKonstantin Taranov <kotaranov@microsoft.com>
Thu, 11 Jul 2024 13:37:57 +0000 (06:37 -0700)
committerLeon Romanovsky <leon@kernel.org>
Sun, 14 Jul 2024 07:49:53 +0000 (10:49 +0300)
Add mana_get_primary_netdev_rcu helper to get a primary
netdevice for a given port. When mana is used with
netvsc, the VF netdev is controlled by an upper netvsc
device. In a baremetal case, the VF netdev is the
primary device.

Use the mana_get_primary_netdev_rcu() helper in the mana_ib
to get the correct device for querying network states.

Fixes: 8b184e4f1c32 ("RDMA/mana_ib: Enable RoCE on port 1")
Signed-off-by: Konstantin Taranov <kotaranov@microsoft.com>
Link: https://lore.kernel.org/r/1720705077-322-1-git-send-email-kotaranov@linux.microsoft.com
Reviewed-by: Long Li <longli@microsoft.com>
Reviewed-by: Zhu Yanjun <yanjun.zhu@linux.dev>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
drivers/infiniband/hw/mana/device.c
drivers/net/ethernet/microsoft/mana/mana_en.c
include/net/mana/mana.h

index b07a8e2e838fbbc8900098bd1aa218107111d307..7ac01918ef7c0db1ccf64d5615a1435714843fcd 100644 (file)
@@ -56,7 +56,7 @@ static int mana_ib_probe(struct auxiliary_device *adev,
 {
        struct mana_adev *madev = container_of(adev, struct mana_adev, adev);
        struct gdma_dev *mdev = madev->mdev;
-       struct net_device *upper_ndev;
+       struct net_device *ndev;
        struct mana_context *mc;
        struct mana_ib_dev *dev;
        u8 mac_addr[ETH_ALEN];
@@ -84,17 +84,17 @@ static int mana_ib_probe(struct auxiliary_device *adev,
        dev->ib_dev.num_comp_vectors = mdev->gdma_context->max_num_queues;
        dev->ib_dev.dev.parent = mdev->gdma_context->dev;
 
-       rcu_read_lock(); /* required to get upper dev */
-       upper_ndev = netdev_master_upper_dev_get_rcu(mc->ports[0]);
-       if (!upper_ndev) {
+       rcu_read_lock(); /* required to get primary netdev */
+       ndev = mana_get_primary_netdev_rcu(mc, 0);
+       if (!ndev) {
                rcu_read_unlock();
                ret = -ENODEV;
-               ibdev_err(&dev->ib_dev, "Failed to get master netdev");
+               ibdev_err(&dev->ib_dev, "Failed to get netdev for IB port 1");
                goto free_ib_device;
        }
-       ether_addr_copy(mac_addr, upper_ndev->dev_addr);
-       addrconf_addr_eui48((u8 *)&dev->ib_dev.node_guid, upper_ndev->dev_addr);
-       ret = ib_device_set_netdev(&dev->ib_dev, upper_ndev, 1);
+       ether_addr_copy(mac_addr, ndev->dev_addr);
+       addrconf_addr_eui48((u8 *)&dev->ib_dev.node_guid, ndev->dev_addr);
+       ret = ib_device_set_netdev(&dev->ib_dev, ndev, 1);
        rcu_read_unlock();
        if (ret) {
                ibdev_err(&dev->ib_dev, "Failed to set ib netdev, ret %d", ret);
index b89ad4afd66eede51f01cf055382886ae1910bd9..68c2bea2c022a0e3de0b4005f9784add63acc1a5 100644 (file)
@@ -3007,3 +3007,22 @@ out:
        gd->gdma_context = NULL;
        kfree(ac);
 }
+
+struct net_device *mana_get_primary_netdev_rcu(struct mana_context *ac, u32 port_index)
+{
+       struct net_device *ndev;
+
+       RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
+                        "Taking primary netdev without holding the RCU read lock");
+       if (port_index >= ac->num_ports)
+               return NULL;
+
+       /* When mana is used in netvsc, the upper netdevice should be returned. */
+       if (ac->ports[port_index]->flags & IFF_SLAVE)
+               ndev = netdev_master_upper_dev_get_rcu(ac->ports[port_index]);
+       else
+               ndev = ac->ports[port_index];
+
+       return ndev;
+}
+EXPORT_SYMBOL_NS(mana_get_primary_netdev_rcu, NET_MANA);
index 59823901b74f800d16597e77352bd4ef55af92d7..f9b4b0dcb69f7225202ccf36a8de553acc8dd94d 100644 (file)
@@ -797,4 +797,6 @@ void mana_destroy_wq_obj(struct mana_port_context *apc, u32 wq_type,
 int mana_cfg_vport(struct mana_port_context *apc, u32 protection_dom_id,
                   u32 doorbell_pg_id);
 void mana_uncfg_vport(struct mana_port_context *apc);
+
+struct net_device *mana_get_primary_netdev_rcu(struct mana_context *ac, u32 port_index);
 #endif /* _MANA_H */