Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 11 Sep 2018 11:43:57 +0300
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Yuri Pankov <yuripv@yuripv.net>
Cc:        freebsd-hackers <freebsd-hackers@freebsd.org>
Subject:   Re: ACPI GPE handler: mtx_lock() by idle thread
Message-ID:  <20180911084357.GU3161@kib.kiev.ua>
In-Reply-To: <475afc8c-d0ad-ead2-e75e-bca873977c2d@yuripv.net>
References:  <475afc8c-d0ad-ead2-e75e-bca873977c2d@yuripv.net>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Sep 11, 2018 at 08:19:26AM +0300, Yuri Pankov wrote:
> I have the panic shown below with a simple device driver that installs 
> GPE handler in the attach routine, and does nothing else than waiting 
> for GPEs.  No matter if I try to handle it sync (calling 
> SPIBUS_TRANSFER() from the handler), or async (calling 
> taskqueue_enqueue()), once one of those functions called from the 
> handler does mtx_lock(), it panics.  Any hints?
If you look at the backtrace below, you would note that ACPI GPE event
handler is executed in the context of an interrupt.  It means that it
borrows the context of whatever thread was executed on the CPU when the
interrupt occured.  One of the consequences is that an interrupt handler
(fast interrupt handler in the FreeBSD terminology) cannot block or
sleep, see locking(9).

There is a different way to handle interrupts in FreeBSD, by normal (not
fast) interrupt handlers.  There, the code executing in the context of
interrupt only wakes up the interrupt thread, which executes the handler
in its dedicated context. As the consequence, mutexes do work for such
handlers. Still, sleep is prohibited.

I briefly looked at the dev/intel/spi.c code and I see that
intelspi_transfer() sleeps waiting for the hardware event.  In other
words, even normal interrupt handler cannot help your problem.

Is it required to do the transfers in the interrupt handler code, for
your work ?  If not, then the usual solution is to delegate the work
that requires resource acquision, to the fast taskqueue.  Your code in
GPE event handler would only schedule a task, and the running task can
do whatever slow operations it needs.  See taskqueue(9), there are
enough examples of the fast taskqueue use in the tree.

> 
> 
> panic: mtx_lock() by idle thread 0xfffff800035bb000 on sleep mutex spi1 
> @ /home/yuri/ws/mbp/sys/dev/intel/spi.c:382
> cpuid = 0
> time = 1536642645
> KDB: stack backtrace:
> db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 
> 0xfffffe00764761b0
> vpanic() at vpanic+0x1a3/frame 0xfffffe0076476210
> panic() at panic+0x43/frame 0xfffffe0076476270
> __mtx_lock_flags() at __mtx_lock_flags+0x15a/frame 0xfffffe00764762c0
> intelspi_transfer() at intelspi_transfer+0x3d/frame 0xfffffe0076476310
> spimbp_gpe_handler() at spimbp_gpe_handler+0x102/frame 0xfffffe0076476580
> AcpiEvGpeDispatch() at AcpiEvGpeDispatch+0xc0/frame 0xfffffe00764765b0
> AcpiEvDetectGpe() at AcpiEvDetectGpe+0x10a/frame 0xfffffe0076476600
> AcpiEvGpeDetect() at AcpiEvGpeDetect+0x323/frame 0xfffffe0076476670
> AcpiEvSciXruptHandler() at AcpiEvSciXruptHandler+0x1e/frame 
> 0xfffffe00764766a0
> acpi_intr_handler() at acpi_intr_handler+0x18/frame 0xfffffe00764766b0
> intr_event_handle() at intr_event_handle+0xcb/frame 0xfffffe0076476700
> intr_execute_handlers() at intr_execute_handlers+0x58/frame 
> 0xfffffe0076476730
> lapic_handle_intr() at lapic_handle_intr+0x5f/frame 0xfffffe0076476750
> Xapic_isr1() at Xapic_isr1+0xd9/frame 0xfffffe0076476750
> --- interrupt, rip = 0xffffffff80461191, rsp = 0xfffffe0076476820, rbp = 
> 0xfffffe0076476860 ---
> acpi_cpu_idle() at acpi_cpu_idle+0x2a1/frame 0xfffffe0076476860
> cpu_idle_acpi() at cpu_idle_acpi+0x3f/frame 0xfffffe0076476880
> cpu_idle() at cpu_idle+0xa7/frame 0xfffffe00764768a0
> sched_idletd() at sched_idletd+0x517/frame 0xfffffe0076476970
> fork_exit() at fork_exit+0x84/frame 0xfffffe00764769b0
> fork_trampoline() at fork_trampoline+0xe/frame 0xfffffe00764769b0
> --- trap 0, rip = 0, rsp = 0, rbp = 0 ---
> KDB: enter: panic



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20180911084357.GU3161>