Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S941137AbcJXQNY (ORCPT ); Mon, 24 Oct 2016 12:13:24 -0400 Received: from smtp5-g21.free.fr ([212.27.42.5]:10122 "EHLO smtp5-g21.free.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933767AbcJXQNW (ORCPT ); Mon, 24 Oct 2016 12:13:22 -0400 Subject: Re: Disabling an interrupt in the handler locks the system up To: Marc Zyngier Cc: Thomas Gleixner , Jason Cooper , LKML , Linux ARM , Sebastian Frias References: <580A4460.2090306@free.fr> <580A60ED.3030307@free.fr> <20161021201448.3f4a0a7a@arm.com> <580A70B9.8060507@free.fr> <580A7A2B.5000702@free.fr> <20161022123713.6dc788b3@arm.com> <580BF1D4.2030509@free.fr> From: Mason Message-ID: <580E3308.4050507@free.fr> Date: Mon, 24 Oct 2016 18:12:56 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:43.0) Gecko/20100101 Firefox/43.0 SeaMonkey/2.40 MIME-Version: 1.0 In-Reply-To: <580BF1D4.2030509@free.fr> Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1954 Lines: 57 On 23/10/2016 01:10, Mason wrote: > Maybe the fact that disable_irq locks the system up is an orthogonal > issue that needs to be fixed anyway. disable_irq_nosync() eventually calls irq_disable() void irq_disable(struct irq_desc *desc) { irq_state_set_disabled(desc); if (desc->irq_data.chip->irq_disable) { desc->irq_data.chip->irq_disable(&desc->irq_data); irq_state_set_masked(desc); } else if (irq_settings_disable_unlazy(desc)) { mask_irq(desc); } } irq_disable() is a NOP on my platform, because the intc driver does not implement irq_disable, and the second test is false as well in this instance. The function's description is interesting. /** * irq_disable - Mark interrupt disabled * @desc: irq descriptor which should be disabled * * If the chip does not implement the irq_disable callback, we * use a lazy disable approach. That means we mark the interrupt * disabled, but leave the hardware unmasked. That's an * optimization because we avoid the hardware access for the * common case where no interrupt happens after we marked it * disabled. If an interrupt happens, then the interrupt flow * handler masks the line at the hardware level and marks it * pending. * * If the interrupt chip does not implement the irq_disable callback, * a driver can disable the lazy approach for a particular irq line by * calling 'irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY)'. This can * be used for devices which cannot disable the interrupt at the * device level under certain circumstances and have to use * disable_irq[_nosync] instead. */ (I assume "chip" and "interrupt chip" refer to the same abstraction.) I took a look at commit e9849777d0e27, but my brain dumped core on the notions of "disabling unlazy" and "disabling a disable". * IRQ_DISABLE_UNLAZY - Disable lazy irq disable For the record, setting the IRQ_DISABLE_UNLAZY flag for this device makes the system lock-up disappear. Regards.