On Wed, Aug 09, 2023 at 01:54:47PM -0500, Mario Limonciello wrote: > The constraints table should be resetting the `list` object > after running through all of `info_obj` iterations. This *looks* like it should fix a real problem (see below), but not the one mentioned here. But maybe I'm missing something because the code that looks broken to me has been there since 146f1ed852a8 ("ACPI: PM: s2idle: Add AMD support to handle _DSM"), which appeared in v5.11 in 2021. > This adjusts whitespace as well as less code will now be included > with each loop. > > Signed-off-by: Mario Limonciello <mario.limonciello@xxxxxxx> > --- > v9->v10: > * split from other patches > --- > drivers/acpi/x86/s2idle.c | 35 +++++++++++++++++------------------ > 1 file changed, 17 insertions(+), 18 deletions(-) > > diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c > index ce62e61a9605e..b566b3aa09388 100644 > --- a/drivers/acpi/x86/s2idle.c > +++ b/drivers/acpi/x86/s2idle.c > @@ -129,12 +129,12 @@ static void lpi_device_get_constraints_amd(void) > struct lpi_constraints *list; > acpi_status status; > > + list = &lpi_constraints_table[lpi_constraints_table_size]; > + list->min_dstate = -EINVAL; I really have no idea what's going on here, but the code still looks weird: 1) Moving the "list" update: for (j = 0; j < package->package.count; ++j) { + list = &lpi_constraints_table[lpi_constraints_table_size]; for (k = 0; k < info_obj->package.count; ++k) { - list = &lpi_constraints_table[lpi_constraints_table_size]; ... } lpi_constraints_table_size++; } looks fine, but lpi_constraints_table_size isn't updated inside the "k" loop, and "list" isn't otherwise updated, so it shouldn't make any functional difference. HOWEVER, this patch also moves all the dev_info.enabled/name/min_dstate tests outside the "k" loop, so they're only done after the "k" loop has completed and they've all been set, which looks like it DOES fix a problem and is not mentioned in the commit log. 2) Both lpi_device_get_constraints_amd() and lpi_device_get_constraints() overwrite the global lpi_constraints_table for each PNP0D80 device. I assume there's some higher-level constraint that there can only be one such device, but the code doesn't enforce that. 3) It's obvious that lpi_device_get_constraints() can only allocate lpi_constraints_table once per call. It's NOT obvious for lpi_device_get_constraints_amd(), because the alloc is inside a loop: for (i = 0; i < out_obj->package.count; i++) { lpi_constraints_table = kcalloc(...); If the AMD _DSM returns more than one package, we'll leak all but the last one. 4) Both lpi_device_get_constraints_amd() and lpi_device_get_constraints() use pre- and post-increment in the "for" loops for no apparent reason: for (i = 0; i < out_obj->package.count; i++) for (j = 0; j < package->package.count; ++j) for (k = 0; k < info_obj->package.count; ++k) # AMD only I'd say they should all use the same (I vote for post-increment). > for (k = 0; k < info_obj->package.count; ++k) { > union acpi_object *obj = &info_obj->package.elements[k]; > > - list = &lpi_constraints_table[lpi_constraints_table_size]; > - list->min_dstate = -1; > - > switch (k) { > case 0: > dev_info.enabled = obj->integer.value; > @@ -149,26 +149,25 @@ static void lpi_device_get_constraints_amd(void) > dev_info.min_dstate = obj->integer.value; > break; > } > + } > > - if (!dev_info.enabled || !dev_info.name || > - !dev_info.min_dstate) > - continue; > + if (!dev_info.enabled || !dev_info.name || > + !dev_info.min_dstate) > + continue; > > - status = acpi_get_handle(NULL, dev_info.name, > - &list->handle); > - if (ACPI_FAILURE(status)) > - continue; > + status = acpi_get_handle(NULL, dev_info.name, &list->handle); > + if (ACPI_FAILURE(status)) > + continue; > > - acpi_handle_debug(lps0_device_handle, > - "Name:%s\n", dev_info.name); > + acpi_handle_debug(lps0_device_handle, > + "Name:%s\n", dev_info.name); > > - list->min_dstate = dev_info.min_dstate; > + list->min_dstate = dev_info.min_dstate; > > - if (list->min_dstate < 0) { > - acpi_handle_debug(lps0_device_handle, > - "Incomplete constraint defined\n"); > - continue; > - } > + if (list->min_dstate < 0) { > + acpi_handle_debug(lps0_device_handle, > + "Incomplete constraint defined\n"); > + continue; > } > lpi_constraints_table_size++; > } > -- > 2.34.1 >