diff mbox series

[1/3] RDMA/core: Move ib device to the same net namespace with net device

Message ID 20221023220450.2287909-2-yanjun.zhu@intel.com (mailing list archive)
State Changes Requested
Delegated to: Jason Gunthorpe
Headers show
Series RDMA net namespace | expand

Commit Message

Zhu Yanjun Oct. 23, 2022, 10:04 p.m. UTC
From: Zhu Yanjun <yanjun.zhu@linux.dev>

When a net device is moved from a net namespace to another net namespace,
the related ib device should also be moved to the same net namespace.

Signed-off-by: Zhu Yanjun <yanjun.zhu@linux.dev>
---
 drivers/infiniband/core/device.c | 57 ++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)
diff mbox series

Patch

diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index d275db195f1a..59784fd10876 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -2735,6 +2735,54 @@  int ib_dma_virt_map_sg(struct ib_device *dev, struct scatterlist *sg, int nents)
 EXPORT_SYMBOL(ib_dma_virt_map_sg);
 #endif /* CONFIG_INFINIBAND_VIRT_DMA */
 
+static int rdma_netns_notify(struct notifier_block *not_blk,
+			     unsigned long event, void *arg)
+{
+	struct net_device *ndev = netdev_notifier_info_to_dev(arg);
+	struct ib_device *ibdev = ib_device_get_by_netdev(ndev, RDMA_DRIVER_UNKNOWN);
+
+	if (!ibdev)
+		return NOTIFY_OK;
+
+	switch (event) {
+	case NETDEV_REGISTER:
+		ib_device_put(ibdev);
+		if (!net_eq(read_pnet(&ibdev->coredev.rdma_net), dev_net(ndev))) {
+			int ret = 0;
+
+			get_device(&ibdev->dev);
+			ret = rdma_dev_change_netns(ibdev,
+						    read_pnet(&ibdev->coredev.rdma_net),
+						    dev_net(ndev));
+			if (ret) {
+				put_device(&ibdev->dev);
+				return NOTIFY_OK;
+			}
+			put_device(&ibdev->dev);
+		}
+		break;
+	case NETDEV_UNREGISTER:
+		ib_device_put(ibdev);
+		break;
+	case NETDEV_REBOOT:
+	case NETDEV_GOING_DOWN:
+	case NETDEV_CHANGEADDR:
+	case NETDEV_CHANGENAME:
+	case NETDEV_FEAT_CHANGE:
+	default:
+		ib_device_put(ibdev);
+		pr_info("ignoring netdev event = %ld for %s\n",
+			event, ndev->name);
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block rdma_netns_notifier = {
+	.notifier_call = rdma_netns_notify,
+};
+
 static const struct rdma_nl_cbs ibnl_ls_cb_table[RDMA_NL_LS_NUM_OPS] = {
 	[RDMA_NL_LS_OP_RESOLVE] = {
 		.doit = ib_nl_handle_resolve_resp,
@@ -2817,8 +2865,16 @@  static int __init ib_core_init(void)
 	rdma_nl_register(RDMA_NL_LS, ibnl_ls_cb_table);
 	roce_gid_mgmt_init();
 
+	ret = register_netdevice_notifier(&rdma_netns_notifier);
+	if (ret) {
+		pr_err("Failed to register netdev notifier\n");
+		goto err_netdevice;
+	}
+
 	return 0;
 
+err_netdevice:
+	unregister_pernet_device(&rdma_dev_net_ops);
 err_compat:
 	unregister_blocking_lsm_notifier(&ibdev_lsm_nb);
 err_sa:
@@ -2842,6 +2898,7 @@  static int __init ib_core_init(void)
 
 static void __exit ib_core_cleanup(void)
 {
+	unregister_netdevice_notifier(&rdma_netns_notifier);
 	roce_gid_mgmt_cleanup();
 	nldev_exit();
 	rdma_nl_unregister(RDMA_NL_LS);