Received: by 2002:a05:6902:102b:0:0:0:0 with SMTP id x11csp2073588ybt; Sun, 28 Jun 2020 07:15:22 -0700 (PDT) X-Google-Smtp-Source: ABdhPJx3ZsG+3OTLjVnzc2uhmo1DM8vLSJ4rqgpIrnKEIB8t5XeEW2PoealGRq73fMFaskhPLdJa X-Received: by 2002:a50:cf05:: with SMTP id c5mr13459200edk.232.1593353722591; Sun, 28 Jun 2020 07:15:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1593353722; cv=none; d=google.com; s=arc-20160816; b=uSnlIrRif8LBxVPfV9zNrJh6uwToJCbXZ9+iA+70sdwbPF7N7nd8LDnrcI8GBbLbHA XjRhTA+kD00lJVdoB7rUzYpcdo5gWn1zUTAOqMmZ6DMvHY5JbmGPdKLtO51r04obnD5B Yc29y5kR1HNHWwLhMihkPLgj0lEZIVMyQNmXqVp2h79ONt3/+Y+dFTkkEOn6oAI2/vWE paggQPXD2r8/+urEDYnnwWInB4MAR4TOL2hVu4G/fiMFvyMegGyuGjlfNNEJXKYe+c5R i5WTUMDRLkd/HbTO4HxUDbnhksemLK4PTDM6dHEMiVIBKJmLwZZR8Ho568GonZ7b+bJM d79w== 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=eKCD7ZTYxhamcNuQn211J6fwI1SYysOc9utHpbcTC/Q=; b=tk7GcSRJ4AwiDYj/WI7562DC6rh2gu2FKx9yiAeFa/IzgglOH62/PIQxzqj0tkhKrW ccvwVd49moIH45VnOLbbXWJ9X1+66PgY8QlA/VAfQGOPYoaZs27pPJBtGJzW/K2Im5LP k53r+V5+dbZeyci5wco+YFnLLvvJoTQsr2rZbrMHFIMLYPffQKyfwQsoukCQnHWWwRJT b/Pgcn5WUN4VZszenh/PVl1hwKN5UPEta4iBkR4IGWuIPN0bbF6utAPfkpZnCgFXwTLq Vxdpw/4q+2yb2ldMjeiXFpIKOllnv4XWsq6DJirOMZT4WUs+WYhp6KyKA4RceeRoV/dV 9XyA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=SYPrOcU6; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id k4si8162415eds.446.2020.06.28.07.15.00; Sun, 28 Jun 2020 07:15:22 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=SYPrOcU6; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726537AbgF1OMl (ORCPT + 99 others); Sun, 28 Jun 2020 10:12:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57166 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726344AbgF1OMl (ORCPT ); Sun, 28 Jun 2020 10:12:41 -0400 Received: from mail-lj1-x241.google.com (mail-lj1-x241.google.com [IPv6:2a00:1450:4864:20::241]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B55D2C061794 for ; Sun, 28 Jun 2020 07:12:40 -0700 (PDT) Received: by mail-lj1-x241.google.com with SMTP id f8so2982906ljc.2 for ; Sun, 28 Jun 2020 07:12:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=eKCD7ZTYxhamcNuQn211J6fwI1SYysOc9utHpbcTC/Q=; b=SYPrOcU6E/TtpD8R3UTy33dOKJDaVtNkHq0DybfwWKCNpwKP44bpfSE+N4e3K8rt6S zhQIZHjMT1fvyzpvwXNKdarqoW9vwswPjdSnWlTt7l4Oqae+Bls2hwjT+E541eMguKFe lbPcfGi0lzO9Yyp0BMRyHJpjiHEinLc5GmBUXer9lhHwa/CNHvPCoibA5wUzgCwlBp3n TOVExQZG7+K42txmGZW6s1AQm6O1vDKkF/XsXky+0+RBAZUQYKKvHI6BIjnERBg6OE3f 0MlTouSBEC3i2Gj6RyGitmRXGHFJItDGNBCn7H1UnhQ8HlBJZfsjKJw4N04niqv8Anvg h8cw== 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=eKCD7ZTYxhamcNuQn211J6fwI1SYysOc9utHpbcTC/Q=; b=XUKfrujcd27tpissGHlvLu0/NkTHj/rlhmzz3AEbkF7YAQM89gsOP/F3M/kX/p2KBX p9oPlNEiZq848z0LrXGNkaGts3vS5troXtAOmMz5tyGMFDobB5FOoxSPTcglY8IYsCAp 1xz0chww0vGQaEiKXllIbP5AhWTLETy/TDvJ8qlj8CAr/ykfQjFpKvCVhv/wR4GLxaTz sqtC2LHt1mQLYOFXr7ihgSfNlyBrA3qpuvmWEY69vu4hV+GhBDa+RH7vWGXsLjMJ9e+m PSWKxvhKs5uZTNusDIFCjJuCA9hF9DULWmqn0c9rnF2qKB/uEy5RN1DCi/L3u5EG+a4q LhZg== X-Gm-Message-State: AOAM532KHVLyjOZ/BLTvxQukO0JEqhuoyB1Gk6njP2ozN7c1atLkerv+ sMXAxazQ9oiCRNZbqDOapNOjbqYomGu5iQ== X-Received: by 2002:a2e:8346:: with SMTP id l6mr5623825ljh.209.1593353558808; Sun, 28 Jun 2020 07:12:38 -0700 (PDT) Received: from natalie.tramplemo.net (2.65.45.120.mobile.tre.se. [2.65.45.120]) by smtp.googlemail.com with ESMTPSA id q13sm8390625lfb.55.2020.06.28.07.12.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 28 Jun 2020 07:12:38 -0700 (PDT) From: Thommy Jakobsson To: linux-kernel@vger.kernel.org Cc: dan.carpenter@oracle.com, gregkh@linuxfoundation.org, Thommy Jakobsson Subject: [PATCH v2] uio: disable lazy irq disable to avoid double fire Date: Sun, 28 Jun 2020 16:12:29 +0200 Message-Id: <20200628141229.16121-1-thommyj@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200521144209.19413-1-thommyj@gmail.com> References: <20200521144209.19413-1-thommyj@gmail.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org uio_pdrv_genirq and uio_dmem_genirq interrupts are handled in userspace. So the condition for the interrupt hasn't normally not been cleared when top half returns. disable_irq_nosync is called in top half, but since that normally is lazy the irq isn't actually disabled. For level triggered interrupts this will always result in a spurious additional fire since the level in to the interrupt controller still is active. The actual interrupt handler isn't run though since this spurious irq is just recorded, and later on discared (for level). This commit disables lazy masking for level triggered interrupts. It leaves edge triggered interrupts as before, because they work with the lazy scheme. All other UIO drivers already seem to clear the interrupt cause at driver levels. Example of double fire. First goes all the way up to uio_pdrv_genirq_handler, second is terminated in handle_fasteoi_irq and marked as pending. -0 [000] d... 8.245870: gic_handle_irq: irq 29 -0 [000] d.h. 8.245873: uio_pdrv_genirq_handler: disable irq 29 -0 [000] d... 8.245878: gic_handle_irq: irq 29 -0 [000] d.h. 8.245880: handle_fasteoi_irq: irq 29 PENDING HInt-34 [001] d... 8.245897: uio_pdrv_genirq_irqcontrol: enable irq 29 Tested on 5.7rc2 using uio_pdrv_genirq and a custom Xilinx MPSoC board. Signed-off-by: Thommy Jakobsson --- New in v2: - use dev_dbg instead of dev_info - make sure not to change current behaviour. If irq_data doesn't exists for some reasone, just skip doing disabling unlazy altogether - with above also the wrongly added kfree is removed (found by kbuild test robot) I did not add the Reported-by tag for the kbuild test robot finding. Not sure about the correct procedure here, but since it found the error in a patch not merged, my reasoning was that it would look wrong in the git log later on. Please advice if this is customary anyway. drivers/uio/uio_dmem_genirq.c | 19 +++++++++++++++++++ drivers/uio/uio_pdrv_genirq.c | 18 ++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c index 6e27fe4fcca3..ec7f66f4555a 100644 --- a/drivers/uio/uio_dmem_genirq.c +++ b/drivers/uio/uio_dmem_genirq.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -199,6 +200,24 @@ static int uio_dmem_genirq_probe(struct platform_device *pdev) goto bad1; uioinfo->irq = ret; } + + if (uioinfo->irq) { + struct irq_data *irq_data = irq_get_irq_data(uioinfo->irq); + + /* + * If a level interrupt, dont do lazy disable. Otherwise the + * irq will fire again since clearing of the actual cause, on + * device level, is done in userspace + * irqd_is_level_type() isn't used since isn't valid until + * irq is configured. + */ + if (irq_data && + irqd_get_trigger_type(irq_data) & IRQ_TYPE_LEVEL_MASK) { + dev_dbg(&pdev->dev, "disable lazy unmask\n"); + irq_set_status_flags(uioinfo->irq, IRQ_DISABLE_UNLAZY); + } + } + uiomem = &uioinfo->mem[0]; for (i = 0; i < pdev->num_resources; ++i) { diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c index ae319ef3a832..6de0b115c2da 100644 --- a/drivers/uio/uio_pdrv_genirq.c +++ b/drivers/uio/uio_pdrv_genirq.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -171,6 +172,23 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev) } } + if (uioinfo->irq) { + struct irq_data *irq_data = irq_get_irq_data(uioinfo->irq); + + /* + * If a level interrupt, dont do lazy disable. Otherwise the + * irq will fire again since clearing of the actual cause, on + * device level, is done in userspace + * irqd_is_level_type() isn't used since isn't valid until + * irq is configured. + */ + if (irq_data && + irqd_get_trigger_type(irq_data) & IRQ_TYPE_LEVEL_MASK) { + dev_dbg(&pdev->dev, "disable lazy unmask\n"); + irq_set_status_flags(uioinfo->irq, IRQ_DISABLE_UNLAZY); + } + } + uiomem = &uioinfo->mem[0]; for (i = 0; i < pdev->num_resources; ++i) { -- 2.17.1