]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.10
authorSasha Levin <sashal@kernel.org>
Sun, 28 Mar 2021 20:46:56 +0000 (16:46 -0400)
committerSasha Levin <sashal@kernel.org>
Sun, 28 Mar 2021 20:46:56 +0000 (16:46 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.10/acpi-scan-rearrange-memory-allocation-in-acpi_device.patch [new file with mode: 0644]
queue-5.10/acpi-scan-use-unique-number-for-instance_no.patch [new file with mode: 0644]
queue-5.10/series

diff --git a/queue-5.10/acpi-scan-rearrange-memory-allocation-in-acpi_device.patch b/queue-5.10/acpi-scan-rearrange-memory-allocation-in-acpi_device.patch
new file mode 100644 (file)
index 0000000..5f2cace
--- /dev/null
@@ -0,0 +1,127 @@
+From 53e4f908e1ef675dcd93082c8ab8ea7c061104bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jan 2021 19:46:47 +0100
+Subject: ACPI: scan: Rearrange memory allocation in acpi_device_add()
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit c1013ff7a5472db637c56bb6237f8343398c03a7 ]
+
+The upfront allocation of new_bus_id is done to avoid allocating
+memory under acpi_device_lock, but it doesn't really help,
+because (1) it leads to many unnecessary memory allocations for
+_ADR devices, (2) kstrdup_const() is run under that lock anyway and
+(3) it complicates the code.
+
+Rearrange acpi_device_add() to allocate memory for a new struct
+acpi_device_bus_id instance only when necessary, eliminate a redundant
+local variable from it and reduce the number of labels in there.
+
+No intentional functional impact.
+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/scan.c | 57 +++++++++++++++++++++------------------------
+ 1 file changed, 26 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
+index dca5cc423cd4..27292697d6a5 100644
+--- a/drivers/acpi/scan.c
++++ b/drivers/acpi/scan.c
+@@ -623,12 +623,23 @@ void acpi_bus_put_acpi_device(struct acpi_device *adev)
+       put_device(&adev->dev);
+ }
++static struct acpi_device_bus_id *acpi_device_bus_id_match(const char *dev_id)
++{
++      struct acpi_device_bus_id *acpi_device_bus_id;
++
++      /* Find suitable bus_id and instance number in acpi_bus_id_list. */
++      list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) {
++              if (!strcmp(acpi_device_bus_id->bus_id, dev_id))
++                      return acpi_device_bus_id;
++      }
++      return NULL;
++}
++
+ int acpi_device_add(struct acpi_device *device,
+                   void (*release)(struct device *))
+ {
++      struct acpi_device_bus_id *acpi_device_bus_id;
+       int result;
+-      struct acpi_device_bus_id *acpi_device_bus_id, *new_bus_id;
+-      int found = 0;
+       if (device->handle) {
+               acpi_status status;
+@@ -654,38 +665,26 @@ int acpi_device_add(struct acpi_device *device,
+       INIT_LIST_HEAD(&device->del_list);
+       mutex_init(&device->physical_node_lock);
+-      new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL);
+-      if (!new_bus_id) {
+-              pr_err(PREFIX "Memory allocation error\n");
+-              result = -ENOMEM;
+-              goto err_detach;
+-      }
+-
+       mutex_lock(&acpi_device_lock);
+-      /*
+-       * Find suitable bus_id and instance number in acpi_bus_id_list
+-       * If failed, create one and link it into acpi_bus_id_list
+-       */
+-      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))) {
+-                      acpi_device_bus_id->instance_no++;
+-                      found = 1;
+-                      kfree(new_bus_id);
+-                      break;
++
++      acpi_device_bus_id = acpi_device_bus_id_match(acpi_device_hid(device));
++      if (acpi_device_bus_id) {
++              acpi_device_bus_id->instance_no++;
++      } else {
++              acpi_device_bus_id = kzalloc(sizeof(*acpi_device_bus_id),
++                                           GFP_KERNEL);
++              if (!acpi_device_bus_id) {
++                      result = -ENOMEM;
++                      goto err_unlock;
+               }
+-      }
+-      if (!found) {
+-              acpi_device_bus_id = new_bus_id;
+               acpi_device_bus_id->bus_id =
+                       kstrdup_const(acpi_device_hid(device), GFP_KERNEL);
+               if (!acpi_device_bus_id->bus_id) {
+-                      pr_err(PREFIX "Memory allocation error for bus id\n");
++                      kfree(acpi_device_bus_id);
+                       result = -ENOMEM;
+-                      goto err_free_new_bus_id;
++                      goto err_unlock;
+               }
+-              acpi_device_bus_id->instance_no = 0;
+               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);
+@@ -720,13 +719,9 @@ int acpi_device_add(struct acpi_device *device,
+               list_del(&device->node);
+       list_del(&device->wakeup_list);
+- err_free_new_bus_id:
+-      if (!found)
+-              kfree(new_bus_id);
+-
++ err_unlock:
+       mutex_unlock(&acpi_device_lock);
+- err_detach:
+       acpi_detach_data(device->handle, acpi_scan_drop_device);
+       return result;
+ }
+-- 
+2.30.1
+
diff --git a/queue-5.10/acpi-scan-use-unique-number-for-instance_no.patch b/queue-5.10/acpi-scan-use-unique-number-for-instance_no.patch
new file mode 100644 (file)
index 0000000..01a2024
--- /dev/null
@@ -0,0 +1,138 @@
+From 8aa513d96fa121f38d2e95d5ab1f3e8a81157625 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Mar 2021 18:31:00 +0200
+Subject: ACPI: scan: Use unique number for instance_no
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit eb50aaf960e3bedfef79063411ffd670da94b84b ]
+
+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).
+
+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@linux.intel.com>
+Cc: 4.10+ <stable@vger.kernel.org> # 4.10+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/internal.h |  6 +++++-
+ drivers/acpi/scan.c     | 33 ++++++++++++++++++++++++++++-----
+ include/acpi/acpi_bus.h |  1 +
+ 3 files changed, 34 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
+index aee023ad0237..a958ad60a339 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);
+@@ -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;
+ };
+diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
+index 27292697d6a5..b47f14ac75ae 100644
+--- a/drivers/acpi/scan.c
++++ b/drivers/acpi/scan.c
+@@ -482,9 +482,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);
+@@ -635,6 +634,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 *))
+ {
+@@ -669,7 +683,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);
+@@ -685,9 +701,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);
+diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
+index 6d1879bf9440..37dac195adbb 100644
+--- a/include/acpi/acpi_bus.h
++++ b/include/acpi/acpi_bus.h
+@@ -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 */
+-- 
+2.30.1
+
index bfd6a60124d4dede5eba2243f48ac2482982bd5d..594f3b6d77f101c2599b442eac940be6ccf5ed00 100644 (file)
@@ -193,3 +193,5 @@ arm64-mm-correct-the-inside-linear-map-range-during-.patch
 dm-table-fix-zoned-model-check-and-zone-sectors-chec.patch
 mm-mmu_notifiers-ensure-range_end-is-paired-with-ran.patch
 revert-netfilter-x_tables-update-remaining-dereferen.patch
+acpi-scan-rearrange-memory-allocation-in-acpi_device.patch
+acpi-scan-use-unique-number-for-instance_no.patch