| From 883f3767b84fac3bd33d25e84b7dd97e287e0adc Mon Sep 17 00:00:00 2001 |
| From: Shamir Rabinovitch <shamir.rabinovitch@oracle.com> |
| Date: Wed, 29 Mar 2017 06:21:59 -0400 |
| Subject: [PATCH] IB/IPoIB: ibX: failed to create mcg debug file |
| |
| 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) |
| 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> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/infiniband/ulp/ipoib/ipoib_fs.c b/drivers/infiniband/ulp/ipoib/ipoib_fs.c |
| index 6bd5740e2691..09396bd7b02d 100644 |
| --- 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_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) |
| diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c |
| index 8ca4df70c418..26d382696865 100644 |
| --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c |
| +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c |
| @@ -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); |
| @@ -1651,8 +1678,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 */ |
| @@ -2070,8 +2095,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)) |
| @@ -2086,7 +2109,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: |
| @@ -2171,6 +2193,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; |
| @@ -2222,6 +2250,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: |
| @@ -2239,6 +2270,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); |
| diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c |
| index a2f9f29c6ab5..57eadd2b7a71 100644 |
| --- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c |
| +++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c |
| @@ -87,8 +87,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)) |
| @@ -109,7 +107,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: |
| -- |
| 2.12.0 |
| |