All of lore.kernel.org
 help / color / mirror / Atom feed
From: Shameerali Kolothum Thodi <shameerali.kolothum.thodi@huawei.com>
To: Marc Zyngier <maz@kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>,
	Bjorn Helgaas <bhelgaas@google.com>,
	"stable@vger.kernel.org" <stable@vger.kernel.org>
Subject: RE: [PATCH] genirq/msi: Activate Multi-MSI early when MSI_FLAG_ACTIVATE_EARLY is set
Date: Mon, 25 Jan 2021 14:39:51 +0000	[thread overview]
Message-ID: <19ddad1517f0495d92c2248d04cf0d5c@huawei.com> (raw)
In-Reply-To: <20210123122759.1781359-1-maz@kernel.org>



> -----Original Message-----
> From: Marc Zyngier [mailto:maz@kernel.org]
> Sent: 23 January 2021 12:28
> To: linux-kernel@vger.kernel.org
> Cc: Thomas Gleixner <tglx@linutronix.de>; Bjorn Helgaas
> <bhelgaas@google.com>; Shameerali Kolothum Thodi
> <shameerali.kolothum.thodi@huawei.com>; stable@vger.kernel.org
> Subject: [PATCH] genirq/msi: Activate Multi-MSI early when
> MSI_FLAG_ACTIVATE_EARLY is set
> 
> When MSI_FLAG_ACTIVATE_EARLY is set (which is the case for PCI),
> we perform the activation of the interrupt (which in the case of
> PCI results in the endpoint being programmed) as soon as the
> interrupt is allocated.
> 
> But it appears that this is only done for the first vector,
> introducing an inconsistent behaviour for PCI Multi-MSI.
> 
> Fix it by iterating over the number of vectors allocated to
> each MSI descriptor. This is easily achieved by introducing
> a new "for_each_msi_vector" iterator, together with a tiny
> bit of refactoring.
> 
> Fixes: f3b0946d629c ("genirq/msi: Make sure PCI MSIs are activated early")
> Reported-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> Cc: stable@vger.kernel.org
> ---
>  include/linux/msi.h |  6 ++++++
>  kernel/irq/msi.c    | 44 ++++++++++++++++++++------------------------
>  2 files changed, 26 insertions(+), 24 deletions(-)
> 
> diff --git a/include/linux/msi.h b/include/linux/msi.h
> index 360a0a7e7341..aef35fd1cf11 100644
> --- a/include/linux/msi.h
> +++ b/include/linux/msi.h
> @@ -178,6 +178,12 @@ struct msi_desc {
>  	list_for_each_entry((desc), dev_to_msi_list((dev)), list)
>  #define for_each_msi_entry_safe(desc, tmp, dev)	\
>  	list_for_each_entry_safe((desc), (tmp), dev_to_msi_list((dev)), list)
> +#define for_each_msi_vector(desc, __irq, dev)				\
> +	for_each_msi_entry((desc), (dev))				\
> +		if ((desc)->irq)					\
> +			for (__irq = (desc)->irq;			\
> +			     __irq < ((desc)->irq + (desc)->nvec_used);	\
> +			     __irq++)
> 
>  #ifdef CONFIG_IRQ_MSI_IOMMU
>  static inline const void *msi_desc_get_iommu_cookie(struct msi_desc *desc)
> diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c
> index 2c0c4d6d0f83..d924676c8781 100644
> --- a/kernel/irq/msi.c
> +++ b/kernel/irq/msi.c
> @@ -436,22 +436,22 @@ int __msi_domain_alloc_irqs(struct irq_domain
> *domain, struct device *dev,
> 
>  	can_reserve = msi_check_reservation_mode(domain, info, dev);
> 
> -	for_each_msi_entry(desc, dev) {
> -		virq = desc->irq;
> -		if (desc->nvec_used == 1)
> -			dev_dbg(dev, "irq %d for MSI\n", virq);
> -		else
> +	/*
> +	 * This flag is set by the PCI layer as we need to activate
> +	 * the MSI entries before the PCI layer enables MSI in the
> +	 * card. Otherwise the card latches a random msi message.
> +	 */
> +	if (!(info->flags & MSI_FLAG_ACTIVATE_EARLY))
> +		goto skip_activate;

This will change the dbg print behavior. From the commit f3b0946d629c,
it looks like the below dev_dbg() code was there for !MSI_FLAG_ACTIVATE_EARLY
case as well. Not sure how much this matters though.

Thanks,
Shameer

> +
> +	for_each_msi_vector(desc, i, dev) {
> +		if (desc->irq == i) {
> +			virq = desc->irq;
>  			dev_dbg(dev, "irq [%d-%d] for MSI\n",
>  				virq, virq + desc->nvec_used - 1);
> -		/*
> -		 * This flag is set by the PCI layer as we need to activate
> -		 * the MSI entries before the PCI layer enables MSI in the
> -		 * card. Otherwise the card latches a random msi message.
> -		 */
> -		if (!(info->flags & MSI_FLAG_ACTIVATE_EARLY))
> -			continue;
> +		}
> 
> -		irq_data = irq_domain_get_irq_data(domain, desc->irq);
> +		irq_data = irq_domain_get_irq_data(domain, i);
>  		if (!can_reserve) {
>  			irqd_clr_can_reserve(irq_data);
>  			if (domain->flags & IRQ_DOMAIN_MSI_NOMASK_QUIRK)
> @@ -462,28 +462,24 @@ int __msi_domain_alloc_irqs(struct irq_domain
> *domain, struct device *dev,
>  			goto cleanup;
>  	}
> 
> +skip_activate:
>  	/*
>  	 * If these interrupts use reservation mode, clear the activated bit
>  	 * so request_irq() will assign the final vector.
>  	 */
>  	if (can_reserve) {
> -		for_each_msi_entry(desc, dev) {
> -			irq_data = irq_domain_get_irq_data(domain, desc->irq);
> +		for_each_msi_vector(desc, i, dev) {
> +			irq_data = irq_domain_get_irq_data(domain, i);
>  			irqd_clr_activated(irq_data);
>  		}
>  	}
>  	return 0;
> 
>  cleanup:
> -	for_each_msi_entry(desc, dev) {
> -		struct irq_data *irqd;
> -
> -		if (desc->irq == virq)
> -			break;
> -
> -		irqd = irq_domain_get_irq_data(domain, desc->irq);
> -		if (irqd_is_activated(irqd))
> -			irq_domain_deactivate_irq(irqd);
> +	for_each_msi_vector(desc, i, dev) {
> +		irq_data = irq_domain_get_irq_data(domain, i);
> +		if (irqd_is_activated(irq_data))
> +			irq_domain_deactivate_irq(irq_data);
>  	}
>  	msi_domain_free_irqs(domain, dev);
>  	return ret;
> --
> 2.29.2


  reply	other threads:[~2021-01-25 16:37 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-23 12:27 [PATCH] genirq/msi: Activate Multi-MSI early when MSI_FLAG_ACTIVATE_EARLY is set Marc Zyngier
2021-01-25 14:39 ` Shameerali Kolothum Thodi [this message]
2021-01-25 14:48   ` Marc Zyngier
2021-01-26  9:28     ` Shameerali Kolothum Thodi
2021-01-30  0:25 ` [tip: irq/urgent] " tip-bot2 for Marc Zyngier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=19ddad1517f0495d92c2248d04cf0d5c@huawei.com \
    --to=shameerali.kolothum.thodi@huawei.com \
    --cc=bhelgaas@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maz@kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.