IB/IPoIB: ibX: failed to create mcg debug file
authorShamir Rabinovitch <shamir.rabinovitch@oracle.com>
Wed, 29 Mar 2017 10:21:59 +0000 (06:21 -0400)
committerDoug Ledford <dledford@redhat.com>
Wed, 5 Apr 2017 17:47:24 +0000 (13:47 -0400)
When udev renames the netdev devices, ipoib debugfs entries does not
get renamed. As a result, if subsequent probe of ipoib device reuse the
name then creating a debugfs entry for the new device would fail.

Also, moved ipoib_create_debug_files and ipoib_delete_debug_files as part
of ipoib event handling in order to avoid any race condition between these.

Fixes: 1732b0ef3b3a ([IPoIB] add path record information in debugfs)
Cc: stable@vger.kernel.org # 2.6.15+
Signed-off-by: Vijay Kumar <vijay.ac.kumar@oracle.com>
Signed-off-by: Shamir Rabinovitch <shamir.rabinovitch@oracle.com>
Reviewed-by: Mark Bloch <markb@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/ulp/ipoib/ipoib_fs.c
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_vlan.c

index 6bd5740..09396bd 100644 (file)
@@ -281,8 +281,11 @@ void ipoib_delete_debug_files(struct net_device *dev)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
 
+       WARN_ONCE(!priv->mcg_dentry, "null mcg debug file\n");
+       WARN_ONCE(!priv->path_dentry, "null path debug file\n");
        debugfs_remove(priv->mcg_dentry);
        debugfs_remove(priv->path_dentry);
+       priv->mcg_dentry = priv->path_dentry = NULL;
 }
 
 int ipoib_register_debugfs(void)
index d1d3fb7..b319cc2 100644 (file)
@@ -108,6 +108,33 @@ static struct ib_client ipoib_client = {
        .get_net_dev_by_params = ipoib_get_net_dev_by_params,
 };
 
+#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
+static int ipoib_netdev_event(struct notifier_block *this,
+                             unsigned long event, void *ptr)
+{
+       struct netdev_notifier_info *ni = ptr;
+       struct net_device *dev = ni->dev;
+
+       if (dev->netdev_ops->ndo_open != ipoib_open)
+               return NOTIFY_DONE;
+
+       switch (event) {
+       case NETDEV_REGISTER:
+               ipoib_create_debug_files(dev);
+               break;
+       case NETDEV_CHANGENAME:
+               ipoib_delete_debug_files(dev);
+               ipoib_create_debug_files(dev);
+               break;
+       case NETDEV_UNREGISTER:
+               ipoib_delete_debug_files(dev);
+               break;
+       }
+
+       return NOTIFY_DONE;
+}
+#endif
+
 int ipoib_open(struct net_device *dev)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -1674,8 +1701,6 @@ void ipoib_dev_cleanup(struct net_device *dev)
 
        ASSERT_RTNL();
 
-       ipoib_delete_debug_files(dev);
-
        /* Delete any child interfaces first */
        list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list) {
                /* Stop GC on child */
@@ -2090,8 +2115,6 @@ static struct net_device *ipoib_add_port(const char *format,
                goto register_failed;
        }
 
-       ipoib_create_debug_files(priv->dev);
-
        if (ipoib_cm_add_mode_attr(priv->dev))
                goto sysfs_failed;
        if (ipoib_add_pkey_attr(priv->dev))
@@ -2106,7 +2129,6 @@ static struct net_device *ipoib_add_port(const char *format,
        return priv->dev;
 
 sysfs_failed:
-       ipoib_delete_debug_files(priv->dev);
        unregister_netdev(priv->dev);
 
 register_failed:
@@ -2191,6 +2213,12 @@ static void ipoib_remove_one(struct ib_device *device, void *client_data)
        kfree(dev_list);
 }
 
+#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
+static struct notifier_block ipoib_netdev_notifier = {
+       .notifier_call = ipoib_netdev_event,
+};
+#endif
+
 static int __init ipoib_init_module(void)
 {
        int ret;
@@ -2243,6 +2271,9 @@ static int __init ipoib_init_module(void)
        if (ret)
                goto err_client;
 
+#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
+       register_netdevice_notifier(&ipoib_netdev_notifier);
+#endif
        return 0;
 
 err_client:
@@ -2260,6 +2291,9 @@ err_fs:
 
 static void __exit ipoib_cleanup_module(void)
 {
+#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
+       unregister_netdevice_notifier(&ipoib_netdev_notifier);
+#endif
        ipoib_netlink_fini();
        ib_unregister_client(&ipoib_client);
        ib_sa_unregister_client(&ipoib_sa_client);
index 3e10e3d..e543bc7 100644 (file)
@@ -86,8 +86,6 @@ int __ipoib_vlan_add(struct ipoib_dev_priv *ppriv, struct ipoib_dev_priv *priv,
                goto register_failed;
        }
 
-       ipoib_create_debug_files(priv->dev);
-
        /* RTNL childs don't need proprietary sysfs entries */
        if (type == IPOIB_LEGACY_CHILD) {
                if (ipoib_cm_add_mode_attr(priv->dev))
@@ -108,7 +106,6 @@ int __ipoib_vlan_add(struct ipoib_dev_priv *ppriv, struct ipoib_dev_priv *priv,
 
 sysfs_failed:
        result = -ENOMEM;
-       ipoib_delete_debug_files(priv->dev);
        unregister_netdevice(priv->dev);
 
 register_failed: