On Fri, Mar 12, 2021 at 5:02 PM Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> wrote: > > Current mechanism of incrementing and decrementing plain integer > to get a next free instance_no when creating an ACPI device is fragile. > > In case of hot plug event or namespace removal of the device instances > with the low numbers the plain integer counter can't cover the gaps > and become desynchronized with real state of affairs. If during next > hot plug event or namespace injection the new instances of > the devices need to be instantiated, the counter may mistakenly point > to the existing instance_no and kernel will complain: > "sysfs: cannot create duplicate filename '/bus/acpi/devices/XXXX1234:02'" This is a slightly convoluted way of stating that there is a bug in acpi_device_del(). Yes, there is one, the instance_no decrementation is clearly incorrect. > Replace plain integer approach by using IDA framework. Also the general idea of using IDA for the instance numbering is a good one IMO. > Fixes: e49bd2dd5a50 ("ACPI: use PNPID:instance_no as bus_id of ACPI device") > Fixes: ca9dc8d42b30 ("ACPI / scan: Fix acpi_bus_id_list bookkeeping") > Signed-off-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> > --- > drivers/acpi/internal.h | 4 ++- > drivers/acpi/scan.c | 55 +++++++++++++++++++++++++++++++++++++---- > 2 files changed, 53 insertions(+), 6 deletions(-) > > diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h > index e6a5d997241c..6fee4f71ba1c 100644 > --- a/drivers/acpi/internal.h > +++ b/drivers/acpi/internal.h > @@ -9,6 +9,8 @@ > #ifndef _ACPI_INTERNAL_H_ > #define _ACPI_INTERNAL_H_ > > +#include <linux/idr.h> > + > #define PREFIX "ACPI: " > > int early_acpi_osi_init(void); > @@ -98,7 +100,7 @@ extern struct list_head acpi_bus_id_list; > > struct acpi_device_bus_id { > const char *bus_id; > - unsigned int instance_no; > + struct ida no; struct ida instance_ida; ? > struct list_head node; > }; > > diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c > index a184529d8fa4..a118a58f7dad 100644 > --- a/drivers/acpi/scan.c > +++ b/drivers/acpi/scan.c > @@ -468,9 +468,27 @@ static void acpi_device_release(struct device *dev) > kfree(acpi_dev); > } > > +static int acpi_device_get_instance_no(struct acpi_device *device) > +{ > + const char *p; > + int result; > + int error; > + > + p = strrchr(dev_name(&device->dev), ':'); > + if (!p) > + return -ENODATA; > + > + error = kstrtoint(p + 1, 16, &result); > + if (error) > + return error; > + > + return result; > +} I don't like the above at all. I would just store the instance number in struct acpi_device_pnp (say).