kernel trap with ACPI on 4.10-release

Andriy Gapon avg at icyb.net.ua
Fri Jun 11 12:21:12 GMT 2004



Out of curiosity again I looked through the sources and became very
surprised that acpi can work for anybody using 4.10-RELEASE :-)
Of course, I am not sure I got everything right.

...
> Fatal trap 12: page fault while in kernel mode
> fault virtual address   = 0x70
> fault code              = supervisor read, page not present
...
> current process         = Idle
...
> #6  0xc0193f30 in tsleep (ident=0xc0e3b980, priority=256,
> wmesg=0xc02cf8f3 "acsem", timo=0) at /export/src/sys/kern/kern_synch.c:436
> #7  0xc015cb13 in AcpiOsWaitSemaphore (Handle=0xc0e3b980, Units=1,
> Timeout=65535) at /export/src/sys/dev/acpica/Osd/OsdSynch.c:240
> #8  0xc014f167 in AcpiUtAcquireMutex (MutexId=0) at
> /export/src/sys/contrib/dev/acpica/utmisc.c:844
...

>From these pieces of debug information it seems that trap actually
occured at kern_synch.c:444
	if (p->p_wchan != NULL)
because p assigned from curpoc was equal to NULL - curpoc is equal to
NULL in the dump and p_wchan field has offset 0x70 in struct proc.
I believe that cuproc being NULL is a correct thing because in 4.10 ACPI
tasks are executed from SWI task queue i.e. from software interrupt
handler, as a part of kernel. But I may be mistaken here.
Then, I think, the call to tsleep i.e the need to wait on semaphore
resulted from the fact that some ACPI Thermal routines are executed both
from ACPI taskqueue and a separate ACPI Thermal kernel thread, so
probabalistically there can be "parallel" access to the same resources.

Now, I see 3 obvious ways of making this work:
1. change tsleep() to handle curproc == NULL
2. run ACPI tasks on kernel thread taskqueue instead of SWI taskqueue,
so that there would be kernel process to run them on
3. somehow make sure that there is no parallel execution of ACPI tasks,
so that tsleep() is never called (eliminate ACPI Thermal kthread)

Having no knowledge in ACPI internals and very little knowledge in
kernel internals I can not dare suggest what would be most appropriate
to do. Nevertheless, it seems that (1) would be too intrusive and
global; (3) is complex and might not be too reliable; (2) seems to be
the easiest, one line change from "taskqueue_swi" to "taskqueue_thread"
in OsdSchedule.c

I hope my investigation has something helpful in it, and any feedback
would also be very helpful for my self-education on kernel matters.

-- 
Andriy Gapon


More information about the freebsd-acpi mailing list