Received: by 2002:a25:868d:0:0:0:0:0 with SMTP id z13csp1474516ybk; Thu, 21 May 2020 07:44:52 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyG8vXH2/+Pu8s+j0tDndfJfBBuvFZ37c4Go/K0o4YYDPVuCiOl406SYMCfMqTpahUceQqR X-Received: by 2002:a17:906:328c:: with SMTP id 12mr3999267ejw.69.1590072292626; Thu, 21 May 2020 07:44:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1590072292; cv=none; d=google.com; s=arc-20160816; b=Q1VYd1iLSRioXQ4mjy2ngzzvhg3Vx8SnHXUjfHoF+Lc97SJgtI8pO8IGBnMpZoxgQ4 +zXT4QUxUHdYtqAobxyejN0LjOvcPScmEF+nnbkzL93/IoZEfiK2nV3PY/5o2cmug1Zn jiREZgsd+I4/nG6q5X9WDaM+N5J9IFXqxDguKsMX9UZKuQNzmPc/FcwmYVgwAFJ5QM3Q i9dwMD4gXnEJB/OAWQZZAcxjtj3OA7TcXRhTJxCPulT2qeoLY7DhLtInvaSurOVyizMc Yy+RyFFKOrti5TBz9wZiXLy4lagRypaDLN4xLyuAWXRPUbQpgZVjAOutse0VzOuBB5eq V2Fw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature; bh=0f/O3Jvsm3O6csBt/1m3GZlLURu8oNsJZqakDLTmCNY=; b=bdHUxm1BsS1jKhTzFEVuuAhkkQahLVqEaheELR0eHGs12uSZMd4XuD9uTYy4GE+NiR ZnxSXxt84tXoYSOCColdx+QyipAzBxFiJIcJPwaSTXF3co7Y6ht8g2I/8Elj4KiviZne dXEHEstJKUJ/M6lq5rGs1vfTvqe8s2FDuKbln65oFIdFD3JaR12zVogHy79aUS3letbv JPxJI3KZ/la2MesfMemrKpIgSWHZyZSLH2jQtAFqj2fcnLV4mhLdUwrQBM2pV3bdculq Tnk4spCvmxoY/40DICibKFAbxVMzO5ss42miZnbs5twqZRXOLxAGd/NME1jjsrqU1Ffv +oGQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=jPqt++gm; 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 o6si3088385edz.574.2020.05.21.07.44.28; Thu, 21 May 2020 07:44:52 -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=jPqt++gm; 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 S1729815AbgEUOmr (ORCPT + 99 others); Thu, 21 May 2020 10:42:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57006 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729840AbgEUOmr (ORCPT ); Thu, 21 May 2020 10:42:47 -0400 Received: from mail-lf1-x143.google.com (mail-lf1-x143.google.com [IPv6:2a00:1450:4864:20::143]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CF9C6C061A0E for ; Thu, 21 May 2020 07:42:46 -0700 (PDT) Received: by mail-lf1-x143.google.com with SMTP id c12so4578980lfc.10 for ; Thu, 21 May 2020 07:42:46 -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; bh=0f/O3Jvsm3O6csBt/1m3GZlLURu8oNsJZqakDLTmCNY=; b=jPqt++gmAqGoeMpnUkqKDp2jclje4mtrndExyagaECcGCuE5xDC3xEGQn24SQOMM2v 6Ng9XhBXZTrsp/CUZ7NcBDGI9ZYfJuv3m3vEJ8pkLeGfU6LxG3tjfZu18Gv9pT3QqJlN 7g0DQze55Q0eIjX/e/NACZlvAaU7EK7ZE0gM9nOx4b3FxSVZbF4FovnZyimcqtiFZeUt KHPNrQbGftnDYBiyRWITDJRPtprnXO2M/ILTKR3jNNR5sRASwRxQaBr/UbCy2oVna5RF ruWDfgimM9u+yxyNTwUGkL4AAFBPuUhHlBOzGBiNkVpeiMLDfBp8o1izKlEdhO1w5M0T 0GCQ== 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; bh=0f/O3Jvsm3O6csBt/1m3GZlLURu8oNsJZqakDLTmCNY=; b=ICCXCiU6qFLUwgFjaZCVsxuplVVflqB0nOFn9KfvoaeB0gexQDjMXEKooH+Jsxy0JW 7IJplRGUa5/Q+zCELujbCg8QeEL1vxUGNTbOjecPsQJUrAH3VFN54JTQGLWAUbuGlMt6 EQmr1XsTJ32VXOzyfcOCP+Fz4mbKbFbDORug1ib8sI1MGptRF3YIyvCuDIX+A9r6ZR0Q Lz4Pz4QmQMsf6A1KBwQQ/FL9F3aZJLk8/VJIzhjv4cuUyf8OQBT4H1yPaUGkUzRU5BXc Q4b6pn0k4i06l/VOZ5IaIsZJ2m0cm4/ms/zAwIY4jOL5byRgSTeW2EjvJCP9mf/nWtWC vkZQ== X-Gm-Message-State: AOAM533m2qttoNAS0eTnTFSfg16KeHXm45CyrAuW2y3klc9Rgitw+OVO DmUAzVA04pWuU5+HJJQwrv8= X-Received: by 2002:a19:5f4e:: with SMTP id a14mr5232403lfj.57.1590072165163; Thu, 21 May 2020 07:42:45 -0700 (PDT) Received: from natalie.tramplemo.net (2.64.211.114.mobile.tre.se. [2.64.211.114]) by smtp.googlemail.com with ESMTPSA id h2sm2004303ljb.45.2020.05.21.07.42.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 May 2020 07:42:44 -0700 (PDT) From: Thommy Jakobsson To: gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org Cc: Thommy Jakobsson Subject: [PATCH] uio: disable lazy irq disable to avoid double fire Date: Thu, 21 May 2020 16:42:09 +0200 Message-Id: <20200521144209.19413-1-thommyj@gmail.com> X-Mailer: git-send-email 2.17.1 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 --- drivers/uio/uio_dmem_genirq.c | 24 ++++++++++++++++++++++++ drivers/uio/uio_pdrv_genirq.c | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c index f6ab3f28c838..14899ed19143 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 @@ -200,6 +201,29 @@ 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 + */ + if (!irq_data) { + dev_err(&pdev->dev, "unable to get irq data\n"); + ret = -ENXIO; + goto bad1; + } + /* + * irqd_is_level_type() isn't used since isn't valid unitil + * irq is configured. + */ + if (irqd_get_trigger_type(irq_data) & IRQ_TYPE_LEVEL_MASK) { + dev_info(&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..abf8e21d7158 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,29 @@ 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 + */ + if (!irq_data) { + dev_err(&pdev->dev, "unable to get irq data\n"); + kfree(priv); + return -ENXIO; + } + /* + * irqd_is_level_type() isn't used since isn't valid unitil + * irq is configured. + */ + if (irqd_get_trigger_type(irq_data) & IRQ_TYPE_LEVEL_MASK) { + dev_info(&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