On Wed, 22 Nov 2023, David E. Box wrote: > Fixes memory leak, caught be kmemleak, due to failure to erase auxiliary > device entries from an xarray on removal. > > Signed-off-by: David E. Box <david.e.box@xxxxxxxxxxxxxxx> Changelog is quite terse, please improve ;-). Missing Fixes tag. > --- > V5 - New patch > > drivers/platform/x86/intel/vsec.c | 24 ++++++++++++++++-------- > drivers/platform/x86/intel/vsec.h | 1 + > 2 files changed, 17 insertions(+), 8 deletions(-) > > diff --git a/drivers/platform/x86/intel/vsec.c b/drivers/platform/x86/intel/vsec.c > index c1f9e4471b28..ae811bb65910 100644 > --- a/drivers/platform/x86/intel/vsec.c > +++ b/drivers/platform/x86/intel/vsec.c > @@ -120,6 +120,8 @@ static void intel_vsec_dev_release(struct device *dev) > { > struct intel_vsec_device *intel_vsec_dev = dev_to_ivdev(dev); > > + xa_erase(&auxdev_array, intel_vsec_dev->id); > + > mutex_lock(&vsec_ida_lock); > ida_free(intel_vsec_dev->ida, intel_vsec_dev->auxdev.id); > mutex_unlock(&vsec_ida_lock); > @@ -136,9 +138,21 @@ int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent, > int ret, id; > > mutex_lock(&vsec_ida_lock); > - ret = ida_alloc(intel_vsec_dev->ida, GFP_KERNEL); > + id = ida_alloc(intel_vsec_dev->ida, GFP_KERNEL); > mutex_unlock(&vsec_ida_lock); > + if (id < 0) { > + kfree(intel_vsec_dev->resource); > + kfree(intel_vsec_dev); > + return ret; > + } > + > + ret = xa_alloc(&auxdev_array, &intel_vsec_dev->id, intel_vsec_dev, > + PMT_XA_LIMIT, GFP_KERNEL); > if (ret < 0) { > + mutex_lock(&vsec_ida_lock); > + ida_free(intel_vsec_dev->ida, id); > + mutex_unlock(&vsec_ida_lock); Can't order of xa_alloc() and ida_alloc() be reversed such that you don't need to do this double mutex dance? -- i. > + > kfree(intel_vsec_dev->resource); > kfree(intel_vsec_dev); > return ret; > @@ -147,7 +161,7 @@ int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent, > if (!parent) > parent = &pdev->dev; > > - auxdev->id = ret; > + auxdev->id = id; > auxdev->name = name; > auxdev->dev.parent = parent; > auxdev->dev.release = intel_vsec_dev_release; > @@ -169,12 +183,6 @@ int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent, > if (ret < 0) > return ret; > > - /* Add auxdev to list */ > - ret = xa_alloc(&auxdev_array, &id, intel_vsec_dev, PMT_XA_LIMIT, > - GFP_KERNEL); > - if (ret) > - return ret; > - > return 0; > } > EXPORT_SYMBOL_NS_GPL(intel_vsec_add_aux, INTEL_VSEC); > diff --git a/drivers/platform/x86/intel/vsec.h b/drivers/platform/x86/intel/vsec.h > index 0fd042c171ba..0a6201b4a0e9 100644 > --- a/drivers/platform/x86/intel/vsec.h > +++ b/drivers/platform/x86/intel/vsec.h > @@ -45,6 +45,7 @@ struct intel_vsec_device { > struct ida *ida; > struct intel_vsec_platform_info *info; > int num_resources; > + int id; /* xa */ > void *priv_data; > size_t priv_data_size; > }; >