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>