From patchwork Mon May 12 15:48:51 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Larry Bassel X-Patchwork-Id: 29981 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qc0-f197.google.com (mail-qc0-f197.google.com [209.85.216.197]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 3D531238ED for ; Mon, 12 May 2014 15:49:16 +0000 (UTC) Received: by mail-qc0-f197.google.com with SMTP id w7sf24311464qcr.8 for ; Mon, 12 May 2014 08:49:16 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:sender:precedence:list-id:x-original-sender :x-original-authentication-results:mailing-list:list-post:list-help :list-archive:list-unsubscribe; bh=tIdVuio+E+rSrWWZosowdyC/dkvvTOFPpAdeQomySEQ=; b=OU0parBdZJk0ufb2OUgOy5rzK7aOKzkBIdq1WN9ykQAWp4cEhDFMQ+cikDjdtVZp/W bFs9IYDyOQWyp2tXyEsxciM4tXeoF8jf4/A6iOnS5qe/GpFY5WgV5Vbd4prFa31GxBri YNXHLNOgK86i19GEvS7A6tEh4Ia1HA/XOopyrtfM1dCjEYXpxx7lBKkvQFENAkZXRHvB OmafMPo47FR69c66bqQfHtPj9AGQCCBj3Fd2ggHFGLAeLUbj3kiTiltE+2un+fPZw0JD 7NoU9VZ4dcsd/pzoCMzCYlU4R0zko+cdI2uCSvFFQtS8UbXly2gCJy511l45lItITXwx Becw== X-Gm-Message-State: ALoCoQmgacj89nOdaBvGJStPuihuFZ7OPMs8HfsEelRKJybmd0buJ/xmGE3YKpC1TFMeVmxU0ixr X-Received: by 10.236.88.210 with SMTP id a58mr12527810yhf.50.1399909756096; Mon, 12 May 2014 08:49:16 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.102.87 with SMTP id v81ls1398771qge.0.gmail; Mon, 12 May 2014 08:49:16 -0700 (PDT) X-Received: by 10.52.153.229 with SMTP id vj5mr1998226vdb.34.1399909756009; Mon, 12 May 2014 08:49:16 -0700 (PDT) Received: from mail-ve0-f169.google.com (mail-ve0-f169.google.com [209.85.128.169]) by mx.google.com with ESMTPS id ya4si2145051vec.1.2014.05.12.08.49.15 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 12 May 2014 08:49:15 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.128.169 as permitted sender) client-ip=209.85.128.169; Received: by mail-ve0-f169.google.com with SMTP id jx11so9242898veb.0 for ; Mon, 12 May 2014 08:49:15 -0700 (PDT) X-Received: by 10.52.2.229 with SMTP id 5mr19872730vdx.24.1399909755909; Mon, 12 May 2014 08:49:15 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.221.72 with SMTP id ib8csp79807vcb; Mon, 12 May 2014 08:49:15 -0700 (PDT) X-Received: by 10.220.47.201 with SMTP id o9mr1292273vcf.65.1399909755101; Mon, 12 May 2014 08:49:15 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id uc7si6542101pbc.88.2014.05.12.08.49.14; Mon, 12 May 2014 08:49:14 -0700 (PDT) Received-SPF: none (google.com: linux-kernel-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753205AbaELPtE (ORCPT + 27 others); Mon, 12 May 2014 11:49:04 -0400 Received: from mail-ob0-f169.google.com ([209.85.214.169]:51367 "EHLO mail-ob0-f169.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752026AbaELPtC (ORCPT ); Mon, 12 May 2014 11:49:02 -0400 Received: by mail-ob0-f169.google.com with SMTP id vb8so8456407obc.28 for ; Mon, 12 May 2014 08:49:01 -0700 (PDT) X-Received: by 10.60.134.137 with SMTP id pk9mr34932592oeb.40.1399909741346; Mon, 12 May 2014 08:49:01 -0700 (PDT) Received: from localhost.localdomain (adsl-71-136-229-99.dsl.sndg02.pacbell.net. [71.136.229.99]) by mx.google.com with ESMTPSA id jy6sm20837098obc.25.2014.05.12.08.48.59 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 12 May 2014 08:49:00 -0700 (PDT) From: Larry Bassel To: catalin.marinas@arm.com, will.deacon@arm.com Cc: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linaro-kernel@lists.linaro.org, khilman@linaro.org, Larry Bassel Subject: [PATCH v3] arm64: Support arch_irq_work_raise() via self IPIs Date: Mon, 12 May 2014 08:48:51 -0700 Message-Id: <1399909731-21196-1-git-send-email-larry.bassel@linaro.org> X-Mailer: git-send-email 1.8.3.2 Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: larry.bassel@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.128.169 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Support for arch_irq_work_raise() was missing from arm64 (a prerequisite for FULL_NOHZ). This patch is based on the arm32 patches ARM 7872/1 and 7887/1. commit bf18525fd793101df42a1344ecc48b49b62e48c9 Author: Stephen Boyd Date: Tue Oct 29 20:32:56 2013 +0100 ARM: 7872/1: Support arch_irq_work_raise() via self IPIs By default, IRQ work is run from the tick interrupt (see irq_work_run() in update_process_times()). When we're in full NOHZ mode, restarting the tick requires the use of IRQ work and if the only place we run IRQ work is in the tick interrupt we have an unbreakable cycle. Implement arch_irq_work_raise() via self IPIs to break this cycle and get the tick started again. Note that we implement this via IPIs which are only available on SMP builds. This shouldn't be a problem because full NOHZ is only supported on SMP builds anyway. Signed-off-by: Stephen Boyd Reviewed-by: Kevin Hilman Cc: Frederic Weisbecker Signed-off-by: Russell King commit c682e51dbc9837f4aa61180775e9ca4f2a463adf Author: Stephen Boyd Date: Sat Nov 9 00:38:24 2013 +0100 ARM: 7887/1: Don't smp_cross_call() on UP devices in arch_irq_work_raise() If we're running a kernel compiled with SMP_ON_UP=y and the hardware only supports UP operation there isn't any smp_cross_call function assigned. Unfortunately, we call smp_cross_call() unconditionally in arch_irq_work_raise() and crash the kernel on UP devices. Check to make sure we're running on an SMP device before calling smp_cross_call() here. Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = c0004000 [00000000] *pgd=00000000 Internal error: Oops: 80000005 [#1] SMP ARM Modules linked in: CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.12.0-rc6-00018-g8d45144-dirty #16 task: de05b440 ti: de05c000 task.ti: de05c000 PC is at 0x0 LR is at arch_irq_work_raise+0x3c/0x48 pc : [<00000000>] lr : [] psr: 60000193 sp : de05dd60 ip : 00000001 fp : 00000000 r10: c085e2f0 r9 : de05c000 r8 : c07be0a4 r7 : de05c000 r6 : de05c000 r5 : c07c5778 r4 : c0824554 r3 : 00000000 r2 : 00000000 r1 : 00000006 r0 : c0529a58 Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel Control: 10c5387d Table: 80004019 DAC: 00000017 Process swapper/0 (pid: 1, stack limit = 0xde05c248) Stack: (0xde05dd60 to 0xde05e000) dd60: c07b9dbc c00cb2dc 00000001 c08242c0 c08242c0 60000113 c07be0a8 c00b0590 dd80: de05c000 c085e2f0 c08242c0 c08242c0 c1414c28 c00b07cc de05b440 c1414c28 dda0: c08242c0 c00b0af8 c0862bb0 c0862db0 c1414cd8 de05c028 c0824840 de05ddb8 ddc0: 00000000 00000009 00000001 00000024 c07be0a8 c07be0a4 de05c000 c085e2f0 dde0: 00000000 c004a4b0 00000010 de00d2dc 00000054 00000100 00000024 00000000 de00: de05c028 0000000a ffff8ae7 00200040 00000016 de05c000 60000193 de05c000 de20: 00000054 00000000 00000000 00000000 00000000 c004a704 00000000 de05c008 de40: c07ba254 c004aa1c c07c5778 c0014b70 fa200000 00000054 de05de80 c0861244 de60: 00000000 c0008634 de05b440 c051c778 20000113 ffffffff de05deb4 c051d0a4 de80: 00000001 00000001 00000000 de05b440 c082afac de057ac0 de057ac0 de0443c0 dea0: 00000000 00000000 00000000 00000000 c082afbc de05dec8 c009f2a0 c051c778 dec0: 20000113 ffffffff 00000000 c016edb0 00000000 000002b0 de057ac0 de057ac0 dee0: 00000000 c016ee40 c0875e50 de05df2e de057ac0 00000000 00000013 00000000 df00: 00000000 c016f054 de043600 de0443c0 c008eb38 de004ec0 c0875e50 c008eb44 df20: 00000012 00000000 00000000 3931f0f8 00000000 00000000 00000014 c0822e84 df40: 00000000 c008ed2c 00000000 00000000 00000000 c07b7490 c07b7490 c075ab3c df60: 00000000 c00701ac 00000002 00000000 c0070160 dffadb73 7bf8edb4 00000000 df80: c051092c 00000000 00000000 00000000 00000000 00000000 00000000 c0510934 dfa0: de05aa40 00000000 c051092c c0013ce8 00000000 00000000 00000000 00000000 dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 07efffe5 4dfac6f5 [] (arch_irq_work_raise+0x3c/0x48) from [] (irq_work_queue+0xe4/0xf8) [] (irq_work_queue+0xe4/0xf8) from [] (rcu_accelerate_cbs+0x1d4/0x1d8) [] (rcu_accelerate_cbs+0x1d4/0x1d8) from [] (rcu_start_gp+0x34/0x48) [] (rcu_start_gp+0x34/0x48) from [] (rcu_process_callbacks+0x318/0x608) [] (rcu_process_callbacks+0x318/0x608) from [] (__do_softirq+0x114/0x2a0) [] (__do_softirq+0x114/0x2a0) from [] (do_softirq+0x6c/0x74) [] (do_softirq+0x6c/0x74) from [] (irq_exit+0xac/0x100) [] (irq_exit+0xac/0x100) from [] (handle_IRQ+0x54/0xb4) [] (handle_IRQ+0x54/0xb4) from [] (omap3_intc_handle_irq+0x60/0x74) [] (omap3_intc_handle_irq+0x60/0x74) from [] (__irq_svc+0x44/0x5c) Exception stack(0xde05de80 to 0xde05dec8) de80: 00000001 00000001 00000000 de05b440 c082afac de057ac0 de057ac0 de0443c0 dea0: 00000000 00000000 00000000 00000000 c082afbc de05dec8 c009f2a0 c051c778 dec0: 20000113 ffffffff [] (__irq_svc+0x44/0x5c) from [] (_raw_spin_unlock_irq+0x28/0x2c) [] (_raw_spin_unlock_irq+0x28/0x2c) from [] (proc_alloc_inum+0x30/0xa8) [] (proc_alloc_inum+0x30/0xa8) from [] (proc_register+0x18/0x130) [] (proc_register+0x18/0x130) from [] (proc_mkdir_data+0x44/0x6c) [] (proc_mkdir_data+0x44/0x6c) from [] (register_irq_proc+0x6c/0x128) [] (register_irq_proc+0x6c/0x128) from [] (init_irq_proc+0x74/0xb0) [] (init_irq_proc+0x74/0xb0) from [] (kernel_init_freeable+0x84/0x1c8) [] (kernel_init_freeable+0x84/0x1c8) from [] (kernel_init+0x8/0x150) [] (kernel_init+0x8/0x150) from [] (ret_from_fork+0x14/0x2c) Code: bad PC value Fixes: bf18525fd79 "ARM: 7872/1: Support arch_irq_work_raise() via self IPIs" Reported-by: Olof Johansson Signed-off-by: Stephen Boyd Tested-by: Olof Johansson Signed-off-by: Russell King Changes v2 to v3: * Do not call is_smp() as this is only defined on arm32 Changes v1 to v2: * Include ARM 7887/1 bugfix Signed-off-by: Larry Bassel Reviewed-by: Kevin Hilman --- arch/arm64/include/asm/hardirq.h | 2 +- arch/arm64/kernel/smp.c | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/hardirq.h b/arch/arm64/include/asm/hardirq.h index ae4801d..0be6782 100644 --- a/arch/arm64/include/asm/hardirq.h +++ b/arch/arm64/include/asm/hardirq.h @@ -20,7 +20,7 @@ #include #include -#define NR_IPI 5 +#define NR_IPI 6 typedef struct { unsigned int __softirq_pending; diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index f0a141d..049aa8d 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -62,6 +63,7 @@ enum ipi_msg_type { IPI_CALL_FUNC_SINGLE, IPI_CPU_STOP, IPI_TIMER, + IPI_IRQ_WORK, }; /* @@ -455,6 +457,14 @@ void arch_send_call_function_single_ipi(int cpu) smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE); } +#ifdef CONFIG_IRQ_WORK +void arch_irq_work_raise(void) +{ + if (smp_cross_call) + smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK); +} +#endif + static const char *ipi_types[NR_IPI] = { #define S(x,s) [x - IPI_RESCHEDULE] = s S(IPI_RESCHEDULE, "Rescheduling interrupts"), @@ -462,6 +472,7 @@ static const char *ipi_types[NR_IPI] = { S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"), S(IPI_CPU_STOP, "CPU stop interrupts"), S(IPI_TIMER, "Timer broadcast interrupts"), + S(IPI_IRQ_WORK, "IRQ work interrupts"), }; void show_ipi_list(struct seq_file *p, int prec) @@ -554,6 +565,14 @@ void handle_IPI(int ipinr, struct pt_regs *regs) break; #endif +#ifdef CONFIG_IRQ_WORK + case IPI_IRQ_WORK: + irq_enter(); + irq_work_run(); + irq_exit(); + break; +#endif + default: pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr); break;