Bug 6328 - loop in acpi initialisation code
Summary: loop in acpi initialisation code
Status: CLOSED CODE_FIX
Alias: None
Product: ACPI
Classification: Unclassified
Component: ACPICA-Core (show other bugs)
Hardware: i386 Linux
: P2 high
Assignee: Robert Moore
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-04-04 07:10 UTC by Xavier Bru
Modified: 2006-09-28 13:16 UTC (History)
2 users (show)

See Also:
Kernel Version: 2.6.16
Subsystem:
Regression: ---
Bisected commit-id:


Attachments
result of command "acpidump -t DSDT -o DSDT" (853.54 KB, text/plain)
2006-04-04 07:16 UTC, Xavier Bru
Details
partial traces of called methods (58.51 KB, application/octet-stream)
2006-04-04 07:28 UTC, Xavier Bru
Details

Description Xavier Bru 2006-04-04 07:10:40 UTC
Most recent kernel where this bug did not occur: 2.6.15
Distribution: Redhat/Bull
Hardware Environment: Bull Novascale
Software Environment:
Problem Description: Boot in ACPI interpreter revision 20060127 at kernel
initialisation time.

This is due to pci buses that are described in the configuration, but not
available in limited configurations.
These buses have a _STA method, but no _INI method.
With 2.6.15, the _STA method is run, and as the bus is not present, the bus and
all devices behind it are ignored.
With 2.6.16 optimisations, as no _INI method is provided for the bus, _STA
method is not run, and then we loop when executing methods for devices behind
the not present bus.

Having a look to ACPI specification, I could find nowhere the restriction that
_STA method is called only when an _INI method is provided for the device:

"6.5.1 _INI (Init)
...
If the _STA method indicates that the device is present, OSPM will evaluate the
_INI for the device (if the _INI method exists) and will examine each of the
children of the device for _INI methods. If the _STA method indicates that the
device is not present, OSPM will not run the _INI and will not examine the
children of the device for _INI methods. "
kernel does

Steps to reproduce: Just boot the system.
Comment 1 Xavier Bru 2006-04-04 07:16:03 UTC
Created attachment 7757 [details]
result of command "acpidump -t DSDT -o DSDT"
Comment 2 Xavier Bru 2006-04-04 07:28:03 UTC
Created attachment 7758 [details]
partial traces of called methods
Comment 3 Xavier Bru 2006-04-04 07:29:49 UTC
I think the problem is that we execute methods on the hot plug controler for an
unexisting bus.
There is a method that loops on a particular field:

Method (WSOB, 0, NotSerialized)
                    {
                        While (SOBO)
                        {
                            Noop
                        }
                    }

I checked that the following patch fixes the problem:

--- linux-2.6.16-old/drivers/acpi/namespace/nsinit.c    2006-03-31
18:26:23.000000000 +0200
+++ linux-2.6.16-new/drivers/acpi/namespace/nsinit.c    2006-04-03
14:57:28.000000000 +0200
@@ -362,19 +362,6 @@ acpi_ns_init_one_device(acpi_handle obj_
    info->device_count++;

    /*
-     * Check if the _INI method exists for this device -
-     * if _INI does not exist, there is no need to run _STA
-     * No _INI means device requires no initialization
-     */
-    status = acpi_ns_search_node(*ACPI_CAST_PTR(u32, METHOD_NAME__INI),
-                     device_node, ACPI_TYPE_METHOD, &ini_node);
-    if (ACPI_FAILURE(status)) {
-        /* No _INI method found - move on to next device */
-
-        return_ACPI_STATUS(AE_OK);
-    }
-
-    /*
     * Run _STA to determine if we can run _INI on the device -
     * the device must be present before _INI can be run.
     * However, _STA is not required - assume device present if no _STA
@@ -405,6 +392,17 @@ acpi_ns_init_one_device(acpi_handle obj_
    }

    /*
+     * Check if the _INI method exists for this device -
+     * No _INI means device requires no initialization
+     */
+    status = acpi_ns_search_node(*ACPI_CAST_PTR(u32, METHOD_NAME__INI),
+                     device_node, ACPI_TYPE_METHOD, &ini_node);
+    if (ACPI_FAILURE(status)) {
+        /* No _INI method found - move on to next device */
+        return_ACPI_STATUS(AE_OK);
+    }
+
+    /*
     * The device is present and _INI exists. Run the _INI method.
     * (We already have the _INI node from above)
     */
Comment 4 Robert Moore 2006-04-04 15:11:03 UTC
I think I've got a handle on this. By making this "optimization" and not 
running _STA if there is no _INI, we are violating the ACPI spec by continuing 
to walk the device tree underneath parent devices that are not present (in the 
case where the parent device has no _INI.) We need to always run _STA before 
_INI for an additional reason: in order to determine whether or not to examine 
the subtree underneath the device.

The fix to this would be to back off to the original code and add additional 
comments to avoid this again in the future.

Does this sound correct?
Comment 5 Xavier Bru 2006-04-05 02:55:38 UTC
It sounds OK for me (But I am not an ACPI expert :-)
An other solution could have been looking for _STA on parent bus to not execute
the _INI method on the device (In our DSDT, the _STA method is only present at
the bus level). BTW, it should be probably better not to run method for devices
on not present bus.
Thanks for your quick answer.
Comment 6 Robert Moore 2006-04-25 10:03:01 UTC
Should be fixed in ACPICA version 20060421
Comment 7 Len Brown 2006-07-05 19:20:00 UTC
20060421 shipped before linux-2.6.18-rc1.
closed.

Note You need to log in before you can comment on or make changes to this bug.