On Thu, Nov 30, 2017 at 05:35:39PM -0800, Jakub Kicinski wrote:
[...]
> +static int nsim_vfs_enable(struct netdevsim *ns, unsigned int num_vfs)
> +{
> + ns->vfconfigs = kcalloc(num_vfs, sizeof(struct nsim_vf_config),
> + GFP_KERNEL);
> + if (!ns->vfconfigs)
> + return -ENOMEM;
> + ns->num_vfs = num_vfs;
> +
> + return 0;
> +}
> +
> +static void nsim_vfs_disable(struct netdevsim *ns)
> +{
> + kfree(ns->vfconfigs);
> + ns->vfconfigs = NULL;
> + ns->num_vfs = 0;
> +}
Why not something like:
| static int nsim_vfs_set(struct netdevsim *ns, unsigned int num_vfs)
| {
| void *ptr = krealloc(ns->vfconfigs,
| num_vfs * sizeof(struct nsim_vf_config),
| GFP_KERNEL);
|
| if (!ptr)
| return -ENOMEM;
|
| ns->vfconfigs = ptr;
| ns->num_vfs = num_vfs;
| return 0;
| }
> +static ssize_t
> +nsim_numvfs_store(struct device *dev, struct device_attribute *attr,
> + const char *buf, size_t count)
> +{
> + struct netdevsim *ns = to_nsim(dev);
> + unsigned int num_vfs;
> + int ret;
> +
> + ret = kstrtouint(buf, 0, &num_vfs);
> + if (ret)
> + return ret;
> +
> + rtnl_lock();
> + if (ns->num_vfs == num_vfs)
> + goto exit_good;
Then replace this:
> + if (ns->num_vfs && num_vfs) {
> + ret = -EBUSY;
> + goto exit_unlock;
> + }
> +
> + if (num_vfs) {
> + ret = nsim_vfs_enable(ns, num_vfs);
> + if (ret)
> + goto exit_unlock;
> + } else {
> + nsim_vfs_disable(ns);
> + }
with just:
| nsim_vfs_set(ns, num_vfs);
> +exit_good:
> + ret = count;
> +exit_unlock:
> + rtnl_unlock();
> +
> + return ret;
> +}
[...]
> +static void nsim_free(struct net_device *dev)
> +{
> + struct netdevsim *ns = netdev_priv(dev);
> +
> + device_unregister(&ns->dev);
> }
Shouldn't this also kfree(ns->vfconfigs)?
Cheers, Phil