Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp9188160ybl; Fri, 17 Jan 2020 07:44:32 -0800 (PST) X-Google-Smtp-Source: APXvYqxD/6pONOE4vLTtc1gfc9ZMRcE31Klvix7zc3+ljIzI2nqm8b3sTRpR1C2oAbZWieFNgkcz X-Received: by 2002:aca:4a87:: with SMTP id x129mr3719560oia.165.1579275872066; Fri, 17 Jan 2020 07:44:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1579275872; cv=none; d=google.com; s=arc-20160816; b=xtwlr8e4Q4E25N8nWqEKCjBXTdYyZm3XcWzrRFe03sIOE6DIU3HxM54hg1UkBw81qy uFPUx48cn3W+nfyk7kxM1VH6X92c6jvJUQkCJp4AZWh/2b7pNsYBUuIrBlvX9BzV1nVb YhgG6pNe2mH8pXUJcnkAIh/FNzzgvQcKWECLEXX4VgsWAj4tNNvIcUQ3nJXNYnNE3iVn dY5PIQ4PAJGHTmRhpKcIcM/x8F9ljGkx+sZCznZz83OBvPkY6X+jAf+G2ffuxZZzO168 y7KXt/id3v6IjhBO5jPrjYEr4zhSETQwjViune7leCktGWKI4Hln6N1TeLDct22QQDtr EWYw== 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 :in-reply-to:references:mime-version:dkim-signature; bh=3f+W4Xvm6P1QHWnul/IjVaVbxVFaJSRxnQJCYSx9gEI=; b=Yp0cIp/JFTXTbkqlCicoUZurJRVP1A+XBkUS2dPjWp/tAS3GiZoRzjjc9w7paQHQV5 OPw+o/XCGNlA0hcfVQH5HCNGvzBV0YWdg2mlIo7ozeHoHVGFIBa01d2kQ/yMI3VURMhx dI9ii7Hhr8Bp1ChaRmi3UZaiJgBcXXpvUOKltdEwT+x4YuPaPXrZluEWyJfbK4ZsXeZi FANBvqK/ZtcGFdgi8EhYFz5WTdIgbOdzRDo/l3+P/DkUOy2qpFa/ghS8nOe9cY5VDzdD D1SwOsFKNsrR9IEjmvqzUoWiv3341VXAYnt9n9216kHoQfJoDkNHrGXc+3U38nU84HSf oi4w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=LOIu42vh; 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; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c26si16533999otf.288.2020.01.17.07.44.19; Fri, 17 Jan 2020 07:44:32 -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=@gmail.com header.s=20161025 header.b=LOIu42vh; 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; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729022AbgAQPnV (ORCPT + 99 others); Fri, 17 Jan 2020 10:43:21 -0500 Received: from mail-oi1-f195.google.com ([209.85.167.195]:38911 "EHLO mail-oi1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728780AbgAQPnV (ORCPT ); Fri, 17 Jan 2020 10:43:21 -0500 Received: by mail-oi1-f195.google.com with SMTP id l9so22531826oii.5; Fri, 17 Jan 2020 07:43:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=3f+W4Xvm6P1QHWnul/IjVaVbxVFaJSRxnQJCYSx9gEI=; b=LOIu42vhUzF9Mu+lfoPqpOM9rxI1BC0+cdUy0nL1Gb7u3qDzLDNkVue67qKqOoK+PQ Zn0Z3eCYKz+sKmY1O6Mn+WxgRGFX72kZoLjIe+w86hCt3HGdyJq31rZsIXKh48QL3EdQ rU+KJKKMm1WS8V4qptEUaxHH1wFPLxl1H2HGSac240BD+K5g8YYI9TubdoT/efcMF6vt kf1pL7QgoR7QjzeHho5AWwkXQumqELeFZjbyqV0pGMF5IGIMHm4pEJhR+evgK94fj+4q k+FUfh61EvtqNxZiiT3x3akhV3X+lmzmWeU2tYIavKm5Ze/oHBk/AhtjmFCyAeTOwvB9 5NFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=3f+W4Xvm6P1QHWnul/IjVaVbxVFaJSRxnQJCYSx9gEI=; b=YLMnjYvvtd+vTQXshfiz5pYqMRuAP46rmx4N5+rhU0Y4dEIZ0ybJOrBsXloUqpa3r1 If6ozni9c9q3A3tXj+K/TraxCXcc2//TbGPNNnL8Lyuo5UdY7hsvXjSzOq0EzawzQMyn NpCFCYswS+4xmwHC9wYCB4fncCGt4EW31hdIM4IfSeCDWU/6rkdhHVX0Qxr/hTzPdKMR 0sbZ6iFwK0NVb3aSTZH5NnLL4xOfBJYRe236nmOKDcx0cUvJ513pAuCA6OTuoCnmGeWp 1oFkV3hZhjp4rEn5s4uFhPmnx8c3LrnLvINyyCGX5q1yoO5Ue09FgVOeZt1FBkJF+JlD XYMQ== X-Gm-Message-State: APjAAAV8KEdiYNbNBONlrj+GxCR3Yc/CXUm3/qH8n5VO6B8ckxeDGVOd 2Cyh6NhDIgo7J3R2cv6O81H8D+1oPvx1s0dv6ZI= X-Received: by 2002:a05:6808:24e:: with SMTP id m14mr3934910oie.168.1579275800172; Fri, 17 Jan 2020 07:43:20 -0800 (PST) MIME-Version: 1.0 References: <87wo9ub5f6.fsf@nanos.tec.linutronix.de> <87imldbqe3.fsf@nanos.tec.linutronix.de> <87v9pcw55q.fsf@nanos.tec.linutronix.de> <87pnfjwxtx.fsf@nanos.tec.linutronix.de> <87zhem172r.fsf@nanos.tec.linutronix.de> In-Reply-To: <87zhem172r.fsf@nanos.tec.linutronix.de> From: Ramon Fried Date: Fri, 17 Jan 2020 17:43:08 +0200 Message-ID: Subject: Re: MSI irqchip configured as IRQCHIP_ONESHOT_SAFE causes spurious IRQs To: Thomas Gleixner Cc: hkallweit1@gmail.com, Bjorn Helgaas , maz@kernel.org, lorenzo.pieralisi@arm.com, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org 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 On Fri, Jan 17, 2020 at 4:38 PM Thomas Gleixner wrote: > > Ramon, > > Ramon Fried writes: > >> So from a software perspective you want to do something like this: > >> > >> gic_irq_handler() > >> { > >> mask_ack(gic_irqX); > >> > >> pending = read(msi_status); > >> for_each_bit(bit, pending) { > >> ack(msi_status, bit); // This clears the latch in the MSI block > >> handle_irq(irqof(bit)); > >> } > >> unmask(gic_irqX); > >> } > >> > >> And that works perfectly correct without masking the MSI interrupt at > >> the PCI level for a threaded handler simply because the PCI device > >> will not send another interrupt until the previous one has been > >> handled by the driver unless the PCI device is broken. > > > > I'm missing something here, isn't this implementation blocks IRQ's only during > > the HW handler and not during the threaded handler ? (Assuming that I selected > > handle_level_irq() as the default handler) > > handle_level_irq() is the proper handler for the actual GIC interrupt > which does the demultiplexing. The MSI interrupts want to have > handle_edge_irq(). > > > Actually my implementation current implementation is very similar to what > > you just described: > > > > static void eq_msi_isr(struct irq_desc *desc) > > { > > struct irq_chip *chip = irq_desc_get_chip(desc); > > struct eq_msi *msi; > > u16 status; > > unsigned long bitmap; > > u32 bit; > > u32 virq; > > > > chained_irq_enter(chip, desc); > > msi = irq_desc_get_handler_data(desc); > > > > while ((status = readw(msi->gcsr_regs_base + LINK_GCSR5_OFFSET) > > & MSI_IRQ_REQ) != 0) { > > pr_debug("MSI: %x\n", status >> 12); > > > > bitmap = status >> 12; > > for_each_set_bit(bit, &bitmap, msi->num_of_vectors) { > > virq = irq_find_mapping(msi->inner_domain, bit); > > if (virq) { > > generic_handle_irq(virq); > > } else { > > pr_err("unexpected MSI\n"); > > handle_bad_irq(desc); > > Now if you look at the example I gave you there is a subtle difference: > > >> pending = read(msi_status); > >> for_each_bit(bit, pending) { > >> ack(msi_status, bit); // This clears the latch in the MSI block > >> handle_irq(irqof(bit)); > >> } > > And this clearing is important when one of the MSI interrupts is > actually having a threaded handler. > > MSI interrupt fires > -> sets bit in msi_status > -> MSI block raises GIC interrupt because msi_status != 0 > > CPU handles GIC interrupt > pending = read(msi_status); > for_each_bit(bit, pending) > handle_irq() > primary_handler() > -> WAKEUP_THREAD > > RETI, but msi_status is still != 0 > > > Additionally the domain allocation is defined like: > > static int eq_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, > > unsigned int nr_irqs, void *args) > > { > > struct eq_msi *msi = domain->host_data; > > unsigned long bit; > > u32 mask; > > > > /* We only allow 32 MSI per device */ > > WARN_ON(nr_irqs > 32); > > if (nr_irqs > 32) > > return -ENOSPC; > > > > bit = find_first_zero_bit(msi->used, msi->num_of_vectors); > > if (bit >= msi->num_of_vectors) > > return -ENOSPC; > > > > set_bit(bit, msi->used); > > > > mask = readw(msi->gcsr_regs_base + LINK_GCSR6_OFFSET); > > mask |= BIT(bit) << 12; > > writew(mask, msi->gcsr_regs_base + LINK_GCSR6_OFFSET); > > > > irq_domain_set_info(domain, virq, bit, &eq_msi_bottom_irq_chip, > > domain->host_data, handle_level_irq, > > This is wrong. MSI is edge type, not level and you are really mixing up > the concepts here. > > The fact that the MSI block raises a level interrupt on the output side > has absolutely nothing to do with the type of the MSI interrupt itself. > > MSI is edge type by definition and this does not change just because > there is a translation unit between the MSI interrupt and the CPU > controller. > > The actual MSI interrupts do not even know about the existance of that > MSI block at all. They do not care, as all they need to know is a > message and an address. When an interrupt is raised in the device the > MSI chip associated to the device (PCI or something else) writes this > message to the address exactly ONCE. And this exactly ONCE defines the > edge nature of MSI. OK, now I understand my mistake. thanks. > > A proper designed MSI device should not send another message before the > interrupt handler which is associated to the device has handled the > interrupt at the device level. By "MSI device" you mean the MSI controller in the SOC or the endpoint that sends the MSI ? > > So you really have to understand that the GIC interrupt and the MSI > interrupts are two different entities. They just have a 'connection' > because the message/address which is handed to the MSI device triggers > that GIC interrupt via the MSI translation unit. But they are still > different and independent entities. > > See? > > Thanks, > > tglx > > > > > >