Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp7179224imu; Thu, 27 Dec 2018 14:04:39 -0800 (PST) X-Google-Smtp-Source: ALg8bN4OOU1YibbSUr3855BjkV9WFKhMmxNKpMTZhdeoRILpAVxhR4MXMKWSAGON5pnQJxngKq9W X-Received: by 2002:a63:7c41:: with SMTP id l1mr23854191pgn.45.1545948279621; Thu, 27 Dec 2018 14:04:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1545948279; cv=none; d=google.com; s=arc-20160816; b=qv4PyOnHgxKAdChsPwuKyeLXAYvM6hFVmGIDg9BBHDJ6uyKIfJcm3N5bx4wMjVGe13 4L6Ow7zbW9Z9mTh0KQTqrv4i/0CX1TwoQ5xruAhNJdSNOax2rvjaJO6ZEU/TNPE7iRgv 0HuLPK7v1paeTLtNLdFOjVLGJzaLM5Q9ZZJRX+OvFF4aBT9T7DkWFBrJSsWUdznB0ojU yUCTRNbgAkancMgOGPqVtk81Ka+f/QgOJGve3TiVhMftHjHEezV8K0rbYUBBiGiGVRTv 0PsH5PA6Muwoo+XPWLOVgw+NyCkzFog0ZERG+KmOPiQibdikfbMPErZPbWZhiww1KnNs KyNA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=BlKwaKedPU8kFUHvmSJlIsJdtI4hfi1jlcbkI/tlo30=; b=YCvVEN2ZpqSb114LCvBQGIq7e1slUImWLZNkwgtOIt1KvCd2T2oR/rlKn/q9xLLKuN VXC9rg/pbGFzgapX/DnO5qpTwirN9ZWIvo70DFr3LxUpgYdg0lKT4HfjOmYYEMIGsyI7 s7ni5nmH12Uoa4wtAIW2scznFHsh9XhTNUjg3gqlraexdqOP3B/PlmoMlv5WbM6xq1Mk xf4yU1F6zAx2CIDdQHnf4jnp20Q4NnkfzknTBRLwKoRpAjy9jCuzKk7zHFdn8rXI22PP TNsvFmdJbOAhCcre3f2XvoY9C7UP9U3yX5iHqxJQ79sobwJixzs0hieY5WFerOZGrmix 3uxw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@brainfault-org.20150623.gappssmtp.com header.s=20150623 header.b=OCTZqQNw; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o124si37532390pfb.256.2018.12.27.14.04.23; Thu, 27 Dec 2018 14:04:39 -0800 (PST) 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; dkim=pass header.i=@brainfault-org.20150623.gappssmtp.com header.s=20150623 header.b=OCTZqQNw; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730824AbeL0LTF (ORCPT + 99 others); Thu, 27 Dec 2018 06:19:05 -0500 Received: from mail-pl1-f194.google.com ([209.85.214.194]:34700 "EHLO mail-pl1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728029AbeL0LTE (ORCPT ); Thu, 27 Dec 2018 06:19:04 -0500 Received: by mail-pl1-f194.google.com with SMTP id w4so8685038plz.1 for ; Thu, 27 Dec 2018 03:19:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brainfault-org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=BlKwaKedPU8kFUHvmSJlIsJdtI4hfi1jlcbkI/tlo30=; b=OCTZqQNw7DV07aIFDKDv0z0AYosGSiDht8YH4GvU2kpz3CNiBL+UEJve4odddSgz35 HrTMmLW7DcyUNFmnUtJIiREORENznhqnrhSyctrNA2Gzw1eRj9zlmLdal+kAee3g2Mi0 8koCENIcjxuI3FQLdwBnz7OxfIyopKmhYKbALeghp1kNVCssCGtc9AxO4BPTxNU1ra7D QECsDLI5Jtj+LpBmGH1muNPr3+VKncfNB2yy39ksn2AWT9QLUDynhzA9hPWmq0a83lW6 2OG2AAiIigPqTOF0/TxtCc0RPRem9mzLXErLwIw2YHo/pypng3bXFP9yQAeOnxAXQXPc SVug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=BlKwaKedPU8kFUHvmSJlIsJdtI4hfi1jlcbkI/tlo30=; b=YB/eYwP4gtWgFVXrOrrQZzjstn+pok7Pz19ZD6PyrjWFhbf61ZmzrpUfZbkOU7i3Jv zrrDKYovLwaF5mVRwP1FhIs0NljpsixK+1D9zkrrjo+JvCLLrLq9TwOPsQp7uLRMTfW4 Z9r0AudrIenGY+Y0YIGDSenbeiKoyEOoPrmGYTDoZKNE53VJ7O2NmclUKKKwILVl3+P9 +jif+vmkR6ol7J3nu6066tI4wkKcxHiLuJ+ik5zEvssPmSV3iBYlcy7rl9DQ9Lr1vK1W q/hUP7Yu6+KzMZVe84EdyJfZIzPVU6lDNkEGWp3BrP90CaXIJgjxbS45DRLPiIvY7hnR DODw== X-Gm-Message-State: AJcUukexLxWc9/mgIdTkLgz1zN6kiM4+VYjJ7J0c9BBM3kvFWb6NABfg q030o/bv947eRdk4k9aIxHIcog== X-Received: by 2002:a17:902:6a4:: with SMTP id 33mr22737414plh.99.1545909543048; Thu, 27 Dec 2018 03:19:03 -0800 (PST) Received: from localhost.localdomain ([106.51.18.57]) by smtp.gmail.com with ESMTPSA id u137sm66830105pfc.140.2018.12.27.03.18.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 27 Dec 2018 03:19:02 -0800 (PST) From: Anup Patel To: Palmer Dabbelt , Albert Ou , Daniel Lezcano , Thomas Gleixner , Jason Cooper , Marc Zyngier Cc: Atish Patra , Christoph Hellwig , linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, Anup Patel Subject: [PATCH v4 5/5] irqchip: sifive-plic: Implement irq_set_affinity() for SMP host Date: Thu, 27 Dec 2018 16:48:21 +0530 Message-Id: <20181227111821.80908-6-anup@brainfault.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181227111821.80908-1-anup@brainfault.org> References: <20181227111821.80908-1-anup@brainfault.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Currently on SMP host, all CPUs take external interrupts routed via PLIC. All CPUs will try to claim a given external interrupt but only one of them will succeed while other CPUs would simply resume whatever they were doing before. This means if we have N CPUs then for every external interrupt N-1 CPUs will always fail to claim it and waste their CPU time. Instead of above, external interrupts should be taken by only one CPU and we should have provision to explicitly specify IRQ affinity from kernel-space or user-space. This patch provides irq_set_affinity() implementation for PLIC driver. It also updates irq_enable() such that PLIC interrupts are only enabled for one of CPUs specified in IRQ affinity mask. With this patch in-place, we can change IRQ affinity at any-time from user-space using procfs. Example: / # cat /proc/interrupts CPU0 CPU1 CPU2 CPU3 8: 44 0 0 0 SiFive PLIC 8 virtio0 10: 48 0 0 0 SiFive PLIC 10 ttyS0 IPI0: 55 663 58 363 Rescheduling interrupts IPI1: 0 1 3 16 Function call interrupts / # / # / # echo 4 > /proc/irq/10/smp_affinity / # / # cat /proc/interrupts CPU0 CPU1 CPU2 CPU3 8: 45 0 0 0 SiFive PLIC 8 virtio0 10: 160 0 17 0 SiFive PLIC 10 ttyS0 IPI0: 68 693 77 410 Rescheduling interrupts IPI1: 0 2 3 16 Function call interrupts Signed-off-by: Anup Patel --- drivers/irqchip/irq-sifive-plic.c | 44 ++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c index 24c906f4be93..47da70795145 100644 --- a/drivers/irqchip/irq-sifive-plic.c +++ b/drivers/irqchip/irq-sifive-plic.c @@ -83,29 +83,58 @@ static void plic_toggle(struct plic_handler *handler, raw_spin_unlock(&handler->enable_lock); } -static void plic_irq_toggle(struct irq_data *d, int enable) +static void plic_irq_toggle(const struct cpumask *mask, int hwirq, int enable) { int cpu; - writel(enable, plic_regs + PRIORITY_BASE + d->hwirq * PRIORITY_PER_ID); - for_each_cpu(cpu, irq_data_get_affinity_mask(d)) { + writel(enable, plic_regs + PRIORITY_BASE + hwirq * PRIORITY_PER_ID); + for_each_cpu(cpu, mask) { struct plic_handler *handler = per_cpu_ptr(&plic_handlers, cpu); if (handler->present) - plic_toggle(handler, d->hwirq, enable); + plic_toggle(handler, hwirq, enable); } } static void plic_irq_enable(struct irq_data *d) { - plic_irq_toggle(d, 1); + unsigned int cpu = cpumask_any_and(irq_data_get_affinity_mask(d), + cpu_online_mask); + if (WARN_ON_ONCE(cpu >= nr_cpu_ids)) + return; + plic_irq_toggle(cpumask_of(cpu), d->hwirq, 1); } static void plic_irq_disable(struct irq_data *d) { - plic_irq_toggle(d, 0); + plic_irq_toggle(cpu_possible_mask, d->hwirq, 0); } +#ifdef CONFIG_SMP +static int plic_set_affinity(struct irq_data *d, + const struct cpumask *mask_val, bool force) +{ + unsigned int cpu; + + if (!force) + cpu = cpumask_any_and(mask_val, cpu_online_mask); + else + cpu = cpumask_first(mask_val); + + 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); + } + + irq_data_update_effective_affinity(d, cpumask_of(cpu)); + + return IRQ_SET_MASK_OK_DONE; +} +#endif + static struct irq_chip plic_chip = { .name = "SiFive PLIC", /* @@ -114,6 +143,9 @@ static struct irq_chip plic_chip = { */ .irq_enable = plic_irq_enable, .irq_disable = plic_irq_disable, +#ifdef CONFIG_SMP + .irq_set_affinity = plic_set_affinity, +#endif }; static int plic_irqdomain_map(struct irq_domain *d, unsigned int irq, -- 2.17.1