All of lore.kernel.org
 help / color / mirror / Atom feed
From: Reinette Chatre <reinette.chatre@intel.com>
To: Thomas Gleixner <tglx@linutronix.de>,
	LKML <linux-kernel@vger.kernel.org>
Cc: <x86@kernel.org>, Joerg Roedel <joro@8bytes.org>,
	Will Deacon <will@kernel.org>, <linux-pci@vger.kernel.org>,
	Bjorn Helgaas <bhelgaas@google.com>,
	Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>,
	"Marc Zyngier" <maz@kernel.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Jason Gunthorpe <jgg@mellanox.com>,
	Dave Jiang <dave.jiang@intel.com>,
	"Alex Williamson" <alex.williamson@redhat.com>,
	Kevin Tian <kevin.tian@intel.com>,
	Dan Williams <dan.j.williams@intel.com>,
	Logan Gunthorpe <logang@deltatee.com>,
	Ashok Raj <ashok.raj@intel.com>, Jon Mason <jdmason@kudzu.us>,
	Allen Hubbe <allenbh@gmail.com>,
	"Ahmed S. Darwish" <darwi@linutronix.de>
Subject: Re: [patch 21/33] genirq/msi: Provide msi_domain_alloc_irq_at()
Date: Thu, 17 Nov 2022 15:33:49 -0800	[thread overview]
Message-ID: <0cbf645b-b23a-6c85-4389-bb039a677a52@intel.com> (raw)
In-Reply-To: <20221111135206.463650635@linutronix.de>

Hi Thomas,

I am trying all three parts of this work out with some experimental
code within the IDXD driver that attempts to use IMS on the host.

In the test, pci_ims_alloc_irq() always encounters -EBUSY and it
seems that there is an attempt to insert the struct msi_desc into
the xarray twice, the second attempt encountering the -EBUSY.

While trying to understand what is going on I found myself looking
at this code area and I'll annotate this patch with what I learned.

On 11/11/2022 5:58 AM, Thomas Gleixner wrote:

...

> --- a/kernel/irq/msi.c
> +++ b/kernel/irq/msi.c
> @@ -39,6 +39,7 @@ static inline int msi_sysfs_create_group
>  /* Invalid XA index which is outside of any searchable range */
>  #define MSI_XA_MAX_INDEX	(ULONG_MAX - 1)
>  #define MSI_XA_DOMAIN_SIZE	(MSI_MAX_INDEX + 1)
> +#define MSI_ANY_INDEX		UINT_MAX
>  
>  static inline void msi_setup_default_irqdomain(struct device *dev, struct msi_device_data *md)
>  {
> @@ -126,18 +127,34 @@ static int msi_insert_desc(struct device

When calling pci_ims_alloc_irq(), msi_insert_desc() ends up being
called twice, first with index = MSI_ANY_INDEX, second with index = 0.
(domid = 1 both times)

>  	}
>  
>  	hwsize = msi_domain_get_hwsize(dev, domid);
> -	if (index >= hwsize) {
> -		ret = -ERANGE;
> -		goto fail;
> -	}
>  
> -	desc->msi_index = index;
> -	index += baseidx;
> -	ret = xa_insert(&md->__store, index, desc, GFP_KERNEL);
> -	if (ret)
> -		goto fail;
> -	return 0;
> +	if (index == MSI_ANY_INDEX) {
> +		struct xa_limit limit;
> +		unsigned int index;
> +
> +		limit.min = baseidx;
> +		limit.max = baseidx + hwsize - 1;
>  
> +		/* Let the xarray allocate a free index within the limits */
> +		ret = xa_alloc(&md->__store, &index, desc, limit, GFP_KERNEL);
> +		if (ret)
> +			goto fail;
> +

This path (index == MSI_ANY_INDEX) is followed when msi_insert_desc()
is called the first time and the xa_alloc() succeeds at index 65536.

> +		desc->msi_index = index;

This is problematic with desc->msi_index being a u16, assigning
65536 to it becomes 0.

> +		return 0;
> +	} else {
> +		if (index >= hwsize) {
> +			ret = -ERANGE;
> +			goto fail;
> +		}
> +
> +		desc->msi_index = index;
> +		index += baseidx;
> +		ret = xa_insert(&md->__store, index, desc, GFP_KERNEL);
> +		if (ret)
> +			goto fail;

This "else" path is followed when msi_insert_desc() is called the second
time with "index = 0". The xa_insert() above fails at index 65536
(baseidx = 65536) with -EBUSY, trickling up as the return code to
pci_ims_alloc_irq().

> +		return 0;
> +	}
>  fail:
>  	msi_free_desc(desc);
>  	return ret;
> @@ -335,7 +352,7 @@ int msi_setup_device_data(struct device
>  
>  	msi_setup_default_irqdomain(dev, md);
>  
> -	xa_init(&md->__store);
> +	xa_init_flags(&md->__store, XA_FLAGS_ALLOC);
>  	mutex_init(&md->mutex);
>  	md->__iter_idx = MSI_XA_MAX_INDEX;
>  	dev->msi.data = md;
> @@ -1423,6 +1440,72 @@ int msi_domain_alloc_irqs_all_locked(str
>  	return msi_domain_alloc_locked(dev, &ctrl);
>  }
>  
> +/**
> + * msi_domain_alloc_irq_at - Allocate an interrupt from a MSI interrupt domain at
> + *			     a given index - or at the next free index
> + *
> + * @dev:	Pointer to device struct of the device for which the interrupts
> + *		are allocated
> + * @domid:	Id of the interrupt domain to operate on
> + * @index:	Index for allocation. If @index == %MSI_ANY_INDEX the allocation
> + *		uses the next free index.
> + * @affdesc:	Optional pointer to an interrupt affinity descriptor structure
> + * @cookie:	Optional pointer to a descriptor specific cookie to be stored
> + *		in msi_desc::data. Must be NULL for MSI-X allocations
> + *
> + * This requires a MSI interrupt domain which lets the core code manage the
> + * MSI descriptors.
> + *
> + * Return: struct msi_map
> + *
> + *	On success msi_map::index contains the allocated index number and
> + *	msi_map::virq the corresponding Linux interrupt number
> + *
> + *	On failure msi_map::index contains the error code and msi_map::virq
> + *	is %0.
> + */
> +struct msi_map msi_domain_alloc_irq_at(struct device *dev, unsigned int domid, unsigned int index,
> +				       const struct irq_affinity_desc *affdesc,
> +				       union msi_dev_cookie *cookie)
> +{
> +	struct irq_domain *domain;
> +	struct msi_map map = { };
> +	struct msi_desc *desc;
> +	int ret;
> +
> +	msi_lock_descs(dev);
> +	domain = msi_get_device_domain(dev, domid);
> +	if (!domain) {
> +		map.index = -ENODEV;
> +		goto unlock;
> +	}
> +
> +	desc = msi_alloc_desc(dev, 1, affdesc);
> +	if (!desc) {
> +		map.index = -ENOMEM;
> +		goto unlock;
> +	}
> +
> +	if (cookie)
> +		desc->data.cookie = *cookie;
> +
> +	ret = msi_insert_desc(dev, desc, domid, index);
> +	if (ret) {
> +		map.index = ret;
> +		goto unlock;
> +	}

Above is the first call to msi_insert_desc(/* index = MSI_ANY_INDEX */)

> +
> +	map.index = desc->msi_index;

msi_insert_desc() did attempt to set desc->msi_index to 65536 but map.index ends
up being 0.

> +	ret = msi_domain_alloc_irqs_range_locked(dev, domid, map.index, map.index);

Here is where the second call to msi_insert_desc() originates:

msi_domain_alloc_irqs_range_locked() -> msi_domain_alloc_locked() -> \
__msi_domain_alloc_locked() -> msi_domain_alloc_simple_msi_descs() -> \
msi_domain_add_simple_msi_descs() -> msi_insert_desc()
		

> +	if (ret)
> +		map.index = ret;
> +	else
> +		map.virq = desc->irq;
> +unlock:
> +	msi_unlock_descs(dev);
> +	return map;
> +}
> +
>  static void __msi_domain_free_irqs(struct device *dev, struct irq_domain *domain,
>  				   struct msi_ctrl *ctrl)
>  {
> 

Reinette

  parent reply	other threads:[~2022-11-17 23:34 UTC|newest]

Thread overview: 86+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-11 13:58 [patch 00/33] genirq, PCI/MSI: Support for per device MSI and PCI/IMS - Part 3 implementation Thomas Gleixner
2022-11-11 13:58 ` [patch 01/33] genirq/msi: Rearrange MSI domain flags Thomas Gleixner
2022-11-16 18:41   ` Jason Gunthorpe
2022-11-11 13:58 ` [patch 02/33] genirq/msi: Provide struct msi_parent_ops Thomas Gleixner
2022-11-16 18:57   ` Jason Gunthorpe
2022-11-17 15:58     ` Thomas Gleixner
2022-11-18 13:52       ` Thomas Gleixner
2022-11-11 13:58 ` [patch 03/33] genirq/msi: Provide data structs for per device domains Thomas Gleixner
2022-11-11 13:58 ` [patch 04/33] genirq/msi: Add size info to struct msi_domain_info Thomas Gleixner
2022-11-11 13:58 ` [patch 05/33] genirq/msi: Split msi_create_irq_domain() Thomas Gleixner
2022-11-11 13:58 ` [patch 06/33] genirq/irqdomain: Add irq_domain::dev for per device MSI domains Thomas Gleixner
2022-11-11 13:58 ` [patch 07/33] genirq/msi: Provide msi_create/free_device_irq_domain() Thomas Gleixner
2022-11-11 13:58 ` [patch 08/33] genirq/msi: Provide msi_match_device_domain() Thomas Gleixner
2022-11-11 13:58 ` [patch 09/33] genirq/msi: Add range checking to msi_insert_desc() Thomas Gleixner
2022-11-11 13:58 ` [patch 10/33] PCI/MSI: Split __pci_write_msi_msg() Thomas Gleixner
2022-11-16 20:10   ` Bjorn Helgaas
2022-11-11 13:58 ` [patch 11/33] genirq/msi: Provide BUS_DEVICE_PCI_MSI[X] Thomas Gleixner
2022-11-11 13:58 ` [patch 12/33] PCI/MSI: Add support for per device MSI[X] domains Thomas Gleixner
2022-11-16 19:13   ` Jason Gunthorpe
2022-11-16 22:38     ` Thomas Gleixner
2022-11-17  0:22       ` Jason Gunthorpe
2022-11-17  8:45         ` Thomas Gleixner
2022-11-16 20:22   ` Bjorn Helgaas
2022-11-11 13:58 ` [patch 13/33] x86/apic/vector: Provide MSI parent domain Thomas Gleixner
2022-11-16 19:18   ` Jason Gunthorpe
2022-11-17 20:06     ` Thomas Gleixner
2022-11-11 13:58 ` [patch 14/33] PCI/MSI: Remove unused pci_dev_has_special_msi_domain() Thomas Gleixner
2022-11-16 20:13   ` Bjorn Helgaas
2022-11-11 13:58 ` [patch 15/33] iommu/vt-d: Switch to MSI parent domains Thomas Gleixner
2022-11-11 13:58 ` [patch 16/33] iommu/amd: Switch to MSI base domains Thomas Gleixner
2022-11-11 13:58 ` [patch 17/33] x86/apic/msi: Remove arch_create_remap_msi_irq_domain() Thomas Gleixner
2022-11-11 13:58 ` [patch 18/33] genirq/msi: Provide struct msi_map Thomas Gleixner
2022-11-11 13:58 ` [patch 19/33] genirq/msi: Provide msi_desc::msi_data Thomas Gleixner
2022-11-16 19:28   ` Jason Gunthorpe
2022-11-17  8:48     ` Thomas Gleixner
2022-11-17 13:33       ` Jason Gunthorpe
2022-11-18 22:08     ` Thomas Gleixner
2022-11-21 17:20       ` Jason Gunthorpe
2022-11-21 19:40         ` Thomas Gleixner
2022-11-22  1:52           ` Jason Gunthorpe
2022-11-22 20:49             ` Thomas Gleixner
2022-11-23 16:58               ` Jason Gunthorpe
2022-11-23 18:38                 ` Thomas Gleixner
2022-12-01 12:24                   ` Thomas Gleixner
2022-12-02  0:35                     ` Jason Gunthorpe
2022-12-02  2:14                       ` Thomas Gleixner
2022-11-11 13:58 ` [patch 20/33] genirq/msi: Provide msi_domain_ops::prepare_desc() Thomas Gleixner
2022-11-11 13:58 ` [patch 21/33] genirq/msi: Provide msi_domain_alloc_irq_at() Thomas Gleixner
2022-11-16 19:36   ` Jason Gunthorpe
2022-11-17  9:40     ` Thomas Gleixner
2022-11-17 23:33   ` Reinette Chatre [this message]
2022-11-18  0:58     ` Thomas Gleixner
2022-11-18  9:15       ` Thomas Gleixner
2022-11-18 11:05         ` Thomas Gleixner
2022-11-18 18:18           ` Reinette Chatre
2022-11-18 22:31             ` Thomas Gleixner
2022-11-18 22:59               ` Reinette Chatre
2022-11-19  0:19                 ` Reinette Chatre
2022-11-11 13:58 ` [patch 22/33] genirq/msi: Provide MSI_FLAG_MSIX_ALLOC_DYN Thomas Gleixner
2022-11-16 19:36   ` Jason Gunthorpe
2022-11-11 13:58 ` [patch 23/33] PCI/MSI: Split MSIX descriptor setup Thomas Gleixner
2022-11-16 20:13   ` Bjorn Helgaas
2022-11-11 13:58 ` [patch 24/33] PCI/MSI: Provide prepare_desc() MSI domain op Thomas Gleixner
2022-11-16 19:40   ` Jason Gunthorpe
2022-11-16 20:26   ` Bjorn Helgaas
2022-11-16 22:42     ` Thomas Gleixner
2022-11-11 13:58 ` [patch 25/33] PCI/MSI: Provide post-enable dynamic allocation interfaces for MSI-X Thomas Gleixner
2022-11-16 20:19   ` Bjorn Helgaas
2022-11-16 22:43     ` Thomas Gleixner
2022-11-11 13:58 ` [patch 26/33] x86/apic/msi: Enable MSI_FLAG_PCI_MSIX_ALLOC_DYN Thomas Gleixner
2022-11-11 13:58 ` [patch 27/33] genirq/msi: Provide constants for PCI/IMS support Thomas Gleixner
2022-11-16 19:54   ` Jason Gunthorpe
2022-11-17  9:46     ` Thomas Gleixner
2022-11-11 13:58 ` [patch 28/33] PCI/MSI: Provide IMS (Interrupt Message Store) support Thomas Gleixner
2022-11-16 20:17   ` Bjorn Helgaas
2022-11-11 13:58 ` [patch 29/33] PCI/MSI: Provide pci_ims_alloc/free_irq() Thomas Gleixner
2022-11-16 20:14   ` Bjorn Helgaas
2022-11-11 13:58 ` [patch 30/33] x86/apic/msi: Enable PCI/IMS Thomas Gleixner
2022-11-11 13:59 ` [patch 31/33] iommu/vt-d: " Thomas Gleixner
2022-11-11 13:59 ` [patch 32/33] iommu/amd: " Thomas Gleixner
2022-11-11 13:59 ` [patch 33/33] irqchip: Add IDXD Interrupt Message Store driver Thomas Gleixner
2022-12-02 17:55   ` Reinette Chatre
2022-12-02 19:51     ` Thomas Gleixner
2022-12-02 21:16       ` Reinette Chatre
2022-12-05 15:20       ` Thomas Gleixner
2022-12-05 17:19         ` Reinette Chatre

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=0cbf645b-b23a-6c85-4389-bb039a677a52@intel.com \
    --to=reinette.chatre@intel.com \
    --cc=alex.williamson@redhat.com \
    --cc=allenbh@gmail.com \
    --cc=ashok.raj@intel.com \
    --cc=bhelgaas@google.com \
    --cc=dan.j.williams@intel.com \
    --cc=darwi@linutronix.de \
    --cc=dave.jiang@intel.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jdmason@kudzu.us \
    --cc=jgg@mellanox.com \
    --cc=joro@8bytes.org \
    --cc=kevin.tian@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=logang@deltatee.com \
    --cc=lorenzo.pieralisi@arm.com \
    --cc=maz@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=will@kernel.org \
    --cc=x86@kernel.org \
    /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.