4.4-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Shamir Rabinovitch <shamir.rabinovi...@oracle.com>

commit 771a52584096c45e4565e8aabb596eece9d73d61 upstream.

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)
Signed-off-by: Vijay Kumar <vijay.ac.ku...@oracle.com>
Signed-off-by: Shamir Rabinovitch <shamir.rabinovi...@oracle.com>
Reviewed-by: Mark Bloch <ma...@mellanox.com>
Signed-off-by: Doug Ledford <dledf...@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
 drivers/infiniband/ulp/ipoib/ipoib_fs.c   |    3 ++
 drivers/infiniband/ulp/ipoib/ipoib_main.c |   44 ++++++++++++++++++++++++++----
 drivers/infiniband/ulp/ipoib/ipoib_vlan.c |    3 --
 3 files changed, 42 insertions(+), 8 deletions(-)

--- a/drivers/infiniband/ulp/ipoib/ipoib_fs.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_fs.c
@@ -281,8 +281,11 @@ void ipoib_delete_debug_files(struct net
 {
        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)
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -106,6 +106,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);
@@ -1595,8 +1622,6 @@ void ipoib_dev_cleanup(struct net_device
 
        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 */
@@ -1908,8 +1933,6 @@ static struct net_device *ipoib_add_port
                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))
@@ -1924,7 +1947,6 @@ static struct net_device *ipoib_add_port
        return priv->dev;
 
 sysfs_failed:
-       ipoib_delete_debug_files(priv->dev);
        unregister_netdev(priv->dev);
 
 register_failed:
@@ -2006,6 +2028,12 @@ static void ipoib_remove_one(struct ib_d
        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;
@@ -2057,6 +2085,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:
@@ -2074,6 +2105,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);
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -85,8 +85,6 @@ int __ipoib_vlan_add(struct ipoib_dev_pr
                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))
@@ -107,7 +105,6 @@ int __ipoib_vlan_add(struct ipoib_dev_pr
 
 sysfs_failed:
        result = -ENOMEM;
-       ipoib_delete_debug_files(priv->dev);
        unregister_netdevice(priv->dev);
 
 register_failed:


Reply via email to