Skip to content

Commit

Permalink
netdevsim: move vfconfig to nsim_dev
Browse files Browse the repository at this point in the history
When netdevsim got split into the faux bus vfconfig ended
up in the bus device (think pci_dev) which is strange because
it contains very networky not to say netdevy information.
Move it to nsim_dev, which is the driver "priv" structure
for the device.

To make sure we don't race with probe/remove take
the device lock (much like PCI).

While at it remove the NULL-checking of vfconfigs.
It appears to be pointless.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Jakub Kicinski authored and David S. Miller committed Nov 1, 2021
1 parent 26c37d8 commit 5e388f3
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 91 deletions.
43 changes: 19 additions & 24 deletions drivers/net/netdevsim/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@ static int nsim_bus_dev_vfs_enable(struct nsim_bus_dev *nsim_bus_dev,

if (nsim_bus_dev->max_vfs < num_vfs)
return -ENOMEM;

if (!nsim_bus_dev->vfconfigs)
return -ENOMEM;
nsim_bus_dev_set_vfs(nsim_bus_dev, num_vfs);

nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev);
Expand Down Expand Up @@ -70,14 +67,21 @@ nsim_bus_dev_numvfs_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
struct nsim_dev *nsim_dev = dev_get_drvdata(dev);
unsigned int num_vfs;
int ret;

ret = kstrtouint(buf, 0, &num_vfs);
if (ret)
return ret;

mutex_lock(&nsim_bus_dev->vfs_lock);
device_lock(dev);
if (!nsim_dev) {
ret = -ENOENT;
goto exit_unlock;
}

mutex_lock(&nsim_dev->vfs_lock);
if (nsim_bus_dev->num_vfs == num_vfs)
goto exit_good;
if (nsim_bus_dev->num_vfs && num_vfs) {
Expand All @@ -95,7 +99,8 @@ nsim_bus_dev_numvfs_store(struct device *dev, struct device_attribute *attr,
exit_good:
ret = count;
exit_unlock:
mutex_unlock(&nsim_bus_dev->vfs_lock);
mutex_unlock(&nsim_dev->vfs_lock);
device_unlock(dev);

return ret;
}
Expand All @@ -117,7 +122,8 @@ ssize_t nsim_bus_dev_max_vfs_read(struct file *file,
char __user *data,
size_t count, loff_t *ppos)
{
struct nsim_bus_dev *nsim_bus_dev = file->private_data;
struct nsim_dev *nsim_dev = file->private_data;
struct nsim_bus_dev *nsim_bus_dev = nsim_dev->nsim_bus_dev;
char buf[11];
ssize_t len;

Expand All @@ -132,7 +138,8 @@ ssize_t nsim_bus_dev_max_vfs_write(struct file *file,
const char __user *data,
size_t count, loff_t *ppos)
{
struct nsim_bus_dev *nsim_bus_dev = file->private_data;
struct nsim_dev *nsim_dev = file->private_data;
struct nsim_bus_dev *nsim_bus_dev = nsim_dev->nsim_bus_dev;
struct nsim_vf_config *vfconfigs;
ssize_t ret;
char buf[10];
Expand All @@ -144,7 +151,7 @@ ssize_t nsim_bus_dev_max_vfs_write(struct file *file,
if (count >= sizeof(buf))
return -ENOSPC;

mutex_lock(&nsim_bus_dev->vfs_lock);
mutex_lock(&nsim_dev->vfs_lock);
/* Reject if VFs are configured */
if (nsim_bus_dev->num_vfs) {
ret = -EBUSY;
Expand Down Expand Up @@ -176,13 +183,13 @@ ssize_t nsim_bus_dev_max_vfs_write(struct file *file,
goto unlock;
}

kfree(nsim_bus_dev->vfconfigs);
nsim_bus_dev->vfconfigs = vfconfigs;
kfree(nsim_dev->vfconfigs);
nsim_dev->vfconfigs = vfconfigs;
nsim_bus_dev->max_vfs = val;
*ppos += count;
ret = count;
unlock:
mutex_unlock(&nsim_bus_dev->vfs_lock);
mutex_unlock(&nsim_dev->vfs_lock);
return ret;
}

Expand Down Expand Up @@ -428,26 +435,15 @@ nsim_bus_dev_new(unsigned int id, unsigned int port_count, unsigned int num_queu
nsim_bus_dev->initial_net = current->nsproxy->net_ns;
nsim_bus_dev->max_vfs = NSIM_BUS_DEV_MAX_VFS;
mutex_init(&nsim_bus_dev->nsim_bus_reload_lock);
mutex_init(&nsim_bus_dev->vfs_lock);
/* Disallow using nsim_bus_dev */
smp_store_release(&nsim_bus_dev->init, false);

nsim_bus_dev->vfconfigs = kcalloc(nsim_bus_dev->max_vfs,
sizeof(struct nsim_vf_config),
GFP_KERNEL | __GFP_NOWARN);
if (!nsim_bus_dev->vfconfigs) {
err = -ENOMEM;
goto err_nsim_bus_dev_id_free;
}

err = device_register(&nsim_bus_dev->dev);
if (err)
goto err_nsim_vfs_free;
goto err_nsim_bus_dev_id_free;

return nsim_bus_dev;

err_nsim_vfs_free:
kfree(nsim_bus_dev->vfconfigs);
err_nsim_bus_dev_id_free:
ida_free(&nsim_bus_dev_ids, nsim_bus_dev->dev.id);
err_nsim_bus_dev_free:
Expand All @@ -461,7 +457,6 @@ static void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev)
smp_store_release(&nsim_bus_dev->init, false);
device_unregister(&nsim_bus_dev->dev);
ida_free(&nsim_bus_dev_ids, nsim_bus_dev->dev.id);
kfree(nsim_bus_dev->vfconfigs);
kfree(nsim_bus_dev);
}

Expand Down
53 changes: 37 additions & 16 deletions drivers/net/netdevsim/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ static inline unsigned int nsim_dev_port_index_to_vf_index(unsigned int port_ind

static struct dentry *nsim_dev_ddir;

unsigned int nsim_dev_get_vfs(struct nsim_dev *nsim_dev)
{
WARN_ON(!lockdep_rtnl_is_held() &&
!lockdep_is_held(&nsim_dev->vfs_lock));

return nsim_dev->nsim_bus_dev->num_vfs;
}

#define NSIM_DEV_DUMMY_REGION_SIZE (1024 * 32)

static int
Expand Down Expand Up @@ -260,7 +268,7 @@ static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev)
nsim_dev->ddir,
&nsim_dev->fail_trap_policer_counter_get);
debugfs_create_file("max_vfs", 0600, nsim_dev->ddir,
nsim_dev->nsim_bus_dev, &nsim_dev_max_vfs_fops);
nsim_dev, &nsim_dev_max_vfs_fops);

nsim_dev->nodes_ddir = debugfs_create_dir("rate_nodes", nsim_dev->ddir);
if (IS_ERR(nsim_dev->nodes_ddir)) {
Expand Down Expand Up @@ -326,9 +334,9 @@ static int nsim_dev_port_debugfs_init(struct nsim_dev *nsim_dev,
unsigned int vf_id = nsim_dev_port_index_to_vf_index(port_index);

debugfs_create_u16("tx_share", 0400, nsim_dev_port->ddir,
&nsim_bus_dev->vfconfigs[vf_id].min_tx_rate);
&nsim_dev->vfconfigs[vf_id].min_tx_rate);
debugfs_create_u16("tx_max", 0400, nsim_dev_port->ddir,
&nsim_bus_dev->vfconfigs[vf_id].max_tx_rate);
&nsim_dev->vfconfigs[vf_id].max_tx_rate);
nsim_dev_port->rate_parent = debugfs_create_file("rate_parent",
0400,
nsim_dev_port->ddir,
Expand Down Expand Up @@ -508,7 +516,7 @@ int nsim_esw_switchdev_enable(struct nsim_dev *nsim_dev, struct netlink_ext_ack
struct nsim_bus_dev *nsim_bus_dev = nsim_dev->nsim_bus_dev;
int i, err;

for (i = 0; i < nsim_bus_dev->num_vfs; i++) {
for (i = 0; i < nsim_dev_get_vfs(nsim_dev); i++) {
err = nsim_dev_port_add(nsim_bus_dev, NSIM_DEV_PORT_TYPE_VF, i);
if (err) {
NL_SET_ERR_MSG_MOD(extack, "Failed to initialize VFs' netdevsim ports");
Expand All @@ -531,7 +539,7 @@ static int nsim_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
struct nsim_dev *nsim_dev = devlink_priv(devlink);
int err = 0;

mutex_lock(&nsim_dev->nsim_bus_dev->vfs_lock);
mutex_lock(&nsim_dev->vfs_lock);
if (mode == nsim_dev->esw_mode)
goto unlock;

Expand All @@ -543,7 +551,7 @@ static int nsim_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
err = -EINVAL;

unlock:
mutex_unlock(&nsim_dev->nsim_bus_dev->vfs_lock);
mutex_unlock(&nsim_dev->vfs_lock);
return err;
}

Expand Down Expand Up @@ -1091,31 +1099,31 @@ static int nsim_leaf_tx_share_set(struct devlink_rate *devlink_rate, void *priv,
u64 tx_share, struct netlink_ext_ack *extack)
{
struct nsim_dev_port *nsim_dev_port = priv;
struct nsim_bus_dev *nsim_bus_dev = nsim_dev_port->ns->nsim_bus_dev;
struct nsim_dev *nsim_dev = nsim_dev_port->ns->nsim_dev;
int vf_id = nsim_dev_port_index_to_vf_index(nsim_dev_port->port_index);
int err;

err = nsim_rate_bytes_to_units("tx_share", &tx_share, extack);
if (err)
return err;

nsim_bus_dev->vfconfigs[vf_id].min_tx_rate = tx_share;
nsim_dev->vfconfigs[vf_id].min_tx_rate = tx_share;
return 0;
}

static int nsim_leaf_tx_max_set(struct devlink_rate *devlink_rate, void *priv,
u64 tx_max, struct netlink_ext_ack *extack)
{
struct nsim_dev_port *nsim_dev_port = priv;
struct nsim_bus_dev *nsim_bus_dev = nsim_dev_port->ns->nsim_bus_dev;
struct nsim_dev *nsim_dev = nsim_dev_port->ns->nsim_dev;
int vf_id = nsim_dev_port_index_to_vf_index(nsim_dev_port->port_index);
int err;

err = nsim_rate_bytes_to_units("tx_max", &tx_max, extack);
if (err)
return err;

nsim_bus_dev->vfconfigs[vf_id].max_tx_rate = tx_max;
nsim_dev->vfconfigs[vf_id].max_tx_rate = tx_max;
return 0;
}

Expand Down Expand Up @@ -1271,13 +1279,12 @@ static const struct devlink_ops nsim_dev_devlink_ops = {
static int __nsim_dev_port_add(struct nsim_dev *nsim_dev, enum nsim_dev_port_type type,
unsigned int port_index)
{
struct nsim_bus_dev *nsim_bus_dev = nsim_dev->nsim_bus_dev;
struct devlink_port_attrs attrs = {};
struct nsim_dev_port *nsim_dev_port;
struct devlink_port *devlink_port;
int err;

if (type == NSIM_DEV_PORT_TYPE_VF && !nsim_bus_dev->num_vfs)
if (type == NSIM_DEV_PORT_TYPE_VF && !nsim_dev_get_vfs(nsim_dev))
return -EINVAL;

nsim_dev_port = kzalloc(sizeof(*nsim_dev_port), GFP_KERNEL);
Expand Down Expand Up @@ -1455,6 +1462,7 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
nsim_dev->switch_id.id_len = sizeof(nsim_dev->switch_id.id);
get_random_bytes(nsim_dev->switch_id.id, nsim_dev->switch_id.id_len);
INIT_LIST_HEAD(&nsim_dev->port_list);
mutex_init(&nsim_dev->vfs_lock);
mutex_init(&nsim_dev->port_list_lock);
nsim_dev->fw_update_status = true;
nsim_dev->fw_update_overwrite_mask = 0;
Expand All @@ -1464,9 +1472,17 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)

dev_set_drvdata(&nsim_bus_dev->dev, nsim_dev);

nsim_dev->vfconfigs = kcalloc(nsim_bus_dev->max_vfs,
sizeof(struct nsim_vf_config),
GFP_KERNEL | __GFP_NOWARN);
if (!nsim_dev->vfconfigs) {
err = -ENOMEM;
goto err_devlink_free;
}

err = nsim_dev_resources_register(devlink);
if (err)
goto err_devlink_free;
goto err_vfc_free;

err = devlink_params_register(devlink, nsim_devlink_params,
ARRAY_SIZE(nsim_devlink_params));
Expand Down Expand Up @@ -1532,8 +1548,11 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
ARRAY_SIZE(nsim_devlink_params));
err_dl_unregister:
devlink_resources_unregister(devlink, NULL);
err_vfc_free:
kfree(nsim_dev->vfconfigs);
err_devlink_free:
devlink_free(devlink);
dev_set_drvdata(&nsim_bus_dev->dev, NULL);
return err;
}

Expand All @@ -1545,10 +1564,10 @@ static void nsim_dev_reload_destroy(struct nsim_dev *nsim_dev)
return;
debugfs_remove(nsim_dev->take_snapshot);

mutex_lock(&nsim_dev->nsim_bus_dev->vfs_lock);
if (nsim_dev->nsim_bus_dev->num_vfs)
mutex_lock(&nsim_dev->vfs_lock);
if (nsim_dev_get_vfs(nsim_dev))
nsim_bus_dev_vfs_disable(nsim_dev->nsim_bus_dev);
mutex_unlock(&nsim_dev->nsim_bus_dev->vfs_lock);
mutex_unlock(&nsim_dev->vfs_lock);

nsim_dev_port_del_all(nsim_dev);
nsim_dev_psample_exit(nsim_dev);
Expand All @@ -1572,7 +1591,9 @@ void nsim_dev_remove(struct nsim_bus_dev *nsim_bus_dev)
devlink_params_unregister(devlink, nsim_devlink_params,
ARRAY_SIZE(nsim_devlink_params));
devlink_resources_unregister(devlink, NULL);
kfree(nsim_dev->vfconfigs);
devlink_free(devlink);
dev_set_drvdata(&nsim_bus_dev->dev, NULL);
}

static struct nsim_dev_port *
Expand Down
Loading

0 comments on commit 5e388f3

Please sign in to comment.