I would suggest this following patch for this issue:
=====================================
diff -r cb29bc2e1e6e usr/src/uts/intel/io/acpica/osl.c
--- a/usr/src/uts/intel/io/acpica/osl.c Sun Jul 13 14:36:23 2008 -0700
+++ b/usr/src/uts/intel/io/acpica/osl.c Mon Jul 14 10:44:33 2008 +0800
@@ -439,7 +439,7 @@
return (AE_BAD_PARAMETER);
mp = (kmutex_t *)kmem_alloc(sizeof (kmutex_t), KM_SLEEP);
- mutex_init(mp, NULL, MUTEX_DRIVER, NULL);
+ mutex_init(mp, NULL, MUTEX_SPIN, (void *)PIL_MAX);
*OutHandle = (ACPI_HANDLE)mp;
return (AE_OK);
=====================================
Any thoughts?
Thanks,
-Aubrey
Li, Aubrey wrote:
> Liu, Jiang wrote:
>
>> Hi Aubrey,
>> Currently solaris ACPICA OSL layer uses adaptive mutex to
>> implement ACPI Lock which seems not confirm to ACPICA
>> programmer manual.
>> Please refer to Section 7.4.5 of "ACPI Component Architecture
>> Programmer Reference" as below:
>>
>> 7.4.5 AcpiOsCreateLock
>> Functional Description:
>> Create a spin lock. Spin locks are used in the ACPI CA subsystem only
>> when there is requirement for mutual exclusion on data structures
>> that are accessed by both interrupt handlers and normal code.
>
> Yeah, from ACPICA manual, hardware lock must a spin lock.
> Solaris OSL initialize it as MUTEX_DRIVER, which could be either
> MUTEX_ADAPTIVE or MUTEX_SPIN depending on the iblock cookie.
> Since iblock cookie is NULL for AcpiGbl_HardwareLock, so it's
> adaptive. I think it should be initialized as MUTEX_SPIN.
>
> Thanks,
> -Aubrey
>
>>
>> Aubrey Li <> wrote:
>>> On Sat, Jul 12, 2008 at 5:49 AM, Bill Holler <Bill.Holler at sun.com>
>>> wrote:
>>>> Dana H. Myers wrote:
>>>>> Bill Holler wrote:
>>>>>> Hi Aubrey,
>>>>>>
>>>>>> I suspect we should raise the interrupt priority level high
>>>>>> enough for mutex_enter() to treat AcpiGbl_HardwareLock as a spin
>>>>>> lock.
>>>> I was thinking of something else. Raising the spl will not help.
>>>>
>>>>
>>>>>>
>>>>>> AcpiGbl_HardwareLock is declared as an ACPI_SPINLOCK.
>>>>>> AcpiOsCreateLock() initializes AcpiGbl_HardwareLock as a
>>>>>> MUTEX_DRIVER. The mutex must be an ADAPTIVE lock.
>>>>>>
>>>>>>
>>>>>> What is the idle code doing with interrupts while it places the
>>>>>> cpu into deeper c-states with the ACPI interface?
>>>>>> I assume it will be like the current cpu_halt() function masks
>>>>>> interrupts before halting the processor?
>>>>>>
>>>>> I'd like to understand better the exposure here. It's true
>>>>> that AcpiOsCreateLock() uses adaptive mutexes; this hasn't
>>>>> appeared to present a problem in the past and I'd like
>>>>> to understand the specific cases where a spin mutex
>>>>> is truly required. Perhaps the problem is better addressed
>>>>> at a higher algorithmic level, for example.
>>>>
>>>> The ACPI interfaces need to be used to halt the processor into
>>>> ACPI C2 and C3. The idle thread cannot block on a mutex
>>>> because the idle thread must always be dispatch-able.
>>>> It would be much simpler if the idle thread can use the ACPI
>>>> interface instead of alternatives such as creating a new
>>>> block-able thread to do this.
>>>>
>>>> AcpiGbl_HardwareLock is defined as an ACPI_"SPIN"LOCK. :-)
>>>> On the other hand, changing AcpiGbl_HardwareLock does
>>>> sound risky.
>>>>
>>>>
>>>>>> We need interrupts to be masked when the processor wakes
>>>>>> up, so we can fixup the local APIC state.
>>>>> It sounds like there's a local CPU vs. other CPU issue
>>>>> with respect to masking interrupts then?
>>>>
>>>> This is a related but different issue than the above idle thread
>>>> blocking in the ACPI interfaces.
>>>>
>>>> The current idle loop services interrupts from the HALT state
>>>> before continuing with the idle loop. CPUs in deep C-state
>>>> will have to execute some code to cleanup cpu state before
>>>> servicing interrupts.
>>>>
>>>> One option is to have the hardware return control to the idle
>>>> thread with interrupts masked. Another option is to check
>>>> for deep c-state cleanup in the interrupt path similar to
>>>> tlb_service().
>>>>
>>>
>>> I think the issue might be different.
>>> The following is what idle code doing.
>>> cpu_acpi_idle()
>>> {
>>> value = AcpiGetRegister(); /* need a lock */
>>> using value to determine next idle type;
>>> cli();
>>> place the processor into Cx;
>>> sti();
>>> }
>>>
>>> The problem occurs in AcpiGetRegister(), it uses
>>> AcpiGbl_HardwareLock. I suspect AcpiGbl_HardwareLock really works as
>>> a spin lock. Otherwise it will not go into turnstiles block.
>>>
>>> Thanks,
>>> -Aubrey
>>> _______________________________________________
>>> tesla-dev mailing list
>>> tesla-dev at opensolaris.org
>>> http://mail.opensolaris.org/mailman/listinfo/tesla-dev
>> _______________________________________________
>> tesla-dev mailing list
>> tesla-dev at opensolaris.org
>> http://mail.opensolaris.org/mailman/listinfo/tesla-dev
>
> _______________________________________________
> tesla-dev mailing list
> tesla-dev at opensolaris.org
> http://mail.opensolaris.org/mailman/listinfo/tesla-dev