From patchwork Thu Aug 20 03:16:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: qiuguorui1 X-Patchwork-Id: 11725373 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E20CC1392 for ; Thu, 20 Aug 2020 03:02:24 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id BB87B2078B for ; Thu, 20 Aug 2020 03:02:24 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="NETBRUjp" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org BB87B2078B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=huawei.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:Message-ID:Date:Subject:To:From: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Owner; bh=udKwzT8PZ2cNZKLr7XJw4rjMfjpmFV3UozWOutCqxAs=; b=NETBRUjpxtbyv1DobZTsNv5/wN FAAi2wXKPCWtHzMzEYIfTP45S+66CDnqVI0hErjMTMmO5NC5NC4fpbuSow5KqBhvOQMjtsKolU1nP jkAfqpM0le1/lFZWH+Y+pNxW01jsZ6pH5HXzEkagp8dviov7GPZtFUy2ZorKdIbD+iKaELN3zSZOJ p0XkWvCTyNHooKmzzCV9CtoKWusfvsDxh5D/reNzSydIA42sWTfYPDoH2zWirrl75zjndT9EE0xvx gUfi7N6uhSxT+UFYez8pgL6A+qgfajq0ZL/uIodUU4FajeCe/wy6Kfn6HiCzI4xsdlToCVmihOWjL ywefsisg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1k8aoT-000214-VP; Thu, 20 Aug 2020 03:00:26 +0000 Received: from szxga04-in.huawei.com ([45.249.212.190] helo=huawei.com) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1k8aoQ-00020V-6U for linux-arm-kernel@lists.infradead.org; Thu, 20 Aug 2020 03:00:23 +0000 Received: from DGGEMS414-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id B39FA6764CA30B10BBD2; Thu, 20 Aug 2020 11:00:16 +0800 (CST) Received: from huawei.com (10.90.52.227) by DGGEMS414-HUB.china.huawei.com (10.3.19.214) with Microsoft SMTP Server id 14.3.487.0; Thu, 20 Aug 2020 11:00:08 +0800 From: qiuguorui1 To: , , , , , Subject: [PATCH v2] irqchip/stm32-exti: avoid interrupts losing due to clearing pending bit by mistake Date: Thu, 20 Aug 2020 11:16:29 +0800 Message-ID: <20200820031629.15582-1-qiuguorui1@huawei.com> X-Mailer: git-send-email 2.12.3 MIME-Version: 1.0 X-Originating-IP: [10.90.52.227] X-CFilter-Loop: Reflected X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200819_230022_484489_9D925D57 X-CRM114-Status: GOOD ( 13.37 ) X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [45.249.212.190 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record 0.0 RCVD_IN_MSPIKE_H4 RBL: Very Good reputation (+4) [45.249.212.190 listed in wl.mailspike.net] 0.0 RCVD_IN_MSPIKE_WL Mailspike good senders X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: chenjianguo3@huawei.com, qiuguorui1@huawei.com, linux-kernel@vger.kernel.org, zengweilin@huawei.com, linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org In the previous code, when the eoi handle of the exti clears the pending bit of the current interrupt, it will first read the values of fpr and rpr, then logically OR the corresponding bit of the interrupt number, and finally write back to fpr and rpr. We found through experiments that if two exti interrupts, we call them int1/int2, arrive almost at the same time. in our scenario, the time difference is 30 microseconds, assuming int1 is triggered first. there will be an extreme scenario: both int's pending bit are set to 1, the irq handle of int1 is executed first, and eoi handle is then executed, at this moment, all pending bits are cleared, but the int 2 has not finally been reported to the cpu yet, which eventually lost int2. According to stm32's TRM description about rpr and fpr: Writing a 1 to this bit will trigger a rising edge event on event x, Writing 0 has no effect. Therefore, when clearing the pending bit, we only need to clear the pending bit of the irq. Changes in v2: - simplify the code by calling writel_relaxed directly in the function stm32_exti_h_eoi. v1:https://lore.kernel.org/lkml/20200819023931.28997-1-qiuguorui1@huawei.com/ Signed-off-by: qiuguorui1 Fixes: 927abfc4461e7 ("irqchip/stm32: Add stm32mp1 support with hierarchy domain") Cc: stable@vger.kernel.org # v4.18+ --- drivers/irqchip/irq-stm32-exti.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c index 03a36be757d8..0c2c61db26b4 100644 --- a/drivers/irqchip/irq-stm32-exti.c +++ b/drivers/irqchip/irq-stm32-exti.c @@ -416,6 +416,16 @@ static void stm32_irq_ack(struct irq_data *d) irq_gc_unlock(gc); } +/* directly set the target bit without reading first. */ +static inline void stm32_exti_write_bit(struct irq_data *d, u32 reg) +{ + struct stm32_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d); + void __iomem *base = chip_data->host_data->base; + u32 val = BIT(d->hwirq % IRQS_PER_BANK); + + writel_relaxed(val, base + reg); +} + static inline u32 stm32_exti_set_bit(struct irq_data *d, u32 reg) { struct stm32_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d); @@ -449,9 +459,9 @@ static void stm32_exti_h_eoi(struct irq_data *d) raw_spin_lock(&chip_data->rlock); - stm32_exti_set_bit(d, stm32_bank->rpr_ofst); + stm32_exti_write_bit(d, stm32_bank->rpr_ofst); if (stm32_bank->fpr_ofst != UNDEF_REG) - stm32_exti_set_bit(d, stm32_bank->fpr_ofst); + stm32_exti_write_bit(d, stm32_bank->fpr_ofst); raw_spin_unlock(&chip_data->rlock);