FAILED: patch "[PATCH] ACPI: scan: Use unique number for instance_no" failed to apply to 5.11-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.11-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From eb50aaf960e3bedfef79063411ffd670da94b84b Mon Sep 17 00:00:00 2001
From: Andy Shevchenko <[email protected]>
Date: Mon, 22 Mar 2021 18:31:00 +0200
Subject: [PATCH] ACPI: scan: Use unique number for instance_no
The decrementation of acpi_device_bus_id->instance_no in acpi_device_del() is incorrect, because it may cause a duplicate instance number to be allocated next time a device with the same acpi_device_bus_id is added.
Replace above mentioned approach by using IDA framework.
While at it, define the instance range to be [0, 4096).
drivers/acpi/internal.h +5 -1
@@ -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 );
@@ -96,9 +98,11 @@ void acpi_scan_table_handler(u32 event, void *table, void *context);extern struct list_head acpi_bus_id_list; +#define ACPI_MAX_DEVICE_INSTANCES 4096 +struct acpi_device_bus_id {const char *bus_id; -unsigned int instance_no; +struct ida instance_ida;struct list_head node; };
drivers/acpi/scan.c +28 -5
@@ -479,9 +479,8 @@ static void acpi_device_del(struct acpi_device *device)list_for_each_entry (acpi_device_bus_id, &acpi_bus_id_list, node)if (!strcmp (acpi_device_bus_id->bus_id,acpi_device_hid (device))) { -if (acpi_device_bus_id->instance_no >0 ) - acpi_device_bus_id->instance_no--; -else { +ida_simple_remove (&acpi_device_bus_id->instance_ida, device->pnp.instance_no); +if (ida_is_empty (&acpi_device_bus_id->instance_ida)) {list_del (&acpi_device_bus_id->node);kfree_const (acpi_device_bus_id->bus_id);kfree (acpi_device_bus_id);
@@ -631,6 +630,21 @@ static struct acpi_device_bus_id *acpi_device_bus_id_match(const char *dev_id)return NULL ; } +static int acpi_device_set_name (struct acpi_device *device, +struct acpi_device_bus_id *acpi_device_bus_id) +{ +struct ida *instance_ida = &acpi_device_bus_id->instance_ida; +int result; + + result =ida_simple_get (instance_ida,0 ,ACPI_MAX_DEVICE_INSTANCES ,GFP_KERNEL ); +if (result <0 ) +return result; + + device->pnp.instance_no = result; +dev_set_name (&device->dev,"%s:%02x" , acpi_device_bus_id->bus_id, result); +return 0 ; +} +int acpi_device_add (struct acpi_device *device,void (*release)(struct device *)) {
@@ -665,7 +679,9 @@ int acpi_device_add(struct acpi_device *device, acpi_device_bus_id =acpi_device_bus_id_match (acpi_device_hid (device));if (acpi_device_bus_id) { - acpi_device_bus_id->instance_no++; + result =acpi_device_set_name (device, acpi_device_bus_id); +if (result) + goto err_unlock; }else { acpi_device_bus_id =kzalloc (sizeof (*acpi_device_bus_id),GFP_KERNEL );
@@ -681,9 +697,16 @@ int acpi_device_add(struct acpi_device *device, goto err_unlock; } +ida_init (&acpi_device_bus_id->instance_ida); + + result =acpi_device_set_name (device, acpi_device_bus_id); +if (result) { +kfree (acpi_device_bus_id); + goto err_unlock; + } +list_add_tail (&acpi_device_bus_id->node, &acpi_bus_id_list); } -dev_set_name (&device->dev,"%s:%02x" , acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no);if (device->parent)list_add_tail (&device->node, &device->parent->children);
include/acpi/acpi_bus.h +1 -0
@@ -233,6 +233,7 @@ struct acpi_pnp_type {struct acpi_device_pnp {acpi_bus_id bus_id;/* Object name */ +int instance_no;/* Instance number of this object */ struct acpi_pnp_type type;/* ID type */ acpi_bus_address bus_address;/* _ADR */ char *unique_id;/* _UID */