From: Zhu Yanjun <yanjun.zhu@xxxxxxxxx> 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@xxxxxxxxx> --- 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