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

Zhu Yanjun
2022-10-23T05:39:36Z

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 --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);
--
2.27.0