]> git.ipfire.org Git - thirdparty/kernel/stable.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)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 3 Aug 2024 07:00:19 +0000 (09:00 +0200)
[ Upstream commit 1df03a4b44146c4f720d793915747272c7773a3e ]

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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/infiniband/hw/mana/device.c
drivers/net/ethernet/microsoft/mana/mana_en.c
include/net/mana/mana.h

index 9a7da2ec9cdbb07c63c8e352f0424c56fdda3f10..7bb7e06392001f59d55a2d05285f37526382c60a 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 608ad31a97022bc8315979d3e320bbf67ec0923c..ad7ae7ba2b8fc3586f85f1990e300c9b729fa877 100644 (file)
@@ -2950,3 +2950,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 561f6719fb4ec5297268385a7b6f0f5806d0e8e2..f207a6e1042ae8b773cebd7c43fb80e39898a31f 100644 (file)
@@ -796,4 +796,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 */