Commit 1df03a4b authored by Konstantin Taranov's avatar Konstantin Taranov Committed by Leon Romanovsky
Browse files

RDMA/mana_ib: Set correct device into ib



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: 8b184e4f ("RDMA/mana_ib: Enable RoCE on port 1")
Signed-off-by: default avatarKonstantin Taranov <kotaranov@microsoft.com>
Link: https://lore.kernel.org/r/1720705077-322-1-git-send-email-kotaranov@linux.microsoft.com


Reviewed-by: default avatarLong Li <longli@microsoft.com>
Reviewed-by: default avatarZhu Yanjun <yanjun.zhu@linux.dev>
Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
parent 95b087f8
Loading
Loading
Loading
Loading
+8 −8
Original line number Diff line number Diff line
@@ -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);
+19 −0
Original line number Diff line number Diff line
@@ -3007,3 +3007,22 @@ void mana_remove(struct gdma_dev *gd, bool suspending)
	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);
+2 −0
Original line number Diff line number Diff line
@@ -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 */