Received: by 10.223.185.116 with SMTP id b49csp8945561wrg; Fri, 2 Mar 2018 10:36:12 -0800 (PST) X-Google-Smtp-Source: AG47ELufNr5RIS2AgeTXy3iyLK0di0Xd6MEkicGSv+jqGM6HXBEu/eQhsilM+bHFN1UEtI2+JI5N X-Received: by 2002:a17:902:341:: with SMTP id 59-v6mr5934000pld.64.1520015772125; Fri, 02 Mar 2018 10:36:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520015772; cv=none; d=google.com; s=arc-20160816; b=yO3+k4141Agpv0/x1s/IdigGtizJ3mwDDkMJ0rfs7c9Otjpsr2HPtLUu0ekf1lKXtR koDwQjZfQ9SecDXp0X69WKWDFn5cVFXrQDTu9sLTud+yb1HMRaWkseBjisvB/+qPzm3j YB8u9NivXNaTv3sFcMSbGasfv/qQdFaBZCsXYljuTzbal7nNK2Dqc1yQA9/dU9d8qGce lJCDCPB5yH925l4oT52bAp3/fe/FsNRxJT4ygc46M6K21Lpa3FXQbJIhlIbuO0gdV72P 2T/1Rc76qiywG+IO+GNx0UCWBLwuUwZyb+yw9FSSO7pABlkRtQeNO5r69K1ha7cFPNi8 EX5w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :references:in-reply-to:mime-version:dkim-signature :arc-authentication-results; bh=rJm07ldpo4X2lJdBlZaAhDplQgoq8jBmECO/41qFSu4=; b=PBR2rgpcNmOEDZHgEvSGJnCNkI6NqB4atLrdqxsRA6phxJZalAfv4MWc8C3tiFqoUZ hQkhnXXgBK76z1GDsVGSdbvEgaPYbC22OOOd4GuA0T9wZkgyj4VXP38aD0HzlOyPkaa8 +X2y+/N4Du3HfK9jZwUmm8Ruv2cdi6JSQOc1FpP44zzkPbIkUgr80koRfOb3z02avh7/ DhpAkPZvV5JqBvCmZdKslqiLlnAiTyPPqryr349//YRxPkp2f6o8NpTLOj32qb36VZ/p lcLU61SX6yIQ06taar1pNni82Gad2/rLggagNch+BCMttkeBbZ/YTjHC1+7H8p3K4ZKh eb9w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@semihalf-com.20150623.gappssmtp.com header.s=20150623 header.b=ll74V65m; 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 bi2-v6si236558plb.645.2018.03.02.10.35.55; Fri, 02 Mar 2018 10:36:12 -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=@semihalf-com.20150623.gappssmtp.com header.s=20150623 header.b=ll74V65m; 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 S936279AbeCBL4a (ORCPT + 99 others); Fri, 2 Mar 2018 06:56:30 -0500 Received: from mail-pg0-f66.google.com ([74.125.83.66]:40670 "EHLO mail-pg0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934881AbeCBL4Z (ORCPT ); Fri, 2 Mar 2018 06:56:25 -0500 Received: by mail-pg0-f66.google.com with SMTP id g2so3695875pgn.7 for ; Fri, 02 Mar 2018 03:56:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=rJm07ldpo4X2lJdBlZaAhDplQgoq8jBmECO/41qFSu4=; b=ll74V65mOn2JLzXG12m7h5VS3suKhYFRWyC+I51eqyKOhyPuMVHmbA92yB2/qFU751 bhgcEYHv7RvLfB6lVgn6KNWeo8+6g1KjqzgvZZjpbmFfiEH5dLuoOMRP7Zy59DPmRs2H TnSDRLbJfGlwyghnONKEf2uCiVyFIok7jW0GgzRpTyxsMdF9HcpLmtq5eohOFQBOJRd4 bxX2BeKr+oXqqw7CXpFBKGGm/VPTlPBySzIS83anzPSiOgsMmSwuUjTgpGqkQVJBkBPI sYVbpZqtNSwH5hvTDrOSVKJnVrsCY3P3+z2SttKWsXxMw5FH/yO49+og5hkRDuY05PPR q1xg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=rJm07ldpo4X2lJdBlZaAhDplQgoq8jBmECO/41qFSu4=; b=GBaMeqfxhcUXVC/+BN6YLdfeNQEIWVl54z2FMoqv7KYzBSaP6Wuq+XXUtgdyIDQfCb 9tWoWNQxm0JV8u4aMyxzXFcpuKq/Y4TaDPGsVsNS/GvXkl6he4yIAcRMb0e8yycv5hfN tTXvBnnDQKGTm7s8ZGXaAjoMYeHBHJnimGoxT6WHGD7f04LlwtHZqiJIxu0rRR8r2Wti wl/X7pAcEQrqsX+g45GZuBdUTMuFObODTpflhASaU9P69ekghPkCoqFbWxg/ja+yhqar G151KERWC4CbvGz8xvfLcRlp9thLLVox+dh/Q3AVH/4NQgXW2Lsy57O4Z8j166Wy9XRN iwkA== X-Gm-Message-State: APf1xPBqOJSFIZPzeOJAxz2F2amolbXKKIs+zk5FJ8vwmok8I5Ab92rH GKWsY4Z0YXAAaSMG8zgmUofioSd0+hcf05+3muYyZA== X-Received: by 10.101.91.133 with SMTP id i5mr4282766pgr.20.1519991785176; Fri, 02 Mar 2018 03:56:25 -0800 (PST) MIME-Version: 1.0 Received: by 10.236.140.148 with HTTP; Fri, 2 Mar 2018 03:56:24 -0800 (PST) In-Reply-To: References: <1519837260-30662-1-git-send-email-jaz@semihalf.com> <20180228171647.6t4dabntujcb5kon@lakrids.cambridge.arm.com> From: Grzegorz Jaszczyk Date: Fri, 2 Mar 2018 12:56:24 +0100 Message-ID: Subject: Re: [PATCH] arm64: kdump: fix interrupt handling done during machine_crash_shutdown To: Marc Zyngier , Mark Rutland Cc: catalin.marinas@arm.com, will.deacon@arm.com, james.morse@arm.com, "AKASHI, Takahiro" , Hoeun Ryu , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Nadav Haklai , Marcin Wojtas Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Thank you for your feedback. I probably over-interpreted some of the documentation paragraph to justify (probably) buggy behavior that I am seeing. Regardless of correctness of this patch I will appreciate if you could help understanding this issue. First the whole story: I was debugging why the crashdump kernel hangs in v. early stage, when the kdump was triggered from the ARM_SBSA_WATCHDOG interrupt handler, while everything worked fine when it was triggered from the process context. Finally It occurred that it is because the crashdump kernel doesn't get any timer interrupt. I also notice that this problem doesn't occur when the gic is configured to work in EOImode == 1. In such circumstances, the write to GIC_CPU_EOI in gic_handle_irq is causing priority drop to idle, and therefore when the crashdump kernel starts, the timer interrupt is able to preempt still active watchdog interrupt (I know that this interrupt shouldn't be active after irq_set_irqchip_state but for some reason it seems to not do the job correctly). In my commit log I wrongly describe the bahaviour of irq_set_irqchip_state and irq_get_irqchip_state. In machine_kexec_mask_interrupts (when watchdog interrupt is active) after adding some debugs I see that (focusing only on watchdog interrupt): 1) before calling irq_set_irqchip_state when I check the status with irq_get_irqchip_state I see that watchdog interrupt is active 2) decative interrupt via irq_set_irqchip_state 3) check the status via irq_get_irqchip_state which indicates that the status has changed to inactive, so everything seems to be fine, but still in crashdump kernel I don't get any interrupts (when the EOImode == 0). When I modify the machine_kexec_mask_interrupts, to call the eoi for watchdog (only temporary to observe the effect): if (i == watchdog_irq) chip->irq_eoi(&desc->irq_data); everything is working. So it seems that deactivating the interrupt via write to GIC_CPU_EOI (EOImode == 0) or GIC_CPU_EOI + GIC_CPU_DEACTIVATE (EOImode == 1) does the job, while deactivating it with use of GIC_DIST_ACTIVE_CLEAR doesn't. I am using the unmodified GICv2m ("arm,gic-400") and the watchdog interrupt is connected as one of the SPI. Do you have any idea what can be wrong? Maybe I am missing something? gic configuration? I also don't exclude that nobody who work with kdump doesn't use (EOImode == 0) and therefore didn't see this behavior. Thank you in advance, Grzegorz 2018-02-28 18:45 GMT+01:00 Marc Zyngier : > On 28/02/18 17:16, Mark Rutland wrote: >> [Adding MarcZ] >> >> On Wed, Feb 28, 2018 at 06:01:00PM +0100, Grzegorz Jaszczyk wrote: >>> Hitherto during machine_kexec_mask_interrupts there was an attempt to >>> remove active state using irq_set_irqchip_state() routine and only if it >>> failed, the attempt to EOI the interrupt was made. Nevertheless relaying >>> on return value from irq_set_irqchip_state inside >>> machine_kexec_mask_interrupts is incorrect - it only returns the status >>> of the routine but doesn't provide information if the interrupt was >>> deactivated correctly or not. >> >> This doesn't sound right. The return value of irq_set_irqchip_state() is >> certainly supposed to indicate that it did what it was asked to (i.e. >> correctly (de)activated the interrupt). >> >> IIUC, you're saying that there's a problem whereby: >> >> (a) irq_set_irqchip_state() returns succesfully, but: >> >> (b) irq_set_irqchip_state() does not alter the interrupt state to that >> requested. >> >> ... which sounds like a bug. >> >> When does this happen, exactly? >> >> Thanks, >> Mark. >> >>> Therefore the irq_eoi wasn't call even if the interrupt remained >>> active. >>> >>> To determine the sate correctly the irq_get_irqchip_state() could be >>> used but according to the ARM Generic Interrupt Controller Architecture >>> Spec, non-secure reading from GICD_ISACTIVERn/GICD_ICACTIVERn can be not >>> permitted (depending on NS_access setting of Non-secure Access Control >>> Registers, a.k.a. GICD_NSACRn). What is more interesting GICD_NSACRn >>> is optional Secure register. > > All the Linux interrupts are either non-secure, or accessible using > non-secure accessors. I'm afraid you're misunderstanding a thing or two > about the architecture. > >>> >>> Moreover de-activating the interrupt via GICD_ISACTIVERn register >>> (regardless of the possibility of checking status or not) seems to not >>> do the job, when the GIC Distributor is configured to forward the >>> interrupts to the CPU interfaces. > > Then you seem to have really buggy HW. > >>> >>> Because of all above the attempt to deactivate interrupts via >>> irq_set_irqchip_state() is removed in this patch. Instead the irq_eoi is >>> called whenever the interrupt is in progress(irqd_irq_inprogress). >>> >>> Before this patch the kdump triggered from interrupt context worked >>> correctly by accident when the GIC was configured with >>> GIC_CPU_CTRL_EOImodeNS == 1 (supports_deactivate == true). In mentioned >>> mode GIC_CPU_EOI has priority drop functionality only and >>> GIC_CPU_DEACTIVATE is used for interrupt deactivation. Also the >>> gic_handle_irq behaviour is a bit different in mentioned mode and >>> performs write to the GIC_CPU_EOI which causes the priority drop to the >>> idle priority. So even if the irq_eoi wasn't called during >>> machine_kexec_mask_interrupts, the interrupts of the crashdump kernel >>> was handled due to interrupt preemption (since the priority of still >>> active interrupt was dropped to idle priority). >>> >>> Nevertheless when the kdump was triggered from interrupt context while >>> the GIC was configured to work in GIC_CPU_CTRL_EOImodeNS == 0, the >>> crashdump kernel hang in early stage due to lack of timer interrupt >>> arrival. >>> >>> After this fix the kdump behaves correctly when triggered from interrupt >>> context independently of GIC_CPU_CTRL_EOImodeNS configuration. >>> >>> Signed-off-by: Grzegorz Jaszczyk >>> --- >>> arch/arm64/kernel/machine_kexec.c | 10 +--------- >>> 1 file changed, 1 insertion(+), 9 deletions(-) >>> >>> diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c >>> index f76ea92..30ad183 100644 >>> --- a/arch/arm64/kernel/machine_kexec.c >>> +++ b/arch/arm64/kernel/machine_kexec.c >>> @@ -220,20 +220,12 @@ static void machine_kexec_mask_interrupts(void) >>> >>> for_each_irq_desc(i, desc) { >>> struct irq_chip *chip; >>> - int ret; >>> >>> chip = irq_desc_get_chip(desc); >>> if (!chip) >>> continue; >>> >>> - /* >>> - * First try to remove the active state. If this >>> - * fails, try to EOI the interrupt. >>> - */ >>> - ret = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false); >>> - >>> - if (ret && irqd_irq_inprogress(&desc->irq_data) && >>> - chip->irq_eoi) >>> + if (irqd_irq_inprogress(&desc->irq_data) && chip->irq_eoi) > > This really doesn't make any sense. Either you've successfully > deactivated the interrupt, or you haven't. Doing both is a terrible > violation of the GIC architecture, don't do that. There is also 0 > guarantee that the interrupt was active on the CPU you're currently > running. If you activated it on another CPU, good luck. > > To echo to Mark's concerns, you don't explain the root cause: Why is > irq_set_irqchip_state silently failing? With what IRQ type? On what GIC > implementation? > >>> chip->irq_eoi(&desc->irq_data); >>> >>> if (chip->irq_mask) > > As it stands, this patch breaks more things than it should. I'd suggest > you start from the beginning and explain the issue you're facing. > > Thanks, > > M. > -- > Jazz is not dead. It just smells funny...