Received: by 2002:a25:c593:0:0:0:0:0 with SMTP id v141csp3207014ybe; Sun, 15 Sep 2019 09:54:32 -0700 (PDT) X-Google-Smtp-Source: APXvYqyb5ZxsRcrLWP4lUCsaey/Kra56F/0yr+Y4o3gBSru9TqLfz+6LbVJrI72+RreLWGHXaOcj X-Received: by 2002:a05:6402:3066:: with SMTP id bs6mr8207785edb.127.1568566472636; Sun, 15 Sep 2019 09:54:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1568566472; cv=none; d=google.com; s=arc-20160816; b=Jz7HHtFaFq5PDHwwDEHS3M0m8KYShWZ9Fq+NvOlNTVOWYSTrk1KOmWaPPGtcTZzT4L YNzKaWi+SAVlmZWC5XYR8TAU4Blg2CDjELTq0iwJpBzm/oVeuYBAsVHo3T8zzZz6//a8 jbUbbPbwAdlMRnM+EBr5cj8dnPvY3u91DvqRW7EuS3UY13Qp/e44UiO8MpRm1rNd3epb cqsJGyWye2xRXYIT/BIjkQ+YsHlP/Ufpjtkl0OTx2r1gqQZLyIaCX05TzqQbQHdviRKu uYLfapAjFK7oglazuScG92Yk4mbhvyDyBu/ADBTCK7Sc/T2zyOQZg7Omi2fM1zNj+YXT 9fXg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:subject:cc:to:from:message-id :date; bh=OMENGt4psVQf9O+lOQOqjvjSwQ9r+d4A+GQ7YcXxe4c=; b=PAzhhmc/gL2PTkF7GO45BN3cemYrQIQExakVTV+giEYzTayiR2kThfa5E0vjgSpYke XY3IFTqIBH6mAlVQSchZDZe1B+Bx+9L5dUk/D9Bt17rIZJ2oDw3JPXOtySf1lgMPHcWH bAwoySnWacpPrBdLJpNwSrSybME8fZNgiyHzWE1NMzmSkvyl5NAiphP174D0DldXBg1D JykZbJaw8kKWJQS2YXAFCBUnrIep6KQUbLVM/yoYUjuNc0ghcxvGE61fwJOLvhniWuPD yrB7LNWsLs/ulgiBTVqwslZBTnbthxsttQKerOmZfTCUKOlJDW7HmnUWnBlA3pSZcW80 AZ8w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id k7si4828070ejk.266.2019.09.15.09.54.08; Sun, 15 Sep 2019 09:54:32 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731674AbfIOOYb convert rfc822-to-8bit (ORCPT + 99 others); Sun, 15 Sep 2019 10:24:31 -0400 Received: from foss.arm.com ([217.140.110.172]:35088 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730611AbfIOOYb (ORCPT ); Sun, 15 Sep 2019 10:24:31 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4A28128; Sun, 15 Sep 2019 07:24:30 -0700 (PDT) Received: from big-swifty.misterjones.org (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 586D63F575; Sun, 15 Sep 2019 07:24:27 -0700 (PDT) Date: Sun, 15 Sep 2019 15:24:20 +0100 Message-ID: <8636gxskmj.wl-maz@kernel.org> From: Marc Zyngier To: Darius Rad Cc: linux-riscv@lists.infradead.org, Palmer Dabbelt , Paul Walmsley , linux-kernel@vger.kernel.org, Thomas Gleixner , Jason Cooper Subject: Re: [PATCH] irqchip/sifive-plic: add irq_mask and irq_unmask In-Reply-To: <529ec882-734f-17ae-e4cb-3aeb563ad1d5@bluespec.com> References: <529ec882-734f-17ae-e4cb-3aeb563ad1d5@bluespec.com> User-Agent: Wanderlust/2.15.9 (Almost Unreal) SEMI-EPG/1.14.7 (Harue) FLIM/1.14.9 (=?UTF-8?B?R29qxY0=?=) APEL/10.8 EasyPG/1.0.0 Emacs/26 (aarch64-unknown-linux-gnu) MULE/6.0 (HANACHIRUSATO) MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 8BIT Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, 12 Sep 2019 22:40:34 +0100, Darius Rad wrote: Hi Darius, > > As per the existing comment, irq_mask and irq_unmask do not need > to do anything for the PLIC. However, the functions must exist > (the pointers cannot be NULL) as they are not optional, based on > the documentation (Documentation/core-api/genericirq.rst) as well > as existing usage (e.g., include/linux/irqchip/chained_irq.h). > > Signed-off-by: Darius Rad > --- > drivers/irqchip/irq-sifive-plic.c | 13 +++++++++---- > 1 file changed, 9 insertions(+), 4 deletions(-) > > diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c > index cf755964f2f8..52d5169f924f 100644 > --- a/drivers/irqchip/irq-sifive-plic.c > +++ b/drivers/irqchip/irq-sifive-plic.c > @@ -111,6 +111,13 @@ static void plic_irq_disable(struct irq_data *d) > plic_irq_toggle(cpu_possible_mask, d->hwirq, 0); > } > > +/* > + * There is no need to mask/unmask PLIC interrupts. They are "masked" > + * by reading claim and "unmasked" when writing it back. > + */ > +static void plic_irq_mask(struct irq_data *d) { } > +static void plic_irq_unmask(struct irq_data *d) { } This outlines a bigger issue. If your irqchip doesn't require mask/unmask, you're probably not using the right interrupt flow. Looking at the code, I see you're using handle_simple_irq, which is almost universally wrong. As per the description above, these interrupts should be using the fasteoi flow, which is designed for this exact behaviour (the interrupt controller knows which interrupt is in flight and doesn't require SW to do anything bar signalling the EOI). Another thing is that mask/unmask tends to be a requirement, while enable/disable tends to be optional. There is no hard line here, but the expectations are that: (a) A disabled line can drop interrupts (b) A masked line cannot drop interrupts Depending what the PLIC architecture mandates, you'll need to implement one and/or the other. Having just (a) is indicative of a HW bug, and I'm not assuming that this is the case. (b) only is pretty common, and (a)+(b) has a few adepts. My bet is that it requires (b) only. > + > #ifdef CONFIG_SMP > static int plic_set_affinity(struct irq_data *d, > const struct cpumask *mask_val, bool force) > @@ -138,12 +145,10 @@ static int plic_set_affinity(struct irq_data *d, > > static struct irq_chip plic_chip = { > .name = "SiFive PLIC", > - /* > - * There is no need to mask/unmask PLIC interrupts. They are "masked" > - * by reading claim and "unmasked" when writing it back. > - */ > .irq_enable = plic_irq_enable, > .irq_disable = plic_irq_disable, > + .irq_mask = plic_irq_mask, > + .irq_unmask = plic_irq_unmask, > #ifdef CONFIG_SMP > .irq_set_affinity = plic_set_affinity, > #endif Can you give the following patch a go? It brings the irq flow in line with what the HW can do. It is of course fully untested (not even compile tested...). Thanks, M. From c0ce33a992ec18f5d3bac7f70de62b1ba2b42090 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Sun, 15 Sep 2019 15:17:45 +0100 Subject: [PATCH] irqchip/sifive-plic: Switch to fasteoi flow The SiFive PLIC interrupt controller seems to have all the HW features to support the fasteoi flow, but the driver seems to be stuck in a distant past. Bring it into the 21st century. Signed-off-by: Marc Zyngier --- drivers/irqchip/irq-sifive-plic.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c index cf755964f2f8..8fea384d392b 100644 --- a/drivers/irqchip/irq-sifive-plic.c +++ b/drivers/irqchip/irq-sifive-plic.c @@ -97,7 +97,7 @@ static inline void plic_irq_toggle(const struct cpumask *mask, } } -static void plic_irq_enable(struct irq_data *d) +static void plic_irq_mask(struct irq_data *d) { unsigned int cpu = cpumask_any_and(irq_data_get_affinity_mask(d), cpu_online_mask); @@ -106,7 +106,7 @@ static void plic_irq_enable(struct irq_data *d) plic_irq_toggle(cpumask_of(cpu), d->hwirq, 1); } -static void plic_irq_disable(struct irq_data *d) +static void plic_irq_unmask(struct irq_data *d) { plic_irq_toggle(cpu_possible_mask, d->hwirq, 0); } @@ -125,10 +125,8 @@ static int plic_set_affinity(struct irq_data *d, if (cpu >= nr_cpu_ids) return -EINVAL; - if (!irqd_irq_disabled(d)) { - plic_irq_toggle(cpu_possible_mask, d->hwirq, 0); - plic_irq_toggle(cpumask_of(cpu), d->hwirq, 1); - } + plic_irq_toggle(cpu_possible_mask, d->hwirq, 0); + plic_irq_toggle(cpumask_of(cpu), d->hwirq, 1); irq_data_update_effective_affinity(d, cpumask_of(cpu)); @@ -136,14 +134,18 @@ static int plic_set_affinity(struct irq_data *d, } #endif +static void plic_irq_eoi(struct irq_data *d) +{ + struct plic_handler *handler = this_cpu_ptr(&plic_handlers); + + writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); +} + static struct irq_chip plic_chip = { .name = "SiFive PLIC", - /* - * There is no need to mask/unmask PLIC interrupts. They are "masked" - * by reading claim and "unmasked" when writing it back. - */ - .irq_enable = plic_irq_enable, - .irq_disable = plic_irq_disable, + .irq_mask = plic_irq_mask, + .irq_unmask = plic_irq_unmask, + .irq_eoi = plic_irq_eoi, #ifdef CONFIG_SMP .irq_set_affinity = plic_set_affinity, #endif @@ -152,7 +154,7 @@ static struct irq_chip plic_chip = { static int plic_irqdomain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hwirq) { - irq_set_chip_and_handler(irq, &plic_chip, handle_simple_irq); + irq_set_chip_and_handler(irq, &plic_chip, handle_fasteoi_irq); irq_set_chip_data(irq, NULL); irq_set_noprobe(irq); return 0; @@ -188,7 +190,6 @@ static void plic_handle_irq(struct pt_regs *regs) hwirq); else generic_handle_irq(irq); - writel(hwirq, claim); } csr_set(sie, SIE_SEIE); } -- 2.20.1 -- Jazz is not dead, it just smells funny.