[PATCH 4.4 30/56] IB/IPoIB: ibX: failed to create mcg debug file

From: Greg Kroah-Hartman
Date: Thu May 18 2017 - 07:07:16 EST


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

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

From: Shamir Rabinovitch <shamir.rabinovitch@xxxxxxxxxx>

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.kumar@xxxxxxxxxx>
Signed-off-by: Shamir Rabinovitch <shamir.rabinovitch@xxxxxxxxxx>
Reviewed-by: Mark Bloch <markb@xxxxxxxxxxxx>
Signed-off-by: Doug Ledford <dledford@xxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

---
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: