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

next in thread | previous in thread | raw e-mail | index | archive | help
Konstantin Belousov wrote:
> 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.

Of course, I don't need to process the event in the GPE handler, and 
just noted that I tried to compare with taskqueue_enqueue()'d async 
handler, which produced the same results mainly because I was stupid and 
didn't notice that there's a separate predefined taskqueue for interrupt 
processing, taskqueue_fast.  Now all looks good, I have the chance to do 
spi transfer in async handler.

Thank you for all your help.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?8affc553-3db8-fd7f-b8be-c04d1072b84c>