[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [linux-2.6.18-xen] ACPI: eliminate restriction on ACPI processor ID range



# HG changeset patch
# User Jan Beulich <jbeulich@xxxxxxxx>
# Date 1323252281 -3600
# Node ID 22ff38fd4b8b1d0b625a01a09210b1863aec8864
# Parent  1a0d68a3b3f99222a23a9e4b3d3c799cd8892033
ACPI: eliminate restriction on ACPI processor ID range

Rather than storing the reference acpi_device pointers in an ACPI-ID-
indexed array (and having a bogus BUG_ON() check on a platform provided
value), use a radix tree instead.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
Acked-by: Keir Fraser <keir@xxxxxxx>
---


diff -r 1a0d68a3b3f9 -r 22ff38fd4b8b drivers/acpi/processor_core.c
--- a/drivers/acpi/processor_core.c     Tue Dec 06 14:25:13 2011 +0100
+++ b/drivers/acpi/processor_core.c     Wed Dec 07 11:04:41 2011 +0100
@@ -513,7 +513,14 @@
        return 0;
 }
 
-static void *processor_device_array[NR_ACPI_CPUS];
+#ifndef CONFIG_XEN
+static void *processor_device_array[NR_CPUS];
+#else
+#include <linux/mutex.h>
+#include <linux/radix-tree.h>
+static DEFINE_MUTEX(processor_device_mutex);
+static RADIX_TREE(processor_device_tree, GFP_KERNEL);
+#endif
 
 static int acpi_processor_start(struct acpi_device *device)
 {
@@ -541,9 +548,20 @@
         * Don't trust it blindly
         */
 #ifdef CONFIG_XEN
-       BUG_ON(pr->acpi_id >= NR_ACPI_CPUS);
-       if (processor_device_array[pr->acpi_id] != NULL &&
-           processor_device_array[pr->acpi_id] != (void *)device) {
+       mutex_lock(&processor_device_mutex);
+       result = radix_tree_insert(&processor_device_tree,
+                                  pr->acpi_id, device);
+       switch (result) {
+       default:
+               goto end_unlock;
+       case -EEXIST:
+               if (radix_tree_lookup(&processor_device_tree,
+                                     pr->acpi_id) == device) {
+       case 0:
+                       mutex_unlock(&processor_device_mutex);
+                       break;
+               }
+               mutex_unlock(&processor_device_mutex);
 #else
        if (processor_device_array[pr->id] != NULL &&
            processor_device_array[pr->id] != (void *)device) {
@@ -553,14 +571,11 @@
                return -ENODEV;
        }
 #ifdef CONFIG_XEN
-       processor_device_array[pr->acpi_id] = (void *)device;
        if (pr->id != -1)
-               processors[pr->id] = pr;
 #else
        processor_device_array[pr->id] = (void *)device;
-
+#endif /* CONFIG_XEN */
        processors[pr->id] = pr;
-#endif /* CONFIG_XEN */
 
        result = acpi_processor_add_fs(device);
        if (result)
@@ -602,6 +617,14 @@
        }
 
       end:
+#ifdef CONFIG_XEN
+       mutex_lock(&processor_device_mutex);
+       if (radix_tree_lookup(&processor_device_tree,
+                             pr->acpi_id) == device)
+               radix_tree_delete(&processor_device_tree, pr->acpi_id);
+      end_unlock:
+       mutex_unlock(&processor_device_mutex);
+#endif
 
        return result;
 }
@@ -692,10 +715,8 @@
 
 #ifdef CONFIG_XEN
        if (pr->id != -1)
-               processors[pr->id] = NULL;
-#else
+#endif
        processors[pr->id] = NULL;
-#endif /* CONFIG_XEN */
 
 
        kfree(pr);
@@ -992,6 +1013,30 @@
 
        remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
 
+#ifdef CONFIG_XEN
+       {
+               struct acpi_device *dev;
+               unsigned int idx = 0;
+
+               while (radix_tree_gang_lookup(&processor_device_tree,
+                                             (void **)&dev, idx, 1)) {
+                       struct acpi_processor *pr = acpi_driver_data(dev);
+
+                       /* prevent live lock */
+                       if (pr->acpi_id < idx) {
+                               printk(KERN_WARNING PREFIX "ID %u unexpected"
+                                      " (less than %u); leaking memory\n",
+                                      pr->acpi_id, idx);
+                               break;
+                       }
+                       idx = pr->acpi_id;
+                       radix_tree_delete(&processor_device_tree, idx);
+                       if (!++idx)
+                               break;
+               }
+       }
+#endif
+
        return;
 }
 
diff -r 1a0d68a3b3f9 -r 22ff38fd4b8b include/acpi/processor.h
--- a/include/acpi/processor.h  Tue Dec 06 14:25:13 2011 +0100
+++ b/include/acpi/processor.h  Wed Dec 07 11:04:41 2011 +0100
@@ -24,12 +24,6 @@
 #define ACPI_TSD_REV0_REVISION         0       /* Support for _PSD as in ACPI 
3.0 */
 #define ACPI_TSD_REV0_ENTRIES          5
 
-#ifdef CONFIG_XEN
-#define NR_ACPI_CPUS                   (NR_CPUS < 256 ? 256 : NR_CPUS)
-#else
-#define NR_ACPI_CPUS                   NR_CPUS
-#endif /* CONFIG_XEN */
-
 /*
  * Types of coordination defined in ACPI 3.0. Same macros can be used across
  * P, C and T states

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.