Skip to content

Commit

Permalink
libertas: register sysfs groups properly
Browse files Browse the repository at this point in the history
The libertas driver was trying to register sysfs groups "by hand" which
causes them to be created _after_ the device is initialized and
announced to userspace, which causes races and can prevent userspace
tools from seeing the sysfs files correctly.

Fix this up by using the built-in sysfs_groups pointers in struct
net_device which were created for this very reason, fixing the race
condition, and properly allowing for any error that might have occured
to be handled properly.

Cc: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20210503115736.2104747-54-gregkh@linuxfoundation.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
gregkh committed May 13, 2021
1 parent 4665107 commit 7e79b38
Showing 1 changed file with 4 additions and 24 deletions.
28 changes: 4 additions & 24 deletions drivers/net/wireless/marvell/libertas/mesh.c
Expand Up @@ -801,19 +801,6 @@ static const struct attribute_group mesh_ie_group = {
.attrs = mesh_ie_attrs,
};

static void lbs_persist_config_init(struct net_device *dev)
{
int ret;
ret = sysfs_create_group(&(dev->dev.kobj), &boot_opts_group);
ret = sysfs_create_group(&(dev->dev.kobj), &mesh_ie_group);
}

static void lbs_persist_config_remove(struct net_device *dev)
{
sysfs_remove_group(&(dev->dev.kobj), &boot_opts_group);
sysfs_remove_group(&(dev->dev.kobj), &mesh_ie_group);
}


/***************************************************************************
* Initializing and starting, stopping mesh
Expand Down Expand Up @@ -1009,26 +996,21 @@ static int lbs_add_mesh(struct lbs_private *priv)
SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent);

mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
mesh_dev->sysfs_groups[0] = &lbs_mesh_attr_group;
mesh_dev->sysfs_groups[1] = &boot_opts_group;
mesh_dev->sysfs_groups[2] = &mesh_ie_group;

/* Register virtual mesh interface */
ret = register_netdev(mesh_dev);
if (ret) {
pr_err("cannot register mshX virtual interface\n");
goto err_free_netdev;
}

ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
if (ret)
goto err_unregister;

lbs_persist_config_init(mesh_dev);

/* Everything successful */
ret = 0;
goto done;

err_unregister:
unregister_netdev(mesh_dev);

err_free_netdev:
free_netdev(mesh_dev);

Expand All @@ -1049,8 +1031,6 @@ void lbs_remove_mesh(struct lbs_private *priv)

netif_stop_queue(mesh_dev);
netif_carrier_off(mesh_dev);
sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
lbs_persist_config_remove(mesh_dev);
unregister_netdev(mesh_dev);
priv->mesh_dev = NULL;
kfree(mesh_dev->ieee80211_ptr);
Expand Down

0 comments on commit 7e79b38

Please sign in to comment.