From patchwork Wed Oct 29 10:26:24 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 5186351 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id C58899F349 for ; Wed, 29 Oct 2014 10:29:10 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id F23F32024D for ; Wed, 29 Oct 2014 10:29:09 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 158C02024C for ; Wed, 29 Oct 2014 10:29:09 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1XjQSt-0005mj-3o; Wed, 29 Oct 2014 10:26:55 +0000 Received: from galois.linutronix.de ([2001:470:1f0b:db:abcd:42:0:1]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1XjQSq-0005fO-1O for linux-arm-kernel@lists.infradead.org; Wed, 29 Oct 2014 10:26:53 +0000 Received: from localhost ([127.0.0.1]) by Galois.linutronix.de with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.80) (envelope-from ) id 1XjQSP-0006u9-CN; Wed, 29 Oct 2014 11:26:25 +0100 Date: Wed, 29 Oct 2014 11:26:24 +0100 (CET) From: Thomas Gleixner To: Marc Zyngier Subject: Re: [PATCH 1/3] genirq: Add support for priority-drop/deactivate interrupt controllers In-Reply-To: <5450BD61.10102@arm.com> Message-ID: References: <1414235215-10468-1-git-send-email-marc.zyngier@arm.com> <1414235215-10468-2-git-send-email-marc.zyngier@arm.com> <544E67D8.3020504@arm.com> <544FF183.9030705@arm.com> <5450BD61.10102@arm.com> User-Agent: Alpine 2.11 (DEB 23 2013-08-11) MIME-Version: 1.0 X-Linutronix-Spam-Score: -1.0 X-Linutronix-Spam-Level: - X-Linutronix-Spam-Status: No , -1.0 points, 5.0 required, ALL_TRUSTED=-1, SHORTCIRCUIT=-0.0001 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20141029_032652_234540_1CE3B505 X-CRM114-Status: GOOD ( 16.41 ) X-Spam-Score: -0.6 (/) Cc: Jason Cooper , "linux-arm-kernel@lists.infradead.org" , "linux-kernel@vger.kernel.org" X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-2.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On Wed, 29 Oct 2014, Marc Zyngier wrote: > On 28/10/14 20:14, Thomas Gleixner wrote: > > irq_enable() calls chip->irq_unmask(), i.e. DIR. So that clears the > > ACTIVE bit and then the IRQ either gets resent by hardware (in case of > > level as the device interrupt is still active) or retriggered by the > > irq_retrigger() callback. > > The problem I see here is for an interrupt that has been flagged as > disabled with irq_disabled(), but that hasn't fired. We'd end up doing a > DIR on something that hasn't had an EOI first. I think that's the only > wrinkle in this scheme. Right. So the untested patch below should do the trick and prevent irq_enable() to invoke irq_unmask() if the interrupt is not flagged masked. And it only can be flagged masked if it was masked in the handler. The startup callback will make sure that irq_enable() is not invoked at startup time. Thanks, tglx ------------------ diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index e5202f00cabc..9c0f73e1994a 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -182,7 +182,7 @@ int irq_startup(struct irq_desc *desc, bool resend) ret = desc->irq_data.chip->irq_startup(&desc->irq_data); irq_state_clr_masked(desc); } else { - irq_enable(desc); + irq_enable(desc, false); } if (resend) check_irq_resend(desc, desc->irq_data.irq); @@ -202,13 +202,14 @@ void irq_shutdown(struct irq_desc *desc) irq_state_set_masked(desc); } -void irq_enable(struct irq_desc *desc) +void irq_enable(struct irq_desc *desc, bool ifmasked) { irq_state_clr_disabled(desc); - if (desc->irq_data.chip->irq_enable) + if (desc->irq_data.chip->irq_enable) { desc->irq_data.chip->irq_enable(&desc->irq_data); - else + } else if (!ifmasked || irqd_irq_masked(&desc->irq_data)) { desc->irq_data.chip->irq_unmask(&desc->irq_data); + } irq_state_clr_masked(desc); } diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h index 4332d766619d..6eff2678cf6d 100644 --- a/kernel/irq/internals.h +++ b/kernel/irq/internals.h @@ -68,7 +68,7 @@ extern void __enable_irq(struct irq_desc *desc, unsigned int irq); extern int irq_startup(struct irq_desc *desc, bool resend); extern void irq_shutdown(struct irq_desc *desc); -extern void irq_enable(struct irq_desc *desc); +extern void irq_enable(struct irq_desc *desc, bool ifmasked); extern void irq_disable(struct irq_desc *desc); extern void irq_percpu_enable(struct irq_desc *desc, unsigned int cpu); extern void irq_percpu_disable(struct irq_desc *desc, unsigned int cpu); diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 0a9104b4608b..d8c474608c2d 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -448,7 +448,7 @@ void __enable_irq(struct irq_desc *desc, unsigned int irq) goto err_out; /* Prevent probing on this irq: */ irq_settings_set_noprobe(desc); - irq_enable(desc); + irq_enable(desc, true); check_irq_resend(desc, irq); /* fall-through */ }