On Fri, Apr 8, 2022 at 2:19 PM Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> wrote: > > On Wed, Apr 06, 2022 at 04:12:08PM +0300, Sakari Ailus wrote: > > struct acpi_device_properties describes one source of properties present > > on either struct acpi_device or struct acpi_data_node. When properties are > > parsed, both are populated but when released, only those properties that > > are associated with the device node are freed. > > > > Fix this by also releasing memory of the data node properties. > > Reviewed-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> Applied as 5.19 material, thanks! > > Fixes: 5f5e4890d57a ("ACPI / property: Allow multiple property compatible _DSD entries") > > Cc: stable@xxxxxxxxxxxxxxx (for v4.20 and up) > > Signed-off-by: Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx> > > --- > > drivers/acpi/property.c | 18 ++++++++++++------ > > 1 file changed, 12 insertions(+), 6 deletions(-) > > > > diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c > > index 3fceb4681ec9f..2da5e7cd28134 100644 > > --- a/drivers/acpi/property.c > > +++ b/drivers/acpi/property.c > > @@ -433,6 +433,16 @@ void acpi_init_properties(struct acpi_device *adev) > > acpi_extract_apple_properties(adev); > > } > > > > +static void acpi_free_device_properties(struct list_head *list) > > +{ > > + struct acpi_device_properties *props, *tmp; > > + > > + list_for_each_entry_safe(props, tmp, list, list) { > > + list_del(&props->list); > > + kfree(props); > > + } > > +} > > + > > static void acpi_destroy_nondev_subnodes(struct list_head *list) > > { > > struct acpi_data_node *dn, *next; > > @@ -445,22 +455,18 @@ static void acpi_destroy_nondev_subnodes(struct list_head *list) > > wait_for_completion(&dn->kobj_done); > > list_del(&dn->sibling); > > ACPI_FREE((void *)dn->data.pointer); > > + acpi_free_device_properties(&dn->data.properties); > > kfree(dn); > > } > > } > > > > void acpi_free_properties(struct acpi_device *adev) > > { > > - struct acpi_device_properties *props, *tmp; > > - > > acpi_destroy_nondev_subnodes(&adev->data.subnodes); > > ACPI_FREE((void *)adev->data.pointer); > > adev->data.of_compatible = NULL; > > adev->data.pointer = NULL; > > - list_for_each_entry_safe(props, tmp, &adev->data.properties, list) { > > - list_del(&props->list); > > - kfree(props); > > - } > > + acpi_free_device_properties(&adev->data.properties); > > } > > > > /** > > --