linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2
@ 2021-11-27  1:20 Thomas Gleixner
  2021-11-27  1:20 ` [patch 01/37] device: Move MSI related data into a struct Thomas Gleixner
                   ` (39 more replies)
  0 siblings, 40 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

This is the second part of [PCI]MSI refactoring which aims to provide the
ability of expanding MSI-X vectors after enabling MSI-X.

The first part of this work can be found here:

    https://lore.kernel.org/r/20211126222700.862407977@linutronix.de

This second part has the following important changes:

   1) Cleanup of the MSI related data in struct device

      struct device contains at the moment various MSI related parts. Some
      of them (the irq domain pointer) cannot be moved out, but the rest
      can be allocated on first use. This is in preparation of adding more
      per device MSI data later on.

   2) Consolidation of sysfs handling

      As a first step this moves the sysfs pointer from struct msi_desc
      into the new per device MSI data structure where it belongs.

      Later changes will cleanup this code further, but that's not possible
      at this point.

   3) Store per device properties in the per device MSI data to avoid
      looking up MSI descriptors and analysing their data. Cleanup all
      related use cases.

   4) Provide a function to retrieve the Linux interrupt number for a given
      MSI index similar to pci_irq_vector() and cleanup all open coded
      variants.

This second series is based on:

     git://git.kernel.org/pub/scm/linux/kernel/git/tglx/devel.git msi-v1-part-1

and also available from git:

     git://git.kernel.org/pub/scm/linux/kernel/git/tglx/devel.git msi-v1-part-2

For the curious who can't wait for the next part to arrive the full series
is available via:

     git://git.kernel.org/pub/scm/linux/kernel/git/tglx/devel.git msi-v1-part-4

Thanks,

	tglx
---
 arch/powerpc/platforms/cell/axon_msi.c              |    6 
 arch/powerpc/platforms/pseries/msi.c                |   38 +---
 arch/x86/kernel/apic/msi.c                          |    5 
 arch/x86/pci/xen.c                                  |    8 
 drivers/base/core.c                                 |    1 
 drivers/base/platform-msi.c                         |  152 ++++++++---------
 drivers/bus/fsl-mc/dprc-driver.c                    |    8 
 drivers/bus/fsl-mc/fsl-mc-allocator.c               |    9 -
 drivers/bus/fsl-mc/fsl-mc-msi.c                     |   26 +--
 drivers/dma/mv_xor_v2.c                             |   16 -
 drivers/dma/qcom/hidma.c                            |   44 ++---
 drivers/dma/ti/k3-udma-private.c                    |    6 
 drivers/dma/ti/k3-udma.c                            |   14 -
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c         |   23 --
 drivers/irqchip/irq-mbigen.c                        |    4 
 drivers/irqchip/irq-mvebu-icu.c                     |   12 -
 drivers/irqchip/irq-ti-sci-inta.c                   |    2 
 drivers/mailbox/bcm-flexrm-mailbox.c                |    9 -
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c    |    4 
 drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c    |    4 
 drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c |    5 
 drivers/pci/msi/irqdomain.c                         |   20 +-
 drivers/pci/msi/legacy.c                            |    6 
 drivers/pci/msi/msi.c                               |  118 +++++--------
 drivers/pci/xen-pcifront.c                          |    2 
 drivers/perf/arm_smmuv3_pmu.c                       |    5 
 drivers/soc/fsl/dpio/dpio-driver.c                  |    8 
 drivers/soc/ti/k3-ringacc.c                         |    6 
 drivers/soc/ti/ti_sci_inta_msi.c                    |   22 --
 drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c              |    4 
 include/linux/device.h                              |   26 ++-
 include/linux/fsl/mc.h                              |    4 
 include/linux/msi.h                                 |  118 +++++++------
 include/linux/pci.h                                 |    1 
 include/linux/soc/ti/ti_sci_inta_msi.h              |    1 
 kernel/irq/msi.c                                    |  171 +++++++++++++++-----
 36 files changed, 463 insertions(+), 445 deletions(-)

^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 01/37] device: Move MSI related data into a struct
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27 12:11   ` Greg Kroah-Hartman
  2021-11-27  1:20 ` [patch 02/37] device: Add device::msi_data pointer and struct msi_device_data Thomas Gleixner
                   ` (38 subsequent siblings)
  39 siblings, 2 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

The only unconditional part of MSI data in struct device is the irqdomain
pointer. Everything else can be allocated on demand. Create a data
structure and move the irqdomain pointer into it. The other MSI specific
parts are going to be removed from struct device in later steps.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Will Deacon <will@kernel.org>
Cc: Santosh Shilimkar <ssantosh@kernel.org>
Cc: iommu@lists.linux-foundation.org
Cc: dmaengine@vger.kernel.org
---
 drivers/base/platform-msi.c                 |   12 ++++++------
 drivers/dma/ti/k3-udma.c                    |    4 ++--
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |    2 +-
 drivers/irqchip/irq-mvebu-icu.c             |    6 +++---
 drivers/soc/ti/k3-ringacc.c                 |    4 ++--
 drivers/soc/ti/ti_sci_inta_msi.c            |    2 +-
 include/linux/device.h                      |   19 +++++++++++++------
 7 files changed, 28 insertions(+), 21 deletions(-)

--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -210,10 +210,10 @@ platform_msi_alloc_priv_data(struct devi
 	 * accordingly (which would impact the max number of MSI
 	 * capable devices).
 	 */
-	if (!dev->msi_domain || !write_msi_msg || !nvec || nvec > MAX_DEV_MSIS)
+	if (!dev->msi.domain || !write_msi_msg || !nvec || nvec > MAX_DEV_MSIS)
 		return ERR_PTR(-EINVAL);
 
-	if (dev->msi_domain->bus_token != DOMAIN_BUS_PLATFORM_MSI) {
+	if (dev->msi.domain->bus_token != DOMAIN_BUS_PLATFORM_MSI) {
 		dev_err(dev, "Incompatible msi_domain, giving up\n");
 		return ERR_PTR(-EINVAL);
 	}
@@ -269,7 +269,7 @@ int platform_msi_domain_alloc_irqs(struc
 	if (err)
 		goto out_free_priv_data;
 
-	err = msi_domain_alloc_irqs(dev->msi_domain, dev, nvec);
+	err = msi_domain_alloc_irqs(dev->msi.domain, dev, nvec);
 	if (err)
 		goto out_free_desc;
 
@@ -282,7 +282,7 @@ int platform_msi_domain_alloc_irqs(struc
 	return 0;
 
 out_free_irqs:
-	msi_domain_free_irqs(dev->msi_domain, dev);
+	msi_domain_free_irqs(dev->msi.domain, dev);
 out_free_desc:
 	platform_msi_free_descs(dev, 0, nvec);
 out_free_priv_data:
@@ -306,7 +306,7 @@ void platform_msi_domain_free_irqs(struc
 		platform_msi_free_priv_data(desc->platform.msi_priv_data);
 	}
 
-	msi_domain_free_irqs(dev->msi_domain, dev);
+	msi_domain_free_irqs(dev->msi.domain, dev);
 	platform_msi_free_descs(dev, 0, MAX_DEV_MSIS);
 }
 EXPORT_SYMBOL_GPL(platform_msi_domain_free_irqs);
@@ -354,7 +354,7 @@ struct irq_domain *
 		return NULL;
 
 	data->host_data = host_data;
-	domain = irq_domain_create_hierarchy(dev->msi_domain, 0,
+	domain = irq_domain_create_hierarchy(dev->msi.domain, 0,
 					     is_tree ? 0 : nvec,
 					     dev->fwnode, ops, data);
 	if (!domain)
--- a/drivers/dma/ti/k3-udma.c
+++ b/drivers/dma/ti/k3-udma.c
@@ -5279,9 +5279,9 @@ static int udma_probe(struct platform_de
 	if (IS_ERR(ud->ringacc))
 		return PTR_ERR(ud->ringacc);
 
-	dev->msi_domain = of_msi_get_domain(dev, dev->of_node,
+	dev->msi.domain = of_msi_get_domain(dev, dev->of_node,
 					    DOMAIN_BUS_TI_SCI_INTA_MSI);
-	if (!dev->msi_domain) {
+	if (!dev->msi.domain) {
 		dev_err(dev, "Failed to get MSI domain\n");
 		return -EPROBE_DEFER;
 	}
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3170,7 +3170,7 @@ static void arm_smmu_setup_msis(struct a
 	if (!(smmu->features & ARM_SMMU_FEAT_MSI))
 		return;
 
-	if (!dev->msi_domain) {
+	if (!dev->msi.domain) {
 		dev_info(smmu->dev, "msi_domain absent - falling back to wired irqs\n");
 		return;
 	}
--- a/drivers/irqchip/irq-mvebu-icu.c
+++ b/drivers/irqchip/irq-mvebu-icu.c
@@ -314,12 +314,12 @@ static int mvebu_icu_subset_probe(struct
 		msi_data->subset_data = of_device_get_match_data(dev);
 	}
 
-	dev->msi_domain = of_msi_get_domain(dev, dev->of_node,
+	dev->msi.domain = of_msi_get_domain(dev, dev->of_node,
 					    DOMAIN_BUS_PLATFORM_MSI);
-	if (!dev->msi_domain)
+	if (!dev->msi.domain)
 		return -EPROBE_DEFER;
 
-	msi_parent_dn = irq_domain_get_of_node(dev->msi_domain);
+	msi_parent_dn = irq_domain_get_of_node(dev->msi.domain);
 	if (!msi_parent_dn)
 		return -ENODEV;
 
--- a/drivers/soc/ti/k3-ringacc.c
+++ b/drivers/soc/ti/k3-ringacc.c
@@ -1356,9 +1356,9 @@ static int k3_ringacc_init(struct platfo
 	struct resource *res;
 	int ret, i;
 
-	dev->msi_domain = of_msi_get_domain(dev, dev->of_node,
+	dev->msi.domain = of_msi_get_domain(dev, dev->of_node,
 					    DOMAIN_BUS_TI_SCI_INTA_MSI);
-	if (!dev->msi_domain) {
+	if (!dev->msi.domain) {
 		dev_err(dev, "Failed to get MSI domain\n");
 		return -EPROBE_DEFER;
 	}
--- a/drivers/soc/ti/ti_sci_inta_msi.c
+++ b/drivers/soc/ti/ti_sci_inta_msi.c
@@ -140,7 +140,7 @@ EXPORT_SYMBOL_GPL(ti_sci_inta_msi_domain
 
 void ti_sci_inta_msi_domain_free_irqs(struct device *dev)
 {
-	msi_domain_free_irqs(dev->msi_domain, dev);
+	msi_domain_free_irqs(dev->msi.domain, dev);
 	ti_sci_inta_msi_free_descs(dev);
 }
 EXPORT_SYMBOL_GPL(ti_sci_inta_msi_domain_free_irqs);
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -372,6 +372,16 @@ struct dev_links_info {
 };
 
 /**
+ * struct dev_msi_info - Device data related to MSI
+ * @domain:	The MSI interrupt domain associated to the device
+ */
+struct dev_msi_info {
+#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
+	struct irq_domain	*domain;
+#endif
+};
+
+/**
  * struct device - The basic device structure
  * @parent:	The device's "parent" device, the device to which it is attached.
  * 		In most cases, a parent device is some sort of bus or host
@@ -409,7 +419,6 @@ struct dev_links_info {
  *		See Documentation/driver-api/pin-control.rst for details.
  * @msi_lock:	Lock to protect MSI mask cache and mask register
  * @msi_list:	Hosts MSI descriptors
- * @msi_domain: The generic MSI domain this device is using.
  * @numa_node:	NUMA node this device is close to.
  * @dma_ops:    DMA mapping operations for this device.
  * @dma_mask:	Dma mask (if dma'ble device).
@@ -501,12 +510,10 @@ struct device {
 	struct em_perf_domain	*em_pd;
 #endif
 
-#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
-	struct irq_domain	*msi_domain;
-#endif
 #ifdef CONFIG_PINCTRL
 	struct dev_pin_info	*pins;
 #endif
+	struct dev_msi_info	msi;
 #ifdef CONFIG_GENERIC_MSI_IRQ
 	raw_spinlock_t		msi_lock;
 	struct list_head	msi_list;
@@ -668,7 +675,7 @@ static inline void set_dev_node(struct d
 static inline struct irq_domain *dev_get_msi_domain(const struct device *dev)
 {
 #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
-	return dev->msi_domain;
+	return dev->msi.domain;
 #else
 	return NULL;
 #endif
@@ -677,7 +684,7 @@ static inline struct irq_domain *dev_get
 static inline void dev_set_msi_domain(struct device *dev, struct irq_domain *d)
 {
 #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
-	dev->msi_domain = d;
+	dev->msi.domain = d;
 #endif
 }
 


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 02/37] device: Add device::msi_data pointer and struct msi_device_data
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
  2021-11-27  1:20 ` [patch 01/37] device: Move MSI related data into a struct Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
                     ` (2 more replies)
  2021-11-27  1:20 ` [patch 03/37] PCI/MSI: Allocate MSI device data on first use Thomas Gleixner
                   ` (37 subsequent siblings)
  39 siblings, 3 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Create struct msi_device_data and add a pointer of that type to struct
dev_msi_info, which is part of struct device. Provide an allocator function
which can be invoked from the MSI interrupt allocation code pathes.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/device.h |    5 +++++
 include/linux/msi.h    |   12 +++++++++++-
 kernel/irq/msi.c       |   33 +++++++++++++++++++++++++++++++++
 3 files changed, 49 insertions(+), 1 deletion(-)

--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -45,6 +45,7 @@ struct iommu_ops;
 struct iommu_group;
 struct dev_pin_info;
 struct dev_iommu;
+struct msi_device_data;
 
 /**
  * struct subsys_interface - interfaces to device functions
@@ -374,11 +375,15 @@ struct dev_links_info {
 /**
  * struct dev_msi_info - Device data related to MSI
  * @domain:	The MSI interrupt domain associated to the device
+ * @data:	Pointer to MSI device data
  */
 struct dev_msi_info {
 #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
 	struct irq_domain	*domain;
 #endif
+#ifdef CONFIG_GENERIC_MSI_IRQ
+	struct msi_device_data	*data;
+#endif
 };
 
 /**
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -2,6 +2,7 @@
 #ifndef LINUX_MSI_H
 #define LINUX_MSI_H
 
+#include <linux/spinlock.h>
 #include <linux/list.h>
 #include <asm/msi.h>
 
@@ -170,6 +171,16 @@ struct msi_desc {
 	};
 };
 
+/**
+ * msi_device_data - MSI per device data
+ * @lock:		Spinlock to protect register access
+ */
+struct msi_device_data {
+	raw_spinlock_t		lock;
+};
+
+int msi_setup_device_data(struct device *dev);
+
 /* Helpers to hide struct msi_desc implementation details */
 #define msi_desc_to_dev(desc)		((desc)->dev)
 #define dev_to_msi_list(dev)		(&(dev)->msi_list)
@@ -185,7 +196,6 @@ struct msi_desc {
 			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)
 {
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -73,6 +73,39 @@ void get_cached_msi_msg(unsigned int irq
 }
 EXPORT_SYMBOL_GPL(get_cached_msi_msg);
 
+static void msi_device_data_release(struct device *dev, void *res)
+{
+	WARN_ON_ONCE(!list_empty(&dev->msi_list));
+	dev->msi.data = NULL;
+}
+
+/**
+ * msi_setup_device_data - Setup MSI device data
+ * @dev:	Device for which MSI device data should be set up
+ *
+ * Return: 0 on success, appropriate error code otherwise
+ *
+ * This can be called more than once for @dev. If the MSI device data is
+ * already allocated the call succeeds. The allocated memory is
+ * automatically released when the device is destroyed.
+ */
+int msi_setup_device_data(struct device *dev)
+{
+	struct msi_device_data *md;
+
+	if (dev->msi.data)
+		return 0;
+
+	md = devres_alloc(msi_device_data_release, sizeof(*md), GFP_KERNEL);
+	if (!md)
+		return -ENOMEM;
+
+	raw_spin_lock_init(&md->lock);
+	dev->msi.data = md;
+	devres_add(dev, md);
+	return 0;
+}
+
 #ifdef CONFIG_SYSFS
 static ssize_t msi_mode_show(struct device *dev, struct device_attribute *attr,
 			     char *buf)


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 03/37] PCI/MSI: Allocate MSI device data on first use
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
  2021-11-27  1:20 ` [patch 01/37] device: Move MSI related data into a struct Thomas Gleixner
  2021-11-27  1:20 ` [patch 02/37] device: Add device::msi_data pointer and struct msi_device_data Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 05/37] platform-msi: " Thomas Gleixner
                   ` (36 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Allocate MSI device data on first use, i.e. when a PCI driver invokes one
of the PCI/MSI enablement functions.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/pci/msi/msi.c |   20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -889,10 +889,12 @@ static int __pci_enable_msi_range(struct
 /* deprecated, don't use */
 int pci_enable_msi(struct pci_dev *dev)
 {
-	int rc = __pci_enable_msi_range(dev, 1, 1, NULL);
-	if (rc < 0)
-		return rc;
-	return 0;
+	int rc = msi_setup_device_data(&dev->dev);
+
+	if (!rc)
+		rc = __pci_enable_msi_range(dev, 1, 1, NULL);
+
+	return rc < 0 ? rc : 0;
 }
 EXPORT_SYMBOL(pci_enable_msi);
 
@@ -947,7 +949,11 @@ static int __pci_enable_msix_range(struc
 int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries,
 		int minvec, int maxvec)
 {
-	return __pci_enable_msix_range(dev, entries, minvec, maxvec, NULL, 0);
+	int ret = msi_setup_device_data(&dev->dev);
+
+	if (!ret)
+		ret = __pci_enable_msix_range(dev, entries, minvec, maxvec, NULL, 0);
+	return ret;
 }
 EXPORT_SYMBOL(pci_enable_msix_range);
 
@@ -974,8 +980,12 @@ int pci_alloc_irq_vectors_affinity(struc
 				   struct irq_affinity *affd)
 {
 	struct irq_affinity msi_default_affd = {0};
+	int ret = msi_setup_device_data(&dev->dev);
 	int nvecs = -ENOSPC;
 
+	if (ret)
+		return ret;
+
 	if (flags & PCI_IRQ_AFFINITY) {
 		if (!affd)
 			affd = &msi_default_affd;


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 04/37] PCI/MSI: Use lock from msi_device_data
  2021-11-27  1:21 ` [patch 04/37] PCI/MSI: Use lock from msi_device_data Thomas Gleixner
@ 2021-11-27  1:20   ` Thomas Gleixner
  2021-11-27 12:13   ` Greg Kroah-Hartman
  1 sibling, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Remove the register lock from struct device and use the one in
struct msi_device_data.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/base/core.c    |    1 -
 drivers/pci/msi/msi.c  |    2 +-
 include/linux/device.h |    2 --
 3 files changed, 1 insertion(+), 4 deletions(-)

--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -2875,7 +2875,6 @@ void device_initialize(struct device *de
 	device_pm_init(dev);
 	set_dev_node(dev, NUMA_NO_NODE);
 #ifdef CONFIG_GENERIC_MSI_IRQ
-	raw_spin_lock_init(&dev->msi_lock);
 	INIT_LIST_HEAD(&dev->msi_list);
 #endif
 	INIT_LIST_HEAD(&dev->links.consumers);
--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -18,7 +18,7 @@ int pci_msi_ignore_mask;
 
 static noinline void pci_msi_update_mask(struct msi_desc *desc, u32 clear, u32 set)
 {
-	raw_spinlock_t *lock = &desc->dev->msi_lock;
+	raw_spinlock_t *lock = &desc->dev->msi.data->lock;
 	unsigned long flags;
 
 	if (!desc->pci.msi_attrib.can_mask)
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -422,7 +422,6 @@ struct dev_msi_info {
  * @em_pd:	device's energy model performance domain
  * @pins:	For device pin management.
  *		See Documentation/driver-api/pin-control.rst for details.
- * @msi_lock:	Lock to protect MSI mask cache and mask register
  * @msi_list:	Hosts MSI descriptors
  * @numa_node:	NUMA node this device is close to.
  * @dma_ops:    DMA mapping operations for this device.
@@ -520,7 +519,6 @@ struct device {
 #endif
 	struct dev_msi_info	msi;
 #ifdef CONFIG_GENERIC_MSI_IRQ
-	raw_spinlock_t		msi_lock;
 	struct list_head	msi_list;
 #endif
 #ifdef CONFIG_DMA_OPS


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 05/37] platform-msi: Allocate MSI device data on first use
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (2 preceding siblings ...)
  2021-11-27  1:20 ` [patch 03/37] PCI/MSI: Allocate MSI device data on first use Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 06/37] bus: fsl-mc-msi: " Thomas Gleixner
                   ` (35 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Allocate the MSI device data on first invocation of the allocation function
for platform MSI private data.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/base/platform-msi.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -204,6 +204,8 @@ platform_msi_alloc_priv_data(struct devi
 			     irq_write_msi_msg_t write_msi_msg)
 {
 	struct platform_msi_priv_data *datap;
+	int err;
+
 	/*
 	 * Limit the number of interrupts to 2048 per device. Should we
 	 * need to bump this up, DEV_ID_SHIFT should be adjusted
@@ -218,6 +220,10 @@ platform_msi_alloc_priv_data(struct devi
 		return ERR_PTR(-EINVAL);
 	}
 
+	err = msi_setup_device_data(dev);
+	if (err)
+		return ERR_PTR(err);
+
 	/* Already had a helping of MSI? Greed... */
 	if (!list_empty(dev_to_msi_list(dev)))
 		return ERR_PTR(-EBUSY);
@@ -229,7 +235,7 @@ platform_msi_alloc_priv_data(struct devi
 	datap->devid = ida_simple_get(&platform_msi_devid_ida,
 				      0, 1 << DEV_ID_SHIFT, GFP_KERNEL);
 	if (datap->devid < 0) {
-		int err = datap->devid;
+		err = datap->devid;
 		kfree(datap);
 		return ERR_PTR(err);
 	}


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 06/37] bus: fsl-mc-msi: Allocate MSI device data on first use
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (3 preceding siblings ...)
  2021-11-27  1:20 ` [patch 05/37] platform-msi: " Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 07/37] soc: ti: ti_sci_inta_msi: " Thomas Gleixner
                   ` (34 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Stuart Yoder, Laurentiu Tudor,
	Santosh Shilimkar, iommu, dmaengine, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Allocate the MSI device data on first invocation of the allocation function.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Stuart Yoder <stuyoder@gmail.com>
Cc: Laurentiu Tudor <laurentiu.tudor@nxp.com>
---
 drivers/bus/fsl-mc/fsl-mc-msi.c |   14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

--- a/drivers/bus/fsl-mc/fsl-mc-msi.c
+++ b/drivers/bus/fsl-mc/fsl-mc-msi.c
@@ -253,6 +253,14 @@ int fsl_mc_msi_domain_alloc_irqs(struct
 	struct irq_domain *msi_domain;
 	int error;
 
+	msi_domain = dev_get_msi_domain(dev);
+	if (!msi_domain)
+		return -EINVAL;
+
+	error = msi_setup_device_data(dev);
+	if (error)
+		return error;
+
 	if (!list_empty(dev_to_msi_list(dev)))
 		return -EINVAL;
 
@@ -260,12 +268,6 @@ int fsl_mc_msi_domain_alloc_irqs(struct
 	if (error < 0)
 		return error;
 
-	msi_domain = dev_get_msi_domain(dev);
-	if (!msi_domain) {
-		error = -EINVAL;
-		goto cleanup_msi_descs;
-	}
-
 	/*
 	 * NOTE: Calling this function will trigger the invocation of the
 	 * its_fsl_mc_msi_prepare() callback


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 07/37] soc: ti: ti_sci_inta_msi: Allocate MSI device data on first use
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (4 preceding siblings ...)
  2021-11-27  1:20 ` [patch 06/37] bus: fsl-mc-msi: " Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 08/37] genirq/msi: Provide msi_device_populate/destroy_sysfs() Thomas Gleixner
                   ` (33 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Nishanth Menon, Tero Kristo,
	Santosh Shilimkar, linux-arm-kernel, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, x86, Vinod Koul, Mark Rutland,
	Will Deacon, Sinan Kaya

Allocate the MSI device data on first invocation of the allocation function.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Nishanth Menon <nm@ti.com>
Cc: Tero Kristo <kristo@kernel.org>
Cc: Santosh Shilimkar <ssantosh@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
---
 drivers/soc/ti/ti_sci_inta_msi.c |    4 ++++
 1 file changed, 4 insertions(+)

--- a/drivers/soc/ti/ti_sci_inta_msi.c
+++ b/drivers/soc/ti/ti_sci_inta_msi.c
@@ -120,6 +120,10 @@ int ti_sci_inta_msi_domain_alloc_irqs(st
 	if (pdev->id < 0)
 		return -ENODEV;
 
+	ret = msi_setup_device_data(dev);
+	if (ret)
+		return ret;
+
 	nvec = ti_sci_inta_msi_alloc_descs(dev, res);
 	if (nvec <= 0)
 		return nvec;


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 08/37] genirq/msi: Provide msi_device_populate/destroy_sysfs()
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (5 preceding siblings ...)
  2021-11-27  1:20 ` [patch 07/37] soc: ti: ti_sci_inta_msi: " Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-30 11:53   ` Jonathan Cameron
  2021-11-27  1:20 ` [patch 09/37] PCI/MSI: Let the irq code handle sysfs groups Thomas Gleixner
                   ` (32 subsequent siblings)
  39 siblings, 2 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Add new allocation functions which can be activated by domain info
flags. They store the groups pointer in struct msi_device_data.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/msi.h |   12 +++++++++++-
 kernel/irq/msi.c    |   42 ++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 51 insertions(+), 3 deletions(-)

--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -174,9 +174,11 @@ struct msi_desc {
 /**
  * msi_device_data - MSI per device data
  * @lock:		Spinlock to protect register access
+ * @attrs:		Pointer to the sysfs attribute group
  */
 struct msi_device_data {
-	raw_spinlock_t		lock;
+	raw_spinlock_t			lock;
+	const struct attribute_group    **attrs;
 };
 
 int msi_setup_device_data(struct device *dev);
@@ -242,10 +244,16 @@ void pci_msi_mask_irq(struct irq_data *d
 void pci_msi_unmask_irq(struct irq_data *data);
 
 #ifdef CONFIG_SYSFS
+int msi_device_populate_sysfs(struct device *dev);
+void msi_device_destroy_sysfs(struct device *dev);
+
 const struct attribute_group **msi_populate_sysfs(struct device *dev);
 void msi_destroy_sysfs(struct device *dev,
 		       const struct attribute_group **msi_irq_groups);
 #else
+static inline int msi_device_populate_sysfs(struct device *dev) { return 0; }
+static inline void msi_device_destroy_sysfs(struct device *dev) { }
+
 static inline const struct attribute_group **msi_populate_sysfs(struct device *dev)
 {
 	return NULL;
@@ -393,6 +401,8 @@ enum {
 	MSI_FLAG_MUST_REACTIVATE	= (1 << 5),
 	/* Is level-triggered capable, using two messages */
 	MSI_FLAG_LEVEL_CAPABLE		= (1 << 6),
+	/* Populate sysfs on alloc() and destroy it on free() */
+	MSI_FLAG_DEV_SYSFS		= (1 << 7),
 };
 
 int msi_domain_set_affinity(struct irq_data *data, const struct cpumask *mask,
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -214,6 +214,20 @@ const struct attribute_group **msi_popul
 }
 
 /**
+ * msi_device_populate_sysfs - Populate msi_irqs sysfs entries for a device
+ * @dev:	The device(PCI, platform etc) which will get sysfs entries
+ */
+int msi_device_populate_sysfs(struct device *dev)
+{
+	const struct attribute_group **group = msi_populate_sysfs(dev);
+
+	if (IS_ERR(group))
+		return PTR_ERR(group);
+	dev->msi.data->attrs = group;
+	return 0;
+}
+
+/**
  * msi_destroy_sysfs - Destroy msi_irqs sysfs entries for devices
  * @dev:		The device(PCI, platform etc) who will remove sysfs entries
  * @msi_irq_groups:	attribute_group for device msi_irqs entries
@@ -239,6 +253,17 @@ void msi_destroy_sysfs(struct device *de
 		kfree(msi_irq_groups);
 	}
 }
+
+/**
+ * msi_device_destroy_sysfs - Destroy msi_irqs sysfs entries for a device
+ * @dev:		The device(PCI, platform etc) for which to remove
+ *			sysfs entries
+ */
+void msi_device_destroy_sysfs(struct device *dev)
+{
+	msi_destroy_sysfs(dev, dev->msi.data->attrs);
+	dev->msi.data->attrs = NULL;
+}
 #endif
 
 #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
@@ -686,8 +711,19 @@ int msi_domain_alloc_irqs(struct irq_dom
 {
 	struct msi_domain_info *info = domain->host_data;
 	struct msi_domain_ops *ops = info->ops;
+	int ret;
 
-	return ops->domain_alloc_irqs(domain, dev, nvec);
+	ret = ops->domain_alloc_irqs(domain, dev, nvec);
+	if (ret)
+		return ret;
+
+	if (!(info->flags & MSI_FLAG_DEV_SYSFS))
+		return 0;
+
+	ret = msi_device_populate_sysfs(dev);
+	if (ret)
+		msi_domain_free_irqs(domain, dev);
+	return ret;
 }
 
 void __msi_domain_free_irqs(struct irq_domain *domain, struct device *dev)
@@ -726,7 +762,9 @@ void msi_domain_free_irqs(struct irq_dom
 	struct msi_domain_info *info = domain->host_data;
 	struct msi_domain_ops *ops = info->ops;
 
-	return ops->domain_free_irqs(domain, dev);
+	if (info->flags & MSI_FLAG_DEV_SYSFS)
+		msi_device_destroy_sysfs(dev);
+	ops->domain_free_irqs(domain, dev);
 }
 
 /**


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 09/37] PCI/MSI: Let the irq code handle sysfs groups
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (6 preceding siblings ...)
  2021-11-27  1:20 ` [patch 08/37] genirq/msi: Provide msi_device_populate/destroy_sysfs() Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 10/37] platform-msi: Let the core " Thomas Gleixner
                   ` (31 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Set the domain info flag which makes the core code handle sysfs groups and
put an explicit invocation into the legacy code.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/pci/msi/irqdomain.c |    2 +-
 drivers/pci/msi/legacy.c    |    6 +++++-
 drivers/pci/msi/msi.c       |   23 -----------------------
 include/linux/pci.h         |    1 -
 4 files changed, 6 insertions(+), 26 deletions(-)

--- a/drivers/pci/msi/irqdomain.c
+++ b/drivers/pci/msi/irqdomain.c
@@ -159,7 +159,7 @@ struct irq_domain *pci_msi_create_irq_do
 	if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS)
 		pci_msi_domain_update_chip_ops(info);
 
-	info->flags |= MSI_FLAG_ACTIVATE_EARLY;
+	info->flags |= MSI_FLAG_ACTIVATE_EARLY | MSI_FLAG_DEV_SYSFS;
 	if (IS_ENABLED(CONFIG_GENERIC_IRQ_RESERVATION_MODE))
 		info->flags |= MSI_FLAG_MUST_REACTIVATE;
 
--- a/drivers/pci/msi/legacy.c
+++ b/drivers/pci/msi/legacy.c
@@ -71,10 +71,14 @@ int pci_msi_legacy_setup_msi_irqs(struct
 {
 	int ret = arch_setup_msi_irqs(dev, nvec, type);
 
-	return pci_msi_setup_check_result(dev, type, ret);
+	ret = pci_msi_setup_check_result(dev, type, ret);
+	if (!ret)
+		ret = msi_device_populate_sysfs(&dev->dev);
+	return ret;
 }
 
 void pci_msi_legacy_teardown_msi_irqs(struct pci_dev *dev)
 {
+	msi_device_destroy_sysfs(&dev->dev);
 	arch_teardown_msi_irqs(dev);
 }
--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -233,11 +233,6 @@ static void free_msi_irqs(struct pci_dev
 			for (i = 0; i < entry->nvec_used; i++)
 				BUG_ON(irq_has_action(entry->irq + i));
 
-	if (dev->msi_irq_groups) {
-		msi_destroy_sysfs(&dev->dev, dev->msi_irq_groups);
-		dev->msi_irq_groups = NULL;
-	}
-
 	pci_msi_teardown_msi_irqs(dev);
 
 	list_for_each_entry_safe(entry, tmp, msi_list, list) {
@@ -415,7 +410,6 @@ static int msi_verify_entries(struct pci
 static int msi_capability_init(struct pci_dev *dev, int nvec,
 			       struct irq_affinity *affd)
 {
-	const struct attribute_group **groups;
 	struct msi_desc *entry;
 	int ret;
 
@@ -439,14 +433,6 @@ static int msi_capability_init(struct pc
 	if (ret)
 		goto err;
 
-	groups = msi_populate_sysfs(&dev->dev);
-	if (IS_ERR(groups)) {
-		ret = PTR_ERR(groups);
-		goto err;
-	}
-
-	dev->msi_irq_groups = groups;
-
 	/* Set MSI enabled bits	*/
 	pci_intx_for_msi(dev, 0);
 	pci_msi_set_enable(dev, 1);
@@ -574,7 +560,6 @@ static void msix_mask_all(void __iomem *
 static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries,
 				int nvec, struct irq_affinity *affd)
 {
-	const struct attribute_group **groups;
 	void __iomem *base;
 	int ret, tsize;
 	u16 control;
@@ -616,14 +601,6 @@ static int msix_capability_init(struct p
 
 	msix_update_entries(dev, entries);
 
-	groups = msi_populate_sysfs(&dev->dev);
-	if (IS_ERR(groups)) {
-		ret = PTR_ERR(groups);
-		goto out_free;
-	}
-
-	dev->msi_irq_groups = groups;
-
 	/* Set MSI-X enabled bits and unmask the function */
 	pci_intx_for_msi(dev, 0);
 	dev->msix_enabled = 1;
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -474,7 +474,6 @@ struct pci_dev {
 #endif
 #ifdef CONFIG_PCI_MSI
 	void __iomem	*msix_base;
-	const struct attribute_group **msi_irq_groups;
 #endif
 	struct pci_vpd	vpd;
 #ifdef CONFIG_PCIE_DPC


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 10/37] platform-msi: Let the core code handle sysfs groups
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (7 preceding siblings ...)
  2021-11-27  1:20 ` [patch 09/37] PCI/MSI: Let the irq code handle sysfs groups Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 11/37] genirq/msi: Remove the original sysfs interfaces Thomas Gleixner
                   ` (30 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Set the domain info flag and remove the local sysfs code.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/base/platform-msi.c |   11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -23,7 +23,6 @@
 struct platform_msi_priv_data {
 	struct device			*dev;
 	void				*host_data;
-	const struct attribute_group    **msi_irq_groups;
 	msi_alloc_info_t		arg;
 	irq_write_msi_msg_t		write_msg;
 	int				devid;
@@ -191,6 +190,7 @@ struct irq_domain *platform_msi_create_i
 		platform_msi_update_dom_ops(info);
 	if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS)
 		platform_msi_update_chip_ops(info);
+	info->flags |= MSI_FLAG_DEV_SYSFS;
 
 	domain = msi_create_irq_domain(fwnode, info, parent);
 	if (domain)
@@ -279,16 +279,8 @@ int platform_msi_domain_alloc_irqs(struc
 	if (err)
 		goto out_free_desc;
 
-	priv_data->msi_irq_groups = msi_populate_sysfs(dev);
-	if (IS_ERR(priv_data->msi_irq_groups)) {
-		err = PTR_ERR(priv_data->msi_irq_groups);
-		goto out_free_irqs;
-	}
-
 	return 0;
 
-out_free_irqs:
-	msi_domain_free_irqs(dev->msi.domain, dev);
 out_free_desc:
 	platform_msi_free_descs(dev, 0, nvec);
 out_free_priv_data:
@@ -308,7 +300,6 @@ void platform_msi_domain_free_irqs(struc
 		struct msi_desc *desc;
 
 		desc = first_msi_entry(dev);
-		msi_destroy_sysfs(dev, desc->platform.msi_priv_data->msi_irq_groups);
 		platform_msi_free_priv_data(desc->platform.msi_priv_data);
 	}
 


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 11/37] genirq/msi: Remove the original sysfs interfaces
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (8 preceding siblings ...)
  2021-11-27  1:20 ` [patch 10/37] platform-msi: Let the core " Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 12/37] platform-msi: Rename functions and clarify comments Thomas Gleixner
                   ` (29 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

No more users. Refactor the core code accordingly.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/msi.h |   12 -----------
 kernel/irq/msi.c    |   53 +++++++++++++++++++---------------------------------
 2 files changed, 20 insertions(+), 45 deletions(-)

--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -246,21 +246,9 @@ void pci_msi_unmask_irq(struct irq_data
 #ifdef CONFIG_SYSFS
 int msi_device_populate_sysfs(struct device *dev);
 void msi_device_destroy_sysfs(struct device *dev);
-
-const struct attribute_group **msi_populate_sysfs(struct device *dev);
-void msi_destroy_sysfs(struct device *dev,
-		       const struct attribute_group **msi_irq_groups);
 #else
 static inline int msi_device_populate_sysfs(struct device *dev) { return 0; }
 static inline void msi_device_destroy_sysfs(struct device *dev) { }
-
-static inline const struct attribute_group **msi_populate_sysfs(struct device *dev)
-{
-	return NULL;
-}
-static inline void msi_destroy_sysfs(struct device *dev, const struct attribute_group **msi_irq_groups)
-{
-}
 #endif
 
 /*
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -132,12 +132,8 @@ static ssize_t msi_mode_show(struct devi
 /**
  * msi_populate_sysfs - Populate msi_irqs sysfs entries for devices
  * @dev:	The device(PCI, platform etc) who will get sysfs entries
- *
- * Return attribute_group ** so that specific bus MSI can save it to
- * somewhere during initilizing msi irqs. If devices has no MSI irq,
- * return NULL; if it fails to populate sysfs, return ERR_PTR
  */
-const struct attribute_group **msi_populate_sysfs(struct device *dev)
+static const struct attribute_group **msi_populate_sysfs(struct device *dev)
 {
 	const struct attribute_group **msi_irq_groups;
 	struct attribute **msi_attrs, *msi_attr;
@@ -228,41 +224,32 @@ int msi_device_populate_sysfs(struct dev
 }
 
 /**
- * msi_destroy_sysfs - Destroy msi_irqs sysfs entries for devices
- * @dev:		The device(PCI, platform etc) who will remove sysfs entries
- * @msi_irq_groups:	attribute_group for device msi_irqs entries
- */
-void msi_destroy_sysfs(struct device *dev, const struct attribute_group **msi_irq_groups)
-{
-	struct device_attribute *dev_attr;
-	struct attribute **msi_attrs;
-	int count = 0;
-
-	if (msi_irq_groups) {
-		sysfs_remove_groups(&dev->kobj, msi_irq_groups);
-		msi_attrs = msi_irq_groups[0]->attrs;
-		while (msi_attrs[count]) {
-			dev_attr = container_of(msi_attrs[count],
-					struct device_attribute, attr);
-			kfree(dev_attr->attr.name);
-			kfree(dev_attr);
-			++count;
-		}
-		kfree(msi_attrs);
-		kfree(msi_irq_groups[0]);
-		kfree(msi_irq_groups);
-	}
-}
-
-/**
  * msi_device_destroy_sysfs - Destroy msi_irqs sysfs entries for a device
  * @dev:		The device(PCI, platform etc) for which to remove
  *			sysfs entries
  */
 void msi_device_destroy_sysfs(struct device *dev)
 {
-	msi_destroy_sysfs(dev, dev->msi.data->attrs);
+	const struct attribute_group **msi_irq_groups = dev->msi.data->attrs;
+	struct device_attribute *dev_attr;
+	struct attribute **msi_attrs;
+	int count = 0;
+
 	dev->msi.data->attrs = NULL;
+	if (!msi_irq_groups)
+		return;
+
+	sysfs_remove_groups(&dev->kobj, msi_irq_groups);
+	msi_attrs = msi_irq_groups[0]->attrs;
+	while (msi_attrs[count]) {
+		dev_attr = container_of(msi_attrs[count], struct device_attribute, attr);
+		kfree(dev_attr->attr.name);
+		kfree(dev_attr);
+		++count;
+	}
+	kfree(msi_attrs);
+	kfree(msi_irq_groups[0]);
+	kfree(msi_irq_groups);
 }
 #endif
 


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 12/37] platform-msi: Rename functions and clarify comments
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (9 preceding siblings ...)
  2021-11-27  1:20 ` [patch 11/37] genirq/msi: Remove the original sysfs interfaces Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 13/37] platform-msi: Store platform private data pointer in msi_device_data Thomas Gleixner
                   ` (28 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

It's hard to distinguish what platform_msi_domain_alloc() and
platform_msi_domain_alloc_irqs() are about. Make the distinction more
explicit and add comments which explain the use cases properly.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/base/platform-msi.c     |   36 +++++++++++++++++++++---------------
 drivers/irqchip/irq-mbigen.c    |    4 ++--
 drivers/irqchip/irq-mvebu-icu.c |    6 +++---
 include/linux/msi.h             |    8 ++++----
 4 files changed, 30 insertions(+), 24 deletions(-)

--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -313,17 +313,18 @@ EXPORT_SYMBOL_GPL(platform_msi_domain_fr
  *                              a platform-msi domain
  * @domain:	The platform-msi domain
  *
- * Returns the private data provided when calling
- * platform_msi_create_device_domain.
+ * Return: The private data provided when calling
+ * platform_msi_create_device_domain().
  */
 void *platform_msi_get_host_data(struct irq_domain *domain)
 {
 	struct platform_msi_priv_data *data = domain->host_data;
+
 	return data->host_data;
 }
 
 /**
- * __platform_msi_create_device_domain - Create a platform-msi domain
+ * __platform_msi_create_device_domain - Create a platform-msi device domain
  *
  * @dev:		The device generating the MSIs
  * @nvec:		The number of MSIs that need to be allocated
@@ -332,7 +333,11 @@ void *platform_msi_get_host_data(struct
  * @ops:		The hierarchy domain operations to use
  * @host_data:		Private data associated to this domain
  *
- * Returns an irqdomain for @nvec interrupts
+ * Return: An irqdomain for @nvec interrupts on success, NULL in case of error.
+ *
+ * This is for interrupt domains which stack on a platform-msi domain
+ * created by platform_msi_create_irq_domain(). @dev->msi.domain points to
+ * that platform-msi domain which is the parent for the new domain.
  */
 struct irq_domain *
 __platform_msi_create_device_domain(struct device *dev,
@@ -372,18 +377,19 @@ struct irq_domain *
 }
 
 /**
- * platform_msi_domain_free - Free interrupts associated with a platform-msi
- *                            domain
+ * platform_msi_device_domain_free - Free interrupts associated with a platform-msi
+ *				     device domain
  *
- * @domain:	The platform-msi domain
+ * @domain:	The platform-msi device domain
  * @virq:	The base irq from which to perform the free operation
  * @nvec:	How many interrupts to free from @virq
  */
-void platform_msi_domain_free(struct irq_domain *domain, unsigned int virq,
-			      unsigned int nvec)
+void platform_msi_device_domain_free(struct irq_domain *domain, unsigned int virq,
+				     unsigned int nvec)
 {
 	struct platform_msi_priv_data *data = domain->host_data;
 	struct msi_desc *desc, *tmp;
+
 	for_each_msi_entry_safe(desc, tmp, data->dev) {
 		if (WARN_ON(!desc->irq || desc->nvec_used != 1))
 			return;
@@ -397,10 +403,10 @@ void platform_msi_domain_free(struct irq
 }
 
 /**
- * platform_msi_domain_alloc - Allocate interrupts associated with
- *			       a platform-msi domain
+ * platform_msi_device_domain_alloc - Allocate interrupts associated with
+ *				      a platform-msi device domain
  *
- * @domain:	The platform-msi domain
+ * @domain:	The platform-msi device domain
  * @virq:	The base irq from which to perform the allocate operation
  * @nr_irqs:	How many interrupts to free from @virq
  *
@@ -408,8 +414,8 @@ void platform_msi_domain_free(struct irq
  * with irq_domain_mutex held (which can only be done as part of a
  * top-level interrupt allocation).
  */
-int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
-			      unsigned int nr_irqs)
+int platform_msi_device_domain_alloc(struct irq_domain *domain, unsigned int virq,
+				     unsigned int nr_irqs)
 {
 	struct platform_msi_priv_data *data = domain->host_data;
 	int err;
@@ -421,7 +427,7 @@ int platform_msi_domain_alloc(struct irq
 	err = msi_domain_populate_irqs(domain->parent, data->dev,
 				       virq, nr_irqs, &data->arg);
 	if (err)
-		platform_msi_domain_free(domain, virq, nr_irqs);
+		platform_msi_device_domain_free(domain, virq, nr_irqs);
 
 	return err;
 }
--- a/drivers/irqchip/irq-mbigen.c
+++ b/drivers/irqchip/irq-mbigen.c
@@ -207,7 +207,7 @@ static int mbigen_irq_domain_alloc(struc
 	if (err)
 		return err;
 
-	err = platform_msi_domain_alloc(domain, virq, nr_irqs);
+	err = platform_msi_device_domain_alloc(domain, virq, nr_irqs);
 	if (err)
 		return err;
 
@@ -223,7 +223,7 @@ static int mbigen_irq_domain_alloc(struc
 static void mbigen_irq_domain_free(struct irq_domain *domain, unsigned int virq,
 				   unsigned int nr_irqs)
 {
-	platform_msi_domain_free(domain, virq, nr_irqs);
+	platform_msi_device_domain_free(domain, virq, nr_irqs);
 }
 
 static const struct irq_domain_ops mbigen_domain_ops = {
--- a/drivers/irqchip/irq-mvebu-icu.c
+++ b/drivers/irqchip/irq-mvebu-icu.c
@@ -221,7 +221,7 @@ mvebu_icu_irq_domain_alloc(struct irq_do
 		icu_irqd->icu_group = msi_data->subset_data->icu_group;
 	icu_irqd->icu = icu;
 
-	err = platform_msi_domain_alloc(domain, virq, nr_irqs);
+	err = platform_msi_device_domain_alloc(domain, virq, nr_irqs);
 	if (err) {
 		dev_err(icu->dev, "failed to allocate ICU interrupt in parent domain\n");
 		goto free_irqd;
@@ -245,7 +245,7 @@ mvebu_icu_irq_domain_alloc(struct irq_do
 	return 0;
 
 free_msi:
-	platform_msi_domain_free(domain, virq, nr_irqs);
+	platform_msi_device_domain_free(domain, virq, nr_irqs);
 free_irqd:
 	kfree(icu_irqd);
 	return err;
@@ -260,7 +260,7 @@ mvebu_icu_irq_domain_free(struct irq_dom
 
 	kfree(icu_irqd);
 
-	platform_msi_domain_free(domain, virq, nr_irqs);
+	platform_msi_device_domain_free(domain, virq, nr_irqs);
 }
 
 static const struct irq_domain_ops mvebu_icu_domain_ops = {
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -432,10 +432,10 @@ struct irq_domain *
 #define platform_msi_create_device_tree_domain(dev, nvec, write, ops, data) \
 	__platform_msi_create_device_domain(dev, nvec, true, write, ops, data)
 
-int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
-			      unsigned int nr_irqs);
-void platform_msi_domain_free(struct irq_domain *domain, unsigned int virq,
-			      unsigned int nvec);
+int platform_msi_device_domain_alloc(struct irq_domain *domain, unsigned int virq,
+				     unsigned int nr_irqs);
+void platform_msi_device_domain_free(struct irq_domain *domain, unsigned int virq,
+				     unsigned int nvec);
 void *platform_msi_get_host_data(struct irq_domain *domain);
 #endif /* CONFIG_GENERIC_MSI_IRQ_DOMAIN */
 


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 13/37] platform-msi: Store platform private data pointer in msi_device_data
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (10 preceding siblings ...)
  2021-11-27  1:20 ` [patch 12/37] platform-msi: Rename functions and clarify comments Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 14/37] genirq/msi: Consolidate MSI descriptor data Thomas Gleixner
                   ` (27 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Storing the platform private data in a MSI descriptor is sloppy at
best. The data belongs to the device and not to the descriptor.
Add a pointer to struct msi_device_data and store the pointer there.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/base/platform-msi.c |   79 +++++++++++++++++---------------------------
 include/linux/msi.h         |    5 +-
 2 files changed, 35 insertions(+), 49 deletions(-)

--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -38,9 +38,7 @@ static DEFINE_IDA(platform_msi_devid_ida
  */
 static irq_hw_number_t platform_msi_calc_hwirq(struct msi_desc *desc)
 {
-	u32 devid;
-
-	devid = desc->platform.msi_priv_data->devid;
+	u32 devid = desc->dev->msi.data->platform_data->devid;
 
 	return (devid << (32 - DEV_ID_SHIFT)) | desc->platform.msi_index;
 }
@@ -85,11 +83,8 @@ static void platform_msi_update_dom_ops(
 static void platform_msi_write_msg(struct irq_data *data, struct msi_msg *msg)
 {
 	struct msi_desc *desc = irq_data_get_msi_desc(data);
-	struct platform_msi_priv_data *priv_data;
-
-	priv_data = desc->platform.msi_priv_data;
 
-	priv_data->write_msg(desc, msg);
+	desc->dev->msi.data->platform_data->write_msg(desc, msg);
 }
 
 static void platform_msi_update_chip_ops(struct msi_domain_info *info)
@@ -126,9 +121,7 @@ static void platform_msi_free_descs(stru
 }
 
 static int platform_msi_alloc_descs_with_irq(struct device *dev, int virq,
-					     int nvec,
-					     struct platform_msi_priv_data *data)
-
+					     int nvec)
 {
 	struct msi_desc *desc;
 	int i, base = 0;
@@ -144,7 +137,6 @@ static int platform_msi_alloc_descs_with
 		if (!desc)
 			break;
 
-		desc->platform.msi_priv_data = data;
 		desc->platform.msi_index = base + i;
 		desc->irq = virq ? virq + i : 0;
 
@@ -161,11 +153,9 @@ static int platform_msi_alloc_descs_with
 	return 0;
 }
 
-static int platform_msi_alloc_descs(struct device *dev, int nvec,
-				    struct platform_msi_priv_data *data)
-
+static int platform_msi_alloc_descs(struct device *dev, int nvec)
 {
-	return platform_msi_alloc_descs_with_irq(dev, 0, nvec, data);
+	return platform_msi_alloc_descs_with_irq(dev, 0, nvec);
 }
 
 /**
@@ -199,9 +189,8 @@ struct irq_domain *platform_msi_create_i
 	return domain;
 }
 
-static struct platform_msi_priv_data *
-platform_msi_alloc_priv_data(struct device *dev, unsigned int nvec,
-			     irq_write_msi_msg_t write_msi_msg)
+static int platform_msi_alloc_priv_data(struct device *dev, unsigned int nvec,
+					irq_write_msi_msg_t write_msi_msg)
 {
 	struct platform_msi_priv_data *datap;
 	int err;
@@ -213,41 +202,44 @@ platform_msi_alloc_priv_data(struct devi
 	 * capable devices).
 	 */
 	if (!dev->msi.domain || !write_msi_msg || !nvec || nvec > MAX_DEV_MSIS)
-		return ERR_PTR(-EINVAL);
+		return -EINVAL;
 
 	if (dev->msi.domain->bus_token != DOMAIN_BUS_PLATFORM_MSI) {
 		dev_err(dev, "Incompatible msi_domain, giving up\n");
-		return ERR_PTR(-EINVAL);
+		return -EINVAL;
 	}
 
 	err = msi_setup_device_data(dev);
 	if (err)
-		return ERR_PTR(err);
+		return err;
 
-	/* Already had a helping of MSI? Greed... */
-	if (!list_empty(dev_to_msi_list(dev)))
-		return ERR_PTR(-EBUSY);
+	/* Already initialized? */
+	if (dev->msi.data->platform_data)
+		return -EBUSY;
 
 	datap = kzalloc(sizeof(*datap), GFP_KERNEL);
 	if (!datap)
-		return ERR_PTR(-ENOMEM);
+		return -ENOMEM;
 
 	datap->devid = ida_simple_get(&platform_msi_devid_ida,
 				      0, 1 << DEV_ID_SHIFT, GFP_KERNEL);
 	if (datap->devid < 0) {
 		err = datap->devid;
 		kfree(datap);
-		return ERR_PTR(err);
+		return err;
 	}
 
 	datap->write_msg = write_msi_msg;
 	datap->dev = dev;
-
-	return datap;
+	dev->msi.data->platform_data = datap;
+	return 0;
 }
 
-static void platform_msi_free_priv_data(struct platform_msi_priv_data *data)
+static void platform_msi_free_priv_data(struct device *dev)
 {
+	struct platform_msi_priv_data *data = dev->msi.data->platform_data;
+
+	dev->msi.data->platform_data = NULL;
 	ida_simple_remove(&platform_msi_devid_ida, data->devid);
 	kfree(data);
 }
@@ -264,14 +256,13 @@ static void platform_msi_free_priv_data(
 int platform_msi_domain_alloc_irqs(struct device *dev, unsigned int nvec,
 				   irq_write_msi_msg_t write_msi_msg)
 {
-	struct platform_msi_priv_data *priv_data;
 	int err;
 
-	priv_data = platform_msi_alloc_priv_data(dev, nvec, write_msi_msg);
-	if (IS_ERR(priv_data))
-		return PTR_ERR(priv_data);
+	err = platform_msi_alloc_priv_data(dev, nvec, write_msi_msg);
+	if (err)
+		return err;
 
-	err = platform_msi_alloc_descs(dev, nvec, priv_data);
+	err = platform_msi_alloc_descs(dev, nvec);
 	if (err)
 		goto out_free_priv_data;
 
@@ -284,8 +275,7 @@ int platform_msi_domain_alloc_irqs(struc
 out_free_desc:
 	platform_msi_free_descs(dev, 0, nvec);
 out_free_priv_data:
-	platform_msi_free_priv_data(priv_data);
-
+	platform_msi_free_priv_data(dev);
 	return err;
 }
 EXPORT_SYMBOL_GPL(platform_msi_domain_alloc_irqs);
@@ -296,15 +286,9 @@ EXPORT_SYMBOL_GPL(platform_msi_domain_al
  */
 void platform_msi_domain_free_irqs(struct device *dev)
 {
-	if (!list_empty(dev_to_msi_list(dev))) {
-		struct msi_desc *desc;
-
-		desc = first_msi_entry(dev);
-		platform_msi_free_priv_data(desc->platform.msi_priv_data);
-	}
-
 	msi_domain_free_irqs(dev->msi.domain, dev);
 	platform_msi_free_descs(dev, 0, MAX_DEV_MSIS);
+	platform_msi_free_priv_data(dev);
 }
 EXPORT_SYMBOL_GPL(platform_msi_domain_free_irqs);
 
@@ -351,10 +335,11 @@ struct irq_domain *
 	struct irq_domain *domain;
 	int err;
 
-	data = platform_msi_alloc_priv_data(dev, nvec, write_msi_msg);
-	if (IS_ERR(data))
+	err = platform_msi_alloc_priv_data(dev, nvec, write_msi_msg);
+	if (err)
 		return NULL;
 
+	data = dev->msi.data->platform_data;
 	data->host_data = host_data;
 	domain = irq_domain_create_hierarchy(dev->msi.domain, 0,
 					     is_tree ? 0 : nvec,
@@ -372,7 +357,7 @@ struct irq_domain *
 free_domain:
 	irq_domain_remove(domain);
 free_priv:
-	platform_msi_free_priv_data(data);
+	platform_msi_free_priv_data(dev);
 	return NULL;
 }
 
@@ -420,7 +405,7 @@ int platform_msi_device_domain_alloc(str
 	struct platform_msi_priv_data *data = domain->host_data;
 	int err;
 
-	err = platform_msi_alloc_descs_with_irq(data->dev, virq, nr_irqs, data);
+	err = platform_msi_alloc_descs_with_irq(data->dev, virq, nr_irqs);
 	if (err)
 		return err;
 
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -56,6 +56,7 @@ struct irq_data;
 struct msi_desc;
 struct pci_dev;
 struct platform_msi_priv_data;
+
 void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
 #ifdef CONFIG_GENERIC_MSI_IRQ
 void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg);
@@ -106,11 +107,9 @@ struct pci_msi_desc {
 
 /**
  * platform_msi_desc - Platform device specific msi descriptor data
- * @msi_priv_data:	Pointer to platform private data
  * @msi_index:		The index of the MSI descriptor for multi MSI
  */
 struct platform_msi_desc {
-	struct platform_msi_priv_data	*msi_priv_data;
 	u16				msi_index;
 };
 
@@ -175,10 +174,12 @@ struct msi_desc {
  * msi_device_data - MSI per device data
  * @lock:		Spinlock to protect register access
  * @attrs:		Pointer to the sysfs attribute group
+ * @platform_data:	Platform-MSI specific data
  */
 struct msi_device_data {
 	raw_spinlock_t			lock;
 	const struct attribute_group    **attrs;
+	struct platform_msi_priv_data	*platform_data;
 };
 
 int msi_setup_device_data(struct device *dev);


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 14/37] genirq/msi: Consolidate MSI descriptor data
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (11 preceding siblings ...)
  2021-11-27  1:20 ` [patch 13/37] platform-msi: Store platform private data pointer in msi_device_data Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 15/37] platform-msi: Use msi_desc::msi_index Thomas Gleixner
                   ` (26 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

All non PCI/MSI usage variants have data structures in struct msi_desc with
only one member: xxx_index. PCI/MSI has a entry_nr member.

Add a common msi_index member to struct msi_desc so all implementations can
share it which allows further consolidation.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/msi.h |    2 ++
 1 file changed, 2 insertions(+)

--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -142,6 +142,7 @@ struct ti_sci_inta_msi_desc {
  *			address or data changes
  * @write_msi_msg_data:	Data parameter for the callback.
  *
+ * @msi_index:	Index of the msi descriptor
  * @pci:	[PCI]	    PCI speficic msi descriptor data
  * @platform:	[platform]  Platform device specific msi descriptor data
  * @fsl_mc:	[fsl-mc]    FSL MC device specific msi descriptor data
@@ -162,6 +163,7 @@ struct msi_desc {
 	void (*write_msi_msg)(struct msi_desc *entry, void *data);
 	void *write_msi_msg_data;
 
+	u16				msi_index;
 	union {
 		struct pci_msi_desc		pci;
 		struct platform_msi_desc	platform;


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 15/37] platform-msi: Use msi_desc::msi_index
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (12 preceding siblings ...)
  2021-11-27  1:20 ` [patch 14/37] genirq/msi: Consolidate MSI descriptor data Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 16/37] bus: fsl-mc-msi: " Thomas Gleixner
                   ` (25 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, linux-arm-kernel, iommu, dmaengine,
	Santosh Shilimkar, Stuart Yoder, Laurentiu Tudor, Nishanth Menon,
	Tero Kristo, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Use the common msi_index member and get rid of the pointless wrapper struct.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-arm-kernel@lists.infradead.org
Cc: iommu@lists.linux-foundation.org
Cc: dmaengine@vger.kernel.org
---
 drivers/base/platform-msi.c                 |   10 +++++-----
 drivers/dma/qcom/hidma.c                    |    4 ++--
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |    4 ++--
 drivers/mailbox/bcm-flexrm-mailbox.c        |    4 ++--
 include/linux/msi.h                         |   10 ----------
 5 files changed, 11 insertions(+), 21 deletions(-)

--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -40,7 +40,7 @@ static irq_hw_number_t platform_msi_calc
 {
 	u32 devid = desc->dev->msi.data->platform_data->devid;
 
-	return (devid << (32 - DEV_ID_SHIFT)) | desc->platform.msi_index;
+	return (devid << (32 - DEV_ID_SHIFT)) | desc->msi_index;
 }
 
 static void platform_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
@@ -112,8 +112,8 @@ static void platform_msi_free_descs(stru
 	struct msi_desc *desc, *tmp;
 
 	list_for_each_entry_safe(desc, tmp, dev_to_msi_list(dev), list) {
-		if (desc->platform.msi_index >= base &&
-		    desc->platform.msi_index < (base + nvec)) {
+		if (desc->msi_index >= base &&
+		    desc->msi_index < (base + nvec)) {
 			list_del(&desc->list);
 			free_msi_entry(desc);
 		}
@@ -129,7 +129,7 @@ static int platform_msi_alloc_descs_with
 	if (!list_empty(dev_to_msi_list(dev))) {
 		desc = list_last_entry(dev_to_msi_list(dev),
 				       struct msi_desc, list);
-		base = desc->platform.msi_index + 1;
+		base = desc->msi_index + 1;
 	}
 
 	for (i = 0; i < nvec; i++) {
@@ -137,7 +137,7 @@ static int platform_msi_alloc_descs_with
 		if (!desc)
 			break;
 
-		desc->platform.msi_index = base + i;
+		desc->msi_index = base + i;
 		desc->irq = virq ? virq + i : 0;
 
 		list_add_tail(&desc->list, dev_to_msi_list(dev));
--- a/drivers/dma/qcom/hidma.c
+++ b/drivers/dma/qcom/hidma.c
@@ -666,7 +666,7 @@ static void hidma_write_msi_msg(struct m
 	struct device *dev = msi_desc_to_dev(desc);
 	struct hidma_dev *dmadev = dev_get_drvdata(dev);
 
-	if (!desc->platform.msi_index) {
+	if (!desc->msi_index) {
 		writel(msg->address_lo, dmadev->dev_evca + 0x118);
 		writel(msg->address_hi, dmadev->dev_evca + 0x11C);
 		writel(msg->data, dmadev->dev_evca + 0x120);
@@ -702,7 +702,7 @@ static int hidma_request_msi(struct hidm
 		return rc;
 
 	for_each_msi_entry(desc, &pdev->dev) {
-		if (!desc->platform.msi_index)
+		if (!desc->msi_index)
 			dmadev->msi_virqbase = desc->irq;
 
 		rc = devm_request_irq(&pdev->dev, desc->irq,
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3142,7 +3142,7 @@ static void arm_smmu_write_msi_msg(struc
 	phys_addr_t doorbell;
 	struct device *dev = msi_desc_to_dev(desc);
 	struct arm_smmu_device *smmu = dev_get_drvdata(dev);
-	phys_addr_t *cfg = arm_smmu_msi_cfg[desc->platform.msi_index];
+	phys_addr_t *cfg = arm_smmu_msi_cfg[desc->msi_index];
 
 	doorbell = (((u64)msg->address_hi) << 32) | msg->address_lo;
 	doorbell &= MSI_CFG0_ADDR_MASK;
@@ -3183,7 +3183,7 @@ static void arm_smmu_setup_msis(struct a
 	}
 
 	for_each_msi_entry(desc, dev) {
-		switch (desc->platform.msi_index) {
+		switch (desc->msi_index) {
 		case EVTQ_MSI_INDEX:
 			smmu->evtq.q.irq = desc->irq;
 			break;
--- a/drivers/mailbox/bcm-flexrm-mailbox.c
+++ b/drivers/mailbox/bcm-flexrm-mailbox.c
@@ -1484,7 +1484,7 @@ static void flexrm_mbox_msi_write(struct
 {
 	struct device *dev = msi_desc_to_dev(desc);
 	struct flexrm_mbox *mbox = dev_get_drvdata(dev);
-	struct flexrm_ring *ring = &mbox->rings[desc->platform.msi_index];
+	struct flexrm_ring *ring = &mbox->rings[desc->msi_index];
 
 	/* Configure per-Ring MSI registers */
 	writel_relaxed(msg->address_lo, ring->regs + RING_MSI_ADDR_LS);
@@ -1609,7 +1609,7 @@ static int flexrm_mbox_probe(struct plat
 
 	/* Save alloced IRQ numbers for each ring */
 	for_each_msi_entry(desc, dev) {
-		ring = &mbox->rings[desc->platform.msi_index];
+		ring = &mbox->rings[desc->msi_index];
 		ring->irq = desc->irq;
 	}
 
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -106,14 +106,6 @@ struct pci_msi_desc {
 };
 
 /**
- * platform_msi_desc - Platform device specific msi descriptor data
- * @msi_index:		The index of the MSI descriptor for multi MSI
- */
-struct platform_msi_desc {
-	u16				msi_index;
-};
-
-/**
  * fsl_mc_msi_desc - FSL-MC device specific msi descriptor data
  * @msi_index:		The index of the MSI descriptor
  */
@@ -144,7 +136,6 @@ struct ti_sci_inta_msi_desc {
  *
  * @msi_index:	Index of the msi descriptor
  * @pci:	[PCI]	    PCI speficic msi descriptor data
- * @platform:	[platform]  Platform device specific msi descriptor data
  * @fsl_mc:	[fsl-mc]    FSL MC device specific msi descriptor data
  * @inta:	[INTA]	    TISCI based INTA specific msi descriptor data
  */
@@ -166,7 +157,6 @@ struct msi_desc {
 	u16				msi_index;
 	union {
 		struct pci_msi_desc		pci;
-		struct platform_msi_desc	platform;
 		struct fsl_mc_msi_desc		fsl_mc;
 		struct ti_sci_inta_msi_desc	inta;
 	};


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 16/37] bus: fsl-mc-msi: Use msi_desc::msi_index
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (13 preceding siblings ...)
  2021-11-27  1:20 ` [patch 15/37] platform-msi: Use msi_desc::msi_index Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 17/37] soc: ti: ti_sci_inta_msi: " Thomas Gleixner
                   ` (24 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Use the common msi_index member and get rid of the pointless wrapper struct.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/bus/fsl-mc/fsl-mc-allocator.c |    2 +-
 drivers/bus/fsl-mc/fsl-mc-msi.c       |    6 +++---
 include/linux/msi.h                   |   10 ----------
 3 files changed, 4 insertions(+), 14 deletions(-)

--- a/drivers/bus/fsl-mc/fsl-mc-allocator.c
+++ b/drivers/bus/fsl-mc/fsl-mc-allocator.c
@@ -393,7 +393,7 @@ int fsl_mc_populate_irq_pool(struct fsl_
 	}
 
 	for_each_msi_entry(msi_desc, &mc_bus_dev->dev) {
-		mc_dev_irq = &irq_resources[msi_desc->fsl_mc.msi_index];
+		mc_dev_irq = &irq_resources[msi_desc->msi_index];
 		mc_dev_irq->msi_desc = msi_desc;
 		mc_dev_irq->resource.id = msi_desc->irq;
 	}
--- a/drivers/bus/fsl-mc/fsl-mc-msi.c
+++ b/drivers/bus/fsl-mc/fsl-mc-msi.c
@@ -29,7 +29,7 @@ static irq_hw_number_t fsl_mc_domain_cal
 	 * Make the base hwirq value for ICID*10000 so it is readable
 	 * as a decimal value in /proc/interrupts.
 	 */
-	return (irq_hw_number_t)(desc->fsl_mc.msi_index + (dev->icid * 10000));
+	return (irq_hw_number_t)(desc->msi_index + (dev->icid * 10000));
 }
 
 static void fsl_mc_msi_set_desc(msi_alloc_info_t *arg,
@@ -122,7 +122,7 @@ static void fsl_mc_msi_write_msg(struct
 	struct fsl_mc_device *mc_bus_dev = to_fsl_mc_device(msi_desc->dev);
 	struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);
 	struct fsl_mc_device_irq *mc_dev_irq =
-		&mc_bus->irq_resources[msi_desc->fsl_mc.msi_index];
+		&mc_bus->irq_resources[msi_desc->msi_index];
 
 	msi_desc->msg = *msg;
 
@@ -235,7 +235,7 @@ static int fsl_mc_msi_alloc_descs(struct
 			goto cleanup_msi_descs;
 		}
 
-		msi_desc->fsl_mc.msi_index = i;
+		msi_desc->msi_index = i;
 		INIT_LIST_HEAD(&msi_desc->list);
 		list_add_tail(&msi_desc->list, dev_to_msi_list(dev));
 	}
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -106,14 +106,6 @@ struct pci_msi_desc {
 };
 
 /**
- * fsl_mc_msi_desc - FSL-MC device specific msi descriptor data
- * @msi_index:		The index of the MSI descriptor
- */
-struct fsl_mc_msi_desc {
-	u16				msi_index;
-};
-
-/**
  * ti_sci_inta_msi_desc - TISCI based INTA specific msi descriptor data
  * @dev_index: TISCI device index
  */
@@ -136,7 +128,6 @@ struct ti_sci_inta_msi_desc {
  *
  * @msi_index:	Index of the msi descriptor
  * @pci:	[PCI]	    PCI speficic msi descriptor data
- * @fsl_mc:	[fsl-mc]    FSL MC device specific msi descriptor data
  * @inta:	[INTA]	    TISCI based INTA specific msi descriptor data
  */
 struct msi_desc {
@@ -157,7 +148,6 @@ struct msi_desc {
 	u16				msi_index;
 	union {
 		struct pci_msi_desc		pci;
-		struct fsl_mc_msi_desc		fsl_mc;
 		struct ti_sci_inta_msi_desc	inta;
 	};
 };


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 17/37] soc: ti: ti_sci_inta_msi: Use msi_desc::msi_index
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (14 preceding siblings ...)
  2021-11-27  1:20 ` [patch 16/37] bus: fsl-mc-msi: " Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 18/37] PCI/MSI: " Thomas Gleixner
                   ` (23 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Use the common msi_index member and get rid of the pointless wrapper struct.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/irqchip/irq-ti-sci-inta.c |    2 +-
 drivers/soc/ti/ti_sci_inta_msi.c  |    6 +++---
 include/linux/msi.h               |   16 ++--------------
 3 files changed, 6 insertions(+), 18 deletions(-)

--- a/drivers/irqchip/irq-ti-sci-inta.c
+++ b/drivers/irqchip/irq-ti-sci-inta.c
@@ -595,7 +595,7 @@ static void ti_sci_inta_msi_set_desc(msi
 	struct platform_device *pdev = to_platform_device(desc->dev);
 
 	arg->desc = desc;
-	arg->hwirq = TO_HWIRQ(pdev->id, desc->inta.dev_index);
+	arg->hwirq = TO_HWIRQ(pdev->id, desc->msi_index);
 }
 
 static struct msi_domain_ops ti_sci_inta_msi_ops = {
--- a/drivers/soc/ti/ti_sci_inta_msi.c
+++ b/drivers/soc/ti/ti_sci_inta_msi.c
@@ -84,7 +84,7 @@ static int ti_sci_inta_msi_alloc_descs(s
 				return -ENOMEM;
 			}
 
-			msi_desc->inta.dev_index = res->desc[set].start + i;
+			msi_desc->msi_index = res->desc[set].start + i;
 			INIT_LIST_HEAD(&msi_desc->list);
 			list_add_tail(&msi_desc->list, dev_to_msi_list(dev));
 			count++;
@@ -96,7 +96,7 @@ static int ti_sci_inta_msi_alloc_descs(s
 				return -ENOMEM;
 			}
 
-			msi_desc->inta.dev_index = res->desc[set].start_sec + i;
+			msi_desc->msi_index = res->desc[set].start_sec + i;
 			INIT_LIST_HEAD(&msi_desc->list);
 			list_add_tail(&msi_desc->list, dev_to_msi_list(dev));
 			count++;
@@ -154,7 +154,7 @@ unsigned int ti_sci_inta_msi_get_virq(st
 	struct msi_desc *desc;
 
 	for_each_msi_entry(desc, dev)
-		if (desc->inta.dev_index == dev_index)
+		if (desc->msi_index == dev_index)
 			return desc->irq;
 
 	return -ENODEV;
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -106,14 +106,6 @@ struct pci_msi_desc {
 };
 
 /**
- * ti_sci_inta_msi_desc - TISCI based INTA specific msi descriptor data
- * @dev_index: TISCI device index
- */
-struct ti_sci_inta_msi_desc {
-	u16	dev_index;
-};
-
-/**
  * struct msi_desc - Descriptor structure for MSI based interrupts
  * @list:	List head for management
  * @irq:	The base interrupt number
@@ -127,8 +119,7 @@ struct ti_sci_inta_msi_desc {
  * @write_msi_msg_data:	Data parameter for the callback.
  *
  * @msi_index:	Index of the msi descriptor
- * @pci:	[PCI]	    PCI speficic msi descriptor data
- * @inta:	[INTA]	    TISCI based INTA specific msi descriptor data
+ * @pci:	PCI speficic msi descriptor data
  */
 struct msi_desc {
 	/* Shared device/bus type independent data */
@@ -146,10 +137,7 @@ struct msi_desc {
 	void *write_msi_msg_data;
 
 	u16				msi_index;
-	union {
-		struct pci_msi_desc		pci;
-		struct ti_sci_inta_msi_desc	inta;
-	};
+	struct pci_msi_desc		pci;
 };
 
 /**


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 18/37] PCI/MSI: Use msi_desc::msi_index
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (15 preceding siblings ...)
  2021-11-27  1:20 ` [patch 17/37] soc: ti: ti_sci_inta_msi: " Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 19/37] genirq/msi: Add msi_device_data::properties Thomas Gleixner
                   ` (22 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

The usage of msi_desc::pci::entry_nr is confusing at best. It's the index
into the MSI[X] descriptor table.

Use msi_desc::msi_index which is shared between all MSI incarnations
instead of having a PCI specific storage for no value.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/powerpc/platforms/pseries/msi.c |    4 ++--
 arch/x86/pci/xen.c                   |    2 +-
 drivers/pci/msi/irqdomain.c          |    2 +-
 drivers/pci/msi/msi.c                |   20 ++++++++------------
 drivers/pci/xen-pcifront.c           |    2 +-
 include/linux/msi.h                  |    2 --
 6 files changed, 13 insertions(+), 19 deletions(-)

--- a/arch/powerpc/platforms/pseries/msi.c
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -332,7 +332,7 @@ static int check_msix_entries(struct pci
 
 	expected = 0;
 	for_each_pci_msi_entry(entry, pdev) {
-		if (entry->pci.msi_attrib.entry_nr != expected) {
+		if (entry->msi_index != expected) {
 			pr_debug("rtas_msi: bad MSI-X entries.\n");
 			return -EINVAL;
 		}
@@ -580,7 +580,7 @@ static int pseries_irq_domain_alloc(stru
 	int hwirq;
 	int i, ret;
 
-	hwirq = rtas_query_irq_number(pci_get_pdn(pdev), desc->pci.msi_attrib.entry_nr);
+	hwirq = rtas_query_irq_number(pci_get_pdn(pdev), desc->msi_index);
 	if (hwirq < 0) {
 		dev_err(&pdev->dev, "Failed to query HW IRQ: %d\n", hwirq);
 		return hwirq;
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -306,7 +306,7 @@ static int xen_initdom_setup_msi_irqs(st
 				return -EINVAL;
 
 			map_irq.table_base = pci_resource_start(dev, bir);
-			map_irq.entry_nr = msidesc->pci.msi_attrib.entry_nr;
+			map_irq.entry_nr = msidesc->msi_index;
 		}
 
 		ret = -EINVAL;
--- a/drivers/pci/msi/irqdomain.c
+++ b/drivers/pci/msi/irqdomain.c
@@ -57,7 +57,7 @@ static irq_hw_number_t pci_msi_domain_ca
 {
 	struct pci_dev *dev = msi_desc_to_pci_dev(desc);
 
-	return (irq_hw_number_t)desc->pci.msi_attrib.entry_nr |
+	return (irq_hw_number_t)desc->msi_index |
 		pci_dev_id(dev) << 11 |
 		(pci_domain_nr(dev->bus) & 0xFFFFFFFF) << 27;
 }
--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -44,7 +44,7 @@ static inline void pci_msi_unmask(struct
 
 static inline void __iomem *pci_msix_desc_addr(struct msi_desc *desc)
 {
-	return desc->pci.mask_base + desc->pci.msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
+	return desc->pci.mask_base + desc->msi_index * PCI_MSIX_ENTRY_SIZE;
 }
 
 /*
@@ -354,13 +354,10 @@ msi_setup_entry(struct pci_dev *dev, int
 	if (dev->dev_flags & PCI_DEV_FLAGS_HAS_MSI_MASKING)
 		control |= PCI_MSI_FLAGS_MASKBIT;
 
-	entry->pci.msi_attrib.is_msix	= 0;
-	entry->pci.msi_attrib.is_64		= !!(control & PCI_MSI_FLAGS_64BIT);
-	entry->pci.msi_attrib.is_virtual    = 0;
-	entry->pci.msi_attrib.entry_nr	= 0;
+	entry->pci.msi_attrib.is_64	= !!(control & PCI_MSI_FLAGS_64BIT);
 	entry->pci.msi_attrib.can_mask	= !pci_msi_ignore_mask &&
 					  !!(control & PCI_MSI_FLAGS_MASKBIT);
-	entry->pci.msi_attrib.default_irq	= dev->irq;	/* Save IOAPIC IRQ */
+	entry->pci.msi_attrib.default_irq = dev->irq;
 	entry->pci.msi_attrib.multi_cap	= (control & PCI_MSI_FLAGS_QMASK) >> 1;
 	entry->pci.msi_attrib.multiple	= ilog2(__roundup_pow_of_two(nvec));
 
@@ -494,12 +491,11 @@ static int msix_setup_entries(struct pci
 		entry->pci.msi_attrib.is_64	= 1;
 
 		if (entries)
-			entry->pci.msi_attrib.entry_nr = entries[i].entry;
+			entry->msi_index = entries[i].entry;
 		else
-			entry->pci.msi_attrib.entry_nr = i;
+			entry->msi_index = i;
 
-		entry->pci.msi_attrib.is_virtual =
-			entry->pci.msi_attrib.entry_nr >= vec_count;
+		entry->pci.msi_attrib.is_virtual = entry->msi_index >= vec_count;
 
 		entry->pci.msi_attrib.can_mask	= !pci_msi_ignore_mask &&
 						  !entry->pci.msi_attrib.is_virtual;
@@ -1025,7 +1021,7 @@ int pci_irq_vector(struct pci_dev *dev,
 		struct msi_desc *entry;
 
 		for_each_pci_msi_entry(entry, dev) {
-			if (entry->pci.msi_attrib.entry_nr == nr)
+			if (entry->msi_index == nr)
 				return entry->irq;
 		}
 		WARN_ON_ONCE(1);
@@ -1057,7 +1053,7 @@ const struct cpumask *pci_irq_get_affini
 		struct msi_desc *entry;
 
 		for_each_pci_msi_entry(entry, dev) {
-			if (entry->pci.msi_attrib.entry_nr == nr)
+			if (entry->msi_index == nr)
 				return &entry->affinity->mask;
 		}
 		WARN_ON_ONCE(1);
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -263,7 +263,7 @@ static int pci_frontend_enable_msix(stru
 
 	i = 0;
 	for_each_pci_msi_entry(entry, dev) {
-		op.msix_entries[i].entry = entry->pci.msi_attrib.entry_nr;
+		op.msix_entries[i].entry = entry->msi_index;
 		/* Vector is useless at this point. */
 		op.msix_entries[i].vector = -1;
 		i++;
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -79,7 +79,6 @@ typedef void (*irq_write_msi_msg_t)(stru
  * @multi_cap:	[PCI MSI/X] log2 num of messages supported
  * @can_mask:	[PCI MSI/X] Masking supported?
  * @is_64:	[PCI MSI/X] Address size: 0=32bit 1=64bit
- * @entry_nr:	[PCI MSI/X] Entry which is described by this descriptor
  * @default_irq:[PCI MSI/X] The default pre-assigned non-MSI irq
  * @mask_pos:	[PCI MSI]   Mask register position
  * @mask_base:	[PCI MSI-X] Mask register base address
@@ -96,7 +95,6 @@ struct pci_msi_desc {
 		u8	can_mask	: 1;
 		u8	is_64		: 1;
 		u8	is_virtual	: 1;
-		u16	entry_nr;
 		unsigned default_irq;
 	} msi_attrib;
 	union {


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 19/37] genirq/msi: Add msi_device_data::properties
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (16 preceding siblings ...)
  2021-11-27  1:20 ` [patch 18/37] PCI/MSI: " Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 20/37] PCI/MSI: Store properties in device::msi::data Thomas Gleixner
                   ` (21 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Add a properties field which allows core code to store information for easy
retrieval in order to replace MSI descriptor fiddling.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/msi.h |   17 +++++++++++++++++
 kernel/irq/msi.c    |   12 ++++++++++++
 2 files changed, 29 insertions(+)

--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -4,6 +4,7 @@
 
 #include <linux/spinlock.h>
 #include <linux/list.h>
+#include <linux/bits.h>
 #include <asm/msi.h>
 
 /* Dummy shadow structures if an architecture does not define them */
@@ -141,17 +142,33 @@ struct msi_desc {
 /**
  * msi_device_data - MSI per device data
  * @lock:		Spinlock to protect register access
+ * @properties:		MSI properties which are interesting to drivers
  * @attrs:		Pointer to the sysfs attribute group
  * @platform_data:	Platform-MSI specific data
  */
 struct msi_device_data {
 	raw_spinlock_t			lock;
+	unsigned long			properties;
 	const struct attribute_group    **attrs;
 	struct platform_msi_priv_data	*platform_data;
 };
 
 int msi_setup_device_data(struct device *dev);
 
+/* MSI device properties */
+#define MSI_PROP_PCI_MSI		BIT(0)
+#define MSI_PROP_PCI_MSIX		BIT(1)
+#define MSI_PROP_64BIT			BIT(2)
+
+#ifdef CONFIG_GENERIC_MSI_IRQ
+bool msi_device_has_property(struct device *dev, unsigned long prop);
+#else
+static inline bool msi_device_has_property(struct device *dev, unsigned long prop)
+{
+	return false;
+}
+#endif
+
 /* Helpers to hide struct msi_desc implementation details */
 #define msi_desc_to_dev(desc)		((desc)->dev)
 #define dev_to_msi_list(dev)		(&(dev)->msi_list)
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -60,6 +60,18 @@ void free_msi_entry(struct msi_desc *ent
 	kfree(entry);
 }
 
+/**
+ * msi_device_has_property - Check whether a device has a specific MSI property
+ * @dev:	Pointer to the device which is queried
+ * @prop:	Property to check for
+ */
+bool msi_device_has_property(struct device *dev, unsigned long prop)
+{
+	if (!dev->msi.data)
+		return false;
+	return !!(dev->msi.data->properties & prop);
+}
+
 void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
 {
 	*msg = entry->msg;


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 20/37] PCI/MSI: Store properties in device::msi::data
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (17 preceding siblings ...)
  2021-11-27  1:20 ` [patch 19/37] genirq/msi: Add msi_device_data::properties Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 21/37] x86/pci/XEN: Use device MSI properties Thomas Gleixner
                   ` (20 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Store the properties which are interesting for various places so the MSI
descriptor fiddling can be removed.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/pci/msi/msi.c |    6 ++++++
 1 file changed, 6 insertions(+)

--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -244,6 +244,8 @@ static void free_msi_irqs(struct pci_dev
 		iounmap(dev->msix_base);
 		dev->msix_base = NULL;
 	}
+
+	dev->dev.msi.data->properties = 0;
 }
 
 static void pci_intx_for_msi(struct pci_dev *dev, int enable)
@@ -372,6 +374,9 @@ msi_setup_entry(struct pci_dev *dev, int
 	if (entry->pci.msi_attrib.can_mask)
 		pci_read_config_dword(dev, entry->pci.mask_pos, &entry->pci.msi_mask);
 
+	dev->dev.msi.data->properties = MSI_PROP_PCI_MSI;
+	if (entry->pci.msi_attrib.is_64)
+		dev->dev.msi.data->properties |= MSI_PROP_64BIT;
 out:
 	kfree(masks);
 	return entry;
@@ -514,6 +519,7 @@ static int msix_setup_entries(struct pci
 		if (masks)
 			curmsk++;
 	}
+	dev->dev.msi.data->properties = MSI_PROP_PCI_MSIX | MSI_PROP_64BIT;
 	ret = 0;
 out:
 	kfree(masks);


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 21/37] x86/pci/XEN: Use device MSI properties
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (18 preceding siblings ...)
  2021-11-27  1:20 ` [patch 20/37] PCI/MSI: Store properties in device::msi::data Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 22/37] x86/apic/msi: " Thomas Gleixner
                   ` (19 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

instead of fiddling with MSI descriptors.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/pci/xen.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -399,9 +399,7 @@ static void xen_teardown_msi_irqs(struct
 
 static void xen_pv_teardown_msi_irqs(struct pci_dev *dev)
 {
-	struct msi_desc *msidesc = first_pci_msi_entry(dev);
-
-	if (msidesc->pci.msi_attrib.is_msix)
+	if (msi_device_has_property(&dev->dev, MSI_PROP_PCI_MSIX))
 		xen_pci_frontend_disable_msix(dev);
 	else
 		xen_pci_frontend_disable_msi(dev);
@@ -417,7 +415,7 @@ static int xen_msi_domain_alloc_irqs(str
 	if (WARN_ON_ONCE(!dev_is_pci(dev)))
 		return -EINVAL;
 
-	if (first_msi_entry(dev)->pci.msi_attrib.is_msix)
+	if (msi_device_has_property(dev, MSI_PROP_PCI_MSIX))
 		type = PCI_CAP_ID_MSIX;
 	else
 		type = PCI_CAP_ID_MSI;


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 22/37] x86/apic/msi: Use device MSI properties
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (19 preceding siblings ...)
  2021-11-27  1:20 ` [patch 21/37] x86/pci/XEN: Use device MSI properties Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 23/37] genirq/msi: " Thomas Gleixner
                   ` (18 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

instead of fiddling with MSI descriptors.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/apic/msi.c |    5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

--- a/arch/x86/kernel/apic/msi.c
+++ b/arch/x86/kernel/apic/msi.c
@@ -160,11 +160,8 @@ static struct irq_chip pci_msi_controlle
 int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
 		    msi_alloc_info_t *arg)
 {
-	struct pci_dev *pdev = to_pci_dev(dev);
-	struct msi_desc *desc = first_pci_msi_entry(pdev);
-
 	init_irq_alloc_info(arg, NULL);
-	if (desc->pci.msi_attrib.is_msix) {
+	if (msi_device_has_property(dev, MSI_PROP_PCI_MSIX)) {
 		arg->type = X86_IRQ_ALLOC_TYPE_PCI_MSIX;
 	} else {
 		arg->type = X86_IRQ_ALLOC_TYPE_PCI_MSI;


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 23/37] genirq/msi: Use device MSI properties
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (20 preceding siblings ...)
  2021-11-27  1:20 ` [patch 22/37] x86/apic/msi: " Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 24/37] powerpc/cell/axon_msi: Use MSI device properties Thomas Gleixner
                   ` (17 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, x86, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

instead of fiddling with MSI descriptors.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: x86@kernel.org
---
 kernel/irq/msi.c |   17 ++---------------
 1 file changed, 2 insertions(+), 15 deletions(-)

--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -114,21 +114,8 @@ int msi_setup_device_data(struct device
 static ssize_t msi_mode_show(struct device *dev, struct device_attribute *attr,
 			     char *buf)
 {
-	struct msi_desc *entry;
-	bool is_msix = false;
-	unsigned long irq;
-	int retval;
-
-	retval = kstrtoul(attr->attr.name, 10, &irq);
-	if (retval)
-		return retval;
-
-	entry = irq_get_msi_desc(irq);
-	if (!entry)
-		return -ENODEV;
-
-	if (dev_is_pci(dev))
-		is_msix = entry->pci.msi_attrib.is_msix;
+	/* MSI vs. MSIX is per device not per interrupt */
+	bool is_msix = msi_device_has_property(dev, MSI_PROP_PCI_MSIX);
 
 	return sysfs_emit(buf, "%s\n", is_msix ? "msix" : "msi");
 }


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 24/37] powerpc/cell/axon_msi: Use MSI device properties
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (21 preceding siblings ...)
  2021-11-27  1:20 ` [patch 23/37] genirq/msi: " Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 25/37] powerpc/pseries/msi: " Thomas Gleixner
                   ` (16 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

instead of fiddling with MSI descriptors.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/powerpc/platforms/cell/axon_msi.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -199,7 +199,7 @@ static struct axon_msic *find_msi_transl
 static int setup_msi_msg_address(struct pci_dev *dev, struct msi_msg *msg)
 {
 	struct device_node *dn;
-	struct msi_desc *entry;
+	bool is_64bit;
 	int len;
 	const u32 *prop;
 
@@ -209,10 +209,10 @@ static int setup_msi_msg_address(struct
 		return -ENODEV;
 	}
 
-	entry = first_pci_msi_entry(dev);
+	is_64bit = msi_device_has_property(MSI_PROP_64BIT);
 
 	for (; dn; dn = of_get_next_parent(dn)) {
-		if (entry->pci.msi_attrib.is_64) {
+		if (is_64bit) {
 			prop = of_get_property(dn, "msi-address-64", &len);
 			if (prop)
 				break;


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 25/37] powerpc/pseries/msi: Use MSI device properties
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (22 preceding siblings ...)
  2021-11-27  1:20 ` [patch 24/37] powerpc/cell/axon_msi: Use MSI device properties Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 26/37] PCI/MSI: Provide MSI_FLAG_MSIX_CONTIGUOUS Thomas Gleixner
                   ` (15 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

instead of fiddling with MSI descriptors.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/powerpc/platforms/pseries/msi.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/arch/powerpc/platforms/pseries/msi.c
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -447,9 +447,9 @@ static int rtas_prepare_msi_irqs(struct
 static int pseries_msi_ops_prepare(struct irq_domain *domain, struct device *dev,
 				   int nvec, msi_alloc_info_t *arg)
 {
+	bool is_msix = msi_device_has_property(dev, MSI_PROP_PCI_MSIX);
+	int type = is_msix ? PCI_CAP_ID_MSIX : PCI_CAP_ID_MSI;
 	struct pci_dev *pdev = to_pci_dev(dev);
-	struct msi_desc *desc = first_pci_msi_entry(pdev);
-	int type = desc->pci.msi_attrib.is_msix ? PCI_CAP_ID_MSIX : PCI_CAP_ID_MSI;
 
 	return rtas_prepare_msi_irqs(pdev, nvec, type, arg);
 }


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 26/37] PCI/MSI: Provide MSI_FLAG_MSIX_CONTIGUOUS
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (23 preceding siblings ...)
  2021-11-27  1:20 ` [patch 25/37] powerpc/pseries/msi: " Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 27/37] powerpc/pseries/msi: Let core code check for contiguous entries Thomas Gleixner
                   ` (14 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Provide a domain info flag which makes the core code check for a contiguous
MSI-X index on allocation. That's simpler than checking it at some other
domain callback in architecture code.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/pci/msi/irqdomain.c |   16 ++++++++++++++--
 include/linux/msi.h         |    2 ++
 2 files changed, 16 insertions(+), 2 deletions(-)

--- a/drivers/pci/msi/irqdomain.c
+++ b/drivers/pci/msi/irqdomain.c
@@ -89,9 +89,21 @@ static int pci_msi_domain_check_cap(stru
 	if (pci_msi_desc_is_multi_msi(desc) &&
 	    !(info->flags & MSI_FLAG_MULTI_PCI_MSI))
 		return 1;
-	else if (desc->pci.msi_attrib.is_msix && !(info->flags & MSI_FLAG_PCI_MSIX))
-		return -ENOTSUPP;
 
+	if (desc->pci.msi_attrib.is_msix) {
+		if (!(info->flags & MSI_FLAG_PCI_MSIX))
+			return -ENOTSUPP;
+
+		if (info->flags & MSI_FLAG_MSIX_CONTIGUOUS) {
+			unsigned int idx = 0;
+
+			/* Check for gaps in the entry indices */
+			for_each_msi_entry(desc, dev) {
+				if (desc->msi_index != idx++)
+					return -ENOTSUPP;
+			}
+		}
+	}
 	return 0;
 }
 
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -378,6 +378,8 @@ enum {
 	MSI_FLAG_LEVEL_CAPABLE		= (1 << 6),
 	/* Populate sysfs on alloc() and destroy it on free() */
 	MSI_FLAG_DEV_SYSFS		= (1 << 7),
+	/* MSI-X entries must be contiguous */
+	MSI_FLAG_MSIX_CONTIGUOUS	= (1 << 8),
 };
 
 int msi_domain_set_affinity(struct irq_data *data, const struct cpumask *mask,


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 27/37] powerpc/pseries/msi: Let core code check for contiguous entries
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (24 preceding siblings ...)
  2021-11-27  1:20 ` [patch 26/37] PCI/MSI: Provide MSI_FLAG_MSIX_CONTIGUOUS Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:22   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 28/37] genirq/msi: Provide interface to retrieve Linux interrupt number Thomas Gleixner
                   ` (13 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Set the domain info flag and remove the check.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/powerpc/platforms/pseries/msi.c |   32 +++++++++-----------------------
 1 file changed, 9 insertions(+), 23 deletions(-)

--- a/arch/powerpc/platforms/pseries/msi.c
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -321,27 +321,6 @@ static int msi_quota_for_device(struct p
 	return request;
 }
 
-static int check_msix_entries(struct pci_dev *pdev)
-{
-	struct msi_desc *entry;
-	int expected;
-
-	/* There's no way for us to express to firmware that we want
-	 * a discontiguous, or non-zero based, range of MSI-X entries.
-	 * So we must reject such requests. */
-
-	expected = 0;
-	for_each_pci_msi_entry(entry, pdev) {
-		if (entry->msi_index != expected) {
-			pr_debug("rtas_msi: bad MSI-X entries.\n");
-			return -EINVAL;
-		}
-		expected++;
-	}
-
-	return 0;
-}
-
 static void rtas_hack_32bit_msi_gen2(struct pci_dev *pdev)
 {
 	u32 addr_hi, addr_lo;
@@ -380,7 +359,7 @@ static int rtas_prepare_msi_irqs(struct
 	if (quota && quota < nvec)
 		return quota;
 
-	if (type == PCI_CAP_ID_MSIX && check_msix_entries(pdev))
+	if (type == PCI_CAP_ID_MSIX)
 		return -EINVAL;
 
 	/*
@@ -530,9 +509,16 @@ static struct irq_chip pseries_pci_msi_i
 	.irq_write_msi_msg	= pseries_msi_write_msg,
 };
 
+
+/*
+ * Set MSI_FLAG_MSIX_CONTIGUOUS as there is no way to express to
+ * firmware to request a discontiguous or non-zero based range of
+ * MSI-X entries. Core code will reject such setup attempts.
+ */
 static struct msi_domain_info pseries_msi_domain_info = {
 	.flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-		  MSI_FLAG_MULTI_PCI_MSI  | MSI_FLAG_PCI_MSIX),
+		  MSI_FLAG_MULTI_PCI_MSI  | MSI_FLAG_PCI_MSIX |
+		  MSI_FLAG_MSIX_CONTIGUOUS),
 	.ops   = &pseries_pci_msi_domain_ops,
 	.chip  = &pseries_pci_msi_irq_chip,
 };


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 28/37] genirq/msi: Provide interface to retrieve Linux interrupt number
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (25 preceding siblings ...)
  2021-11-27  1:20 ` [patch 27/37] powerpc/pseries/msi: Let core code check for contiguous entries Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:22   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 29/37] PCI/MSI: Use __msi_get_virq() in pci_get_vector() Thomas Gleixner
                   ` (12 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

This allows drivers to retrieve the Linux interrupt number instead of
fiddling with MSI descriptors.

msi_get_virq() returns the Linux interrupt number or 0, __msi_get_virq()
has more detailed return codes so pci_irq_vector() can use it as well.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/msi.h |   16 ++++++++++++++++
 kernel/irq/msi.c    |   38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+)

--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -169,6 +169,22 @@ static inline bool msi_device_has_proper
 }
 #endif
 
+int __msi_get_virq(struct device *dev, unsigned int index);
+
+/**
+ * msi_get_virq - Return Linux interrupt number of a MSI interrupt
+ * @dev:	Device to operate on
+ * @index:	MSI interrupt index to look for (0-based)
+ *
+ * Return: The Linux interrupt number on success (> 0), 0 if not found
+ */
+static inline unsigned int msi_get_virq(struct device *dev, unsigned int index)
+{
+	int ret = __msi_get_virq(dev, index);
+
+	return ret < 0 ? 0 : ret;
+}
+
 /* Helpers to hide struct msi_desc implementation details */
 #define msi_desc_to_dev(desc)		((desc)->dev)
 #define dev_to_msi_list(dev)		(&(dev)->msi_list)
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -120,6 +120,44 @@ int msi_setup_device_data(struct device
 	return 0;
 }
 
+/**
+ * __msi_get_virq - Return Linux interrupt number of a MSI interrupt
+ * @dev:	Device to operate on
+ * @index:	MSI interrupt index to look for (0-based)
+ *
+ * Return: The Linux interrupt number on success (> 0)
+ *	   -ENODEV when the device is not using MSI
+ *	   -ENOENT if no such entry exists
+ */
+int __msi_get_virq(struct device *dev, unsigned int index)
+{
+	struct msi_desc *desc;
+	bool pcimsi;
+
+	if (!dev->msi.data)
+		return -ENODEV;
+
+	pcimsi = msi_device_has_property(dev, MSI_PROP_PCI_MSI);
+
+	for_each_msi_entry(desc, dev) {
+		/* PCI-MSI has only one descriptor for multiple interrupts. */
+		if (pcimsi) {
+			if (desc->irq && index < desc->nvec_used)
+				return desc->irq + index;
+			break;
+		}
+
+		/*
+		 * PCI-MSIX and platform MSI use a descriptor per
+		 * interrupt.
+		 */
+		if (desc->msi_index == index)
+			return desc->irq;
+	}
+	return -ENOENT;
+}
+EXPORT_SYMBOL_GPL(__msi_get_virq);
+
 #ifdef CONFIG_SYSFS
 static ssize_t msi_mode_show(struct device *dev, struct device_attribute *attr,
 			     char *buf)


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 29/37] PCI/MSI: Use __msi_get_virq() in pci_get_vector()
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (26 preceding siblings ...)
  2021-11-27  1:20 ` [patch 28/37] genirq/msi: Provide interface to retrieve Linux interrupt number Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:22   ` Thomas Gleixner
  2021-11-28 19:37   ` Marc Zyngier
  2021-11-27  1:20 ` [patch 30/37] PCI/MSI: Simplify pci_irq_get_affinity() Thomas Gleixner
                   ` (11 subsequent siblings)
  39 siblings, 2 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Use __msi_get_vector() and handle the return values to be compatible.

No functional change intended.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/pci/msi/msi.c |   25 +++++--------------------
 1 file changed, 5 insertions(+), 20 deletions(-)

--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -1023,28 +1023,13 @@ EXPORT_SYMBOL(pci_free_irq_vectors);
  */
 int pci_irq_vector(struct pci_dev *dev, unsigned int nr)
 {
-	if (dev->msix_enabled) {
-		struct msi_desc *entry;
+	int irq = __msi_get_virq(&dev->dev, nr);
 
-		for_each_pci_msi_entry(entry, dev) {
-			if (entry->msi_index == nr)
-				return entry->irq;
-		}
-		WARN_ON_ONCE(1);
-		return -EINVAL;
+	switch (irq) {
+	case -ENODEV: return !nr ? dev->irq : -EINVAL;
+	case -ENOENT: return -EINVAL;
 	}
-
-	if (dev->msi_enabled) {
-		struct msi_desc *entry = first_pci_msi_entry(dev);
-
-		if (WARN_ON_ONCE(nr >= entry->nvec_used))
-			return -EINVAL;
-	} else {
-		if (WARN_ON_ONCE(nr > 0))
-			return -EINVAL;
-	}
-
-	return dev->irq + nr;
+	return irq;
 }
 EXPORT_SYMBOL(pci_irq_vector);
 


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 30/37] PCI/MSI: Simplify pci_irq_get_affinity()
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (27 preceding siblings ...)
  2021-11-27  1:20 ` [patch 29/37] PCI/MSI: Use __msi_get_virq() in pci_get_vector() Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:22   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 31/37] dmaengine: mv_xor_v2: Get rid of msi_desc abuse Thomas Gleixner
                   ` (10 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Replace open coded MSI descriptor chasing and use the proper accessor
functions instead.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/pci/msi/msi.c |   26 ++++++++++----------------
 1 file changed, 10 insertions(+), 16 deletions(-)

--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -1040,26 +1040,20 @@ EXPORT_SYMBOL(pci_irq_vector);
  */
 const struct cpumask *pci_irq_get_affinity(struct pci_dev *dev, int nr)
 {
-	if (dev->msix_enabled) {
-		struct msi_desc *entry;
+	int irq = pci_irq_vector(dev, nr);
+	struct msi_desc *desc;
 
-		for_each_pci_msi_entry(entry, dev) {
-			if (entry->msi_index == nr)
-				return &entry->affinity->mask;
-		}
-		WARN_ON_ONCE(1);
+	if (WARN_ON_ONCE(irq <= 0))
 		return NULL;
-	} else if (dev->msi_enabled) {
-		struct msi_desc *entry = first_pci_msi_entry(dev);
 
-		if (WARN_ON_ONCE(!entry || !entry->affinity ||
-				 nr >= entry->nvec_used))
-			return NULL;
-
-		return &entry->affinity[nr].mask;
-	} else {
+	desc = irq_get_msi_desc(irq);
+	/* Non-MSI does not have the information handy */
+	if (!desc)
 		return cpu_possible_mask;
-	}
+
+	if (WARN_ON_ONCE(!desc->affinity))
+		return NULL;
+	return &desc->affinity[nr].mask;
 }
 EXPORT_SYMBOL(pci_irq_get_affinity);
 


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 31/37] dmaengine: mv_xor_v2: Get rid of msi_desc abuse
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (28 preceding siblings ...)
  2021-11-27  1:20 ` [patch 30/37] PCI/MSI: Simplify pci_irq_get_affinity() Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:22   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 32/37] perf/smmuv3: Use msi_get_virq() Thomas Gleixner
                   ` (9 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, dmaengine, Vinod Koul, Santosh Shilimkar,
	iommu, Stuart Yoder, Laurentiu Tudor, Nishanth Menon,
	Tero Kristo, linux-arm-kernel, x86, Mark Rutland, Will Deacon,
	Sinan Kaya

Storing a pointer to the MSI descriptor just to keep track of the Linux
interrupt number is daft. Use msi_get_virq() instead.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: dmaengine@vger.kernel.org
Cc: Vinod Koul <vkoul@kernel.org>
---
 drivers/dma/mv_xor_v2.c |   16 +++++-----------
 1 file changed, 5 insertions(+), 11 deletions(-)

--- a/drivers/dma/mv_xor_v2.c
+++ b/drivers/dma/mv_xor_v2.c
@@ -149,7 +149,7 @@ struct mv_xor_v2_descriptor {
  * @desc_size: HW descriptor size
  * @npendings: number of pending descriptors (for which tx_submit has
  * @hw_queue_idx: HW queue index
- * @msi_desc: local interrupt descriptor information
+ * @irq: The Linux interrupt number
  * been called, but not yet issue_pending)
  */
 struct mv_xor_v2_device {
@@ -168,7 +168,7 @@ struct mv_xor_v2_device {
 	int desc_size;
 	unsigned int npendings;
 	unsigned int hw_queue_idx;
-	struct msi_desc *msi_desc;
+	unsigned int irq;
 };
 
 /**
@@ -718,7 +718,6 @@ static int mv_xor_v2_probe(struct platfo
 	int i, ret = 0;
 	struct dma_device *dma_dev;
 	struct mv_xor_v2_sw_desc *sw_desc;
-	struct msi_desc *msi_desc;
 
 	BUILD_BUG_ON(sizeof(struct mv_xor_v2_descriptor) !=
 		     MV_XOR_V2_EXT_DESC_SIZE);
@@ -770,14 +769,9 @@ static int mv_xor_v2_probe(struct platfo
 	if (ret)
 		goto disable_clk;
 
-	msi_desc = first_msi_entry(&pdev->dev);
-	if (!msi_desc) {
-		ret = -ENODEV;
-		goto free_msi_irqs;
-	}
-	xor_dev->msi_desc = msi_desc;
+	xor_dev->irq = msi_get_virq(&pdev->dev, 0);
 
-	ret = devm_request_irq(&pdev->dev, msi_desc->irq,
+	ret = devm_request_irq(&pdev->dev, xor_dev->irq,
 			       mv_xor_v2_interrupt_handler, 0,
 			       dev_name(&pdev->dev), xor_dev);
 	if (ret)
@@ -892,7 +886,7 @@ static int mv_xor_v2_remove(struct platf
 			  xor_dev->desc_size * MV_XOR_V2_DESC_NUM,
 			  xor_dev->hw_desq_virt, xor_dev->hw_desq);
 
-	devm_free_irq(&pdev->dev, xor_dev->msi_desc->irq, xor_dev);
+	devm_free_irq(&pdev->dev, xor_dev->irq, xor_dev);
 
 	platform_msi_domain_free_irqs(&pdev->dev);
 


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 32/37] perf/smmuv3: Use msi_get_virq()
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (29 preceding siblings ...)
  2021-11-27  1:20 ` [patch 31/37] dmaengine: mv_xor_v2: Get rid of msi_desc abuse Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:22   ` Thomas Gleixner
  2021-11-27  1:20 ` [patch 33/37] iommu/arm-smmu-v3: " Thomas Gleixner
                   ` (8 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Mark Rutland, Will Deacon, linux-arm-kernel,
	Santosh Shilimkar, iommu, dmaengine, Stuart Yoder,
	Laurentiu Tudor, Nishanth Menon, Tero Kristo, x86, Vinod Koul,
	Sinan Kaya

Let the core code fiddle with the MSI descriptor retrieval.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
---
 drivers/perf/arm_smmuv3_pmu.c |    5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

--- a/drivers/perf/arm_smmuv3_pmu.c
+++ b/drivers/perf/arm_smmuv3_pmu.c
@@ -684,7 +684,6 @@ static void smmu_pmu_write_msi_msg(struc
 
 static void smmu_pmu_setup_msi(struct smmu_pmu *pmu)
 {
-	struct msi_desc *desc;
 	struct device *dev = pmu->dev;
 	int ret;
 
@@ -701,9 +700,7 @@ static void smmu_pmu_setup_msi(struct sm
 		return;
 	}
 
-	desc = first_msi_entry(dev);
-	if (desc)
-		pmu->irq = desc->irq;
+	pmu->irq = msi_get_virq(dev, 0);
 
 	/* Add callback to free MSIs on teardown */
 	devm_add_action(dev, smmu_pmu_free_msis, dev);


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 33/37] iommu/arm-smmu-v3: Use msi_get_virq()
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (30 preceding siblings ...)
  2021-11-27  1:20 ` [patch 32/37] perf/smmuv3: Use msi_get_virq() Thomas Gleixner
@ 2021-11-27  1:20 ` Thomas Gleixner
  2021-11-27  1:22   ` Thomas Gleixner
                     ` (2 more replies)
  2021-11-27  1:21 ` [patch 34/37] mailbox: bcm-flexrm-mailbox: Rework MSI interrupt handling Thomas Gleixner
                   ` (7 subsequent siblings)
  39 siblings, 3 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:20 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Let the core code fiddle with the MSI descriptor retrieval.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |   19 +++----------------
 1 file changed, 3 insertions(+), 16 deletions(-)

--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3154,7 +3154,6 @@ static void arm_smmu_write_msi_msg(struc
 
 static void arm_smmu_setup_msis(struct arm_smmu_device *smmu)
 {
-	struct msi_desc *desc;
 	int ret, nvec = ARM_SMMU_MAX_MSIS;
 	struct device *dev = smmu->dev;
 
@@ -3182,21 +3181,9 @@ static void arm_smmu_setup_msis(struct a
 		return;
 	}
 
-	for_each_msi_entry(desc, dev) {
-		switch (desc->msi_index) {
-		case EVTQ_MSI_INDEX:
-			smmu->evtq.q.irq = desc->irq;
-			break;
-		case GERROR_MSI_INDEX:
-			smmu->gerr_irq = desc->irq;
-			break;
-		case PRIQ_MSI_INDEX:
-			smmu->priq.q.irq = desc->irq;
-			break;
-		default:	/* Unknown */
-			continue;
-		}
-	}
+	smmu->evtq.q.irq = msi_get_virq(dev, EVTQ_MSI_INDEX);
+	smmu->gerr_irq = msi_get_virq(dev, GERROR_MSI_INDEX);
+	smmu->priq.q.irq = msi_get_virq(dev, PRIQ_MSI_INDEX);
 
 	/* Add callback to free MSIs on teardown */
 	devm_add_action(dev, arm_smmu_free_msis, dev);


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 34/37] mailbox: bcm-flexrm-mailbox: Rework MSI interrupt handling
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (31 preceding siblings ...)
  2021-11-27  1:20 ` [patch 33/37] iommu/arm-smmu-v3: " Thomas Gleixner
@ 2021-11-27  1:21 ` Thomas Gleixner
  2021-11-27  1:22   ` Thomas Gleixner
  2021-11-27  1:21 ` [patch 35/37] bus: fsl-mc: fsl-mc-allocator: Rework MSI handling Thomas Gleixner
                   ` (6 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

No point in retrieving the MSI descriptors. Just query the Linux interrupt
number.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/mailbox/bcm-flexrm-mailbox.c |    7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

--- a/drivers/mailbox/bcm-flexrm-mailbox.c
+++ b/drivers/mailbox/bcm-flexrm-mailbox.c
@@ -1497,7 +1497,6 @@ static int flexrm_mbox_probe(struct plat
 	int index, ret = 0;
 	void __iomem *regs;
 	void __iomem *regs_end;
-	struct msi_desc *desc;
 	struct resource *iomem;
 	struct flexrm_ring *ring;
 	struct flexrm_mbox *mbox;
@@ -1608,10 +1607,8 @@ static int flexrm_mbox_probe(struct plat
 		goto fail_destroy_cmpl_pool;
 
 	/* Save alloced IRQ numbers for each ring */
-	for_each_msi_entry(desc, dev) {
-		ring = &mbox->rings[desc->msi_index];
-		ring->irq = desc->irq;
-	}
+	for (index = 0; index < mbox->num_rings; index++)
+		mbox->rings[index].irq = msi_get_virq(dev, index);
 
 	/* Check availability of debugfs */
 	if (!debugfs_initialized())


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 35/37] bus: fsl-mc: fsl-mc-allocator: Rework MSI handling
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (32 preceding siblings ...)
  2021-11-27  1:21 ` [patch 34/37] mailbox: bcm-flexrm-mailbox: Rework MSI interrupt handling Thomas Gleixner
@ 2021-11-27  1:21 ` Thomas Gleixner
  2021-11-27  1:22   ` Thomas Gleixner
  2021-11-27  1:21 ` [patch 36/37] soc: ti: ti_sci_inta_msi: Get rid of ti_sci_inta_msi_get_virq() Thomas Gleixner
                   ` (5 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Stuart Yoder, Santosh Shilimkar, iommu,
	dmaengine, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Storing a pointer to the MSI descriptor just to track the Linux interrupt
number is daft. Just store the interrupt number and be done with it.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Stuart Yoder <stuyoder@gmail.com>
---
 drivers/bus/fsl-mc/dprc-driver.c                    |    8 ++++----
 drivers/bus/fsl-mc/fsl-mc-allocator.c               |    9 ++-------
 drivers/bus/fsl-mc/fsl-mc-msi.c                     |    6 +++---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c    |    4 ++--
 drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c    |    4 +---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c |    5 ++---
 drivers/soc/fsl/dpio/dpio-driver.c                  |    8 ++++----
 drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c              |    4 ++--
 include/linux/fsl/mc.h                              |    4 ++--
 9 files changed, 22 insertions(+), 30 deletions(-)

--- a/drivers/bus/fsl-mc/dprc-driver.c
+++ b/drivers/bus/fsl-mc/dprc-driver.c
@@ -400,7 +400,7 @@ static irqreturn_t dprc_irq0_handler_thr
 	struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
 	struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
 	struct fsl_mc_io *mc_io = mc_dev->mc_io;
-	struct msi_desc *msi_desc = mc_dev->irqs[0]->msi_desc;
+	int irq = mc_dev->irqs[0]->virq;
 
 	dev_dbg(dev, "DPRC IRQ %d triggered on CPU %u\n",
 		irq_num, smp_processor_id());
@@ -409,7 +409,7 @@ static irqreturn_t dprc_irq0_handler_thr
 		return IRQ_HANDLED;
 
 	mutex_lock(&mc_bus->scan_mutex);
-	if (!msi_desc || msi_desc->irq != (u32)irq_num)
+	if (irq != (u32)irq_num)
 		goto out;
 
 	status = 0;
@@ -521,7 +521,7 @@ static int register_dprc_irq_handler(str
 	 * function that programs the MSI physically in the device
 	 */
 	error = devm_request_threaded_irq(&mc_dev->dev,
-					  irq->msi_desc->irq,
+					  irq->virq,
 					  dprc_irq0_handler,
 					  dprc_irq0_handler_thread,
 					  IRQF_NO_SUSPEND | IRQF_ONESHOT,
@@ -771,7 +771,7 @@ static void dprc_teardown_irq(struct fsl
 
 	(void)disable_dprc_irq(mc_dev);
 
-	devm_free_irq(&mc_dev->dev, irq->msi_desc->irq, &mc_dev->dev);
+	devm_free_irq(&mc_dev->dev, irq->virq, &mc_dev->dev);
 
 	fsl_mc_free_irqs(mc_dev);
 }
--- a/drivers/bus/fsl-mc/fsl-mc-allocator.c
+++ b/drivers/bus/fsl-mc/fsl-mc-allocator.c
@@ -350,7 +350,6 @@ int fsl_mc_populate_irq_pool(struct fsl_
 			     unsigned int irq_count)
 {
 	unsigned int i;
-	struct msi_desc *msi_desc;
 	struct fsl_mc_device_irq *irq_resources;
 	struct fsl_mc_device_irq *mc_dev_irq;
 	int error;
@@ -388,16 +387,12 @@ int fsl_mc_populate_irq_pool(struct fsl_
 		mc_dev_irq->resource.type = res_pool->type;
 		mc_dev_irq->resource.data = mc_dev_irq;
 		mc_dev_irq->resource.parent_pool = res_pool;
+		mc_dev_irq->virq = msi_get_virq(&mc_bus_dev->dev, i);
+		mc_dev_irq->resource.id = mc_dev_irq->virq;
 		INIT_LIST_HEAD(&mc_dev_irq->resource.node);
 		list_add_tail(&mc_dev_irq->resource.node, &res_pool->free_list);
 	}
 
-	for_each_msi_entry(msi_desc, &mc_bus_dev->dev) {
-		mc_dev_irq = &irq_resources[msi_desc->msi_index];
-		mc_dev_irq->msi_desc = msi_desc;
-		mc_dev_irq->resource.id = msi_desc->irq;
-	}
-
 	res_pool->max_count = irq_count;
 	res_pool->free_count = irq_count;
 	mc_bus->irq_resources = irq_resources;
--- a/drivers/bus/fsl-mc/fsl-mc-msi.c
+++ b/drivers/bus/fsl-mc/fsl-mc-msi.c
@@ -58,11 +58,11 @@ static void fsl_mc_msi_update_dom_ops(st
 }
 
 static void __fsl_mc_msi_write_msg(struct fsl_mc_device *mc_bus_dev,
-				   struct fsl_mc_device_irq *mc_dev_irq)
+				   struct fsl_mc_device_irq *mc_dev_irq,
+				   struct msi_desc *msi_desc)
 {
 	int error;
 	struct fsl_mc_device *owner_mc_dev = mc_dev_irq->mc_dev;
-	struct msi_desc *msi_desc = mc_dev_irq->msi_desc;
 	struct dprc_irq_cfg irq_cfg;
 
 	/*
@@ -129,7 +129,7 @@ static void fsl_mc_msi_write_msg(struct
 	/*
 	 * Program the MSI (paddr, value) pair in the device:
 	 */
-	__fsl_mc_msi_write_msg(mc_bus_dev, mc_dev_irq);
+	__fsl_mc_msi_write_msg(mc_bus_dev, mc_dev_irq, msi_desc);
 }
 
 static void fsl_mc_msi_update_chip_ops(struct msi_domain_info *info)
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -4246,7 +4246,7 @@ static int dpaa2_eth_setup_irqs(struct f
 	}
 
 	irq = ls_dev->irqs[0];
-	err = devm_request_threaded_irq(&ls_dev->dev, irq->msi_desc->irq,
+	err = devm_request_threaded_irq(&ls_dev->dev, irq->virq,
 					NULL, dpni_irq0_handler_thread,
 					IRQF_NO_SUSPEND | IRQF_ONESHOT,
 					dev_name(&ls_dev->dev), &ls_dev->dev);
@@ -4273,7 +4273,7 @@ static int dpaa2_eth_setup_irqs(struct f
 	return 0;
 
 free_irq:
-	devm_free_irq(&ls_dev->dev, irq->msi_desc->irq, &ls_dev->dev);
+	devm_free_irq(&ls_dev->dev, irq->virq, &ls_dev->dev);
 free_mc_irq:
 	fsl_mc_free_irqs(ls_dev);
 
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c
@@ -129,7 +129,6 @@ static irqreturn_t dpaa2_ptp_irq_handler
 static int dpaa2_ptp_probe(struct fsl_mc_device *mc_dev)
 {
 	struct device *dev = &mc_dev->dev;
-	struct fsl_mc_device_irq *irq;
 	struct ptp_qoriq *ptp_qoriq;
 	struct device_node *node;
 	void __iomem *base;
@@ -177,8 +176,7 @@ static int dpaa2_ptp_probe(struct fsl_mc
 		goto err_unmap;
 	}
 
-	irq = mc_dev->irqs[0];
-	ptp_qoriq->irq = irq->msi_desc->irq;
+	ptp_qoriq->irq = mc_dev->irqs[0]->virq;
 
 	err = request_threaded_irq(ptp_qoriq->irq, NULL,
 				   dpaa2_ptp_irq_handler_thread,
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
@@ -1553,8 +1553,7 @@ static int dpaa2_switch_setup_irqs(struc
 
 	irq = sw_dev->irqs[DPSW_IRQ_INDEX_IF];
 
-	err = devm_request_threaded_irq(dev, irq->msi_desc->irq,
-					NULL,
+	err = devm_request_threaded_irq(dev, irq->virq, NULL,
 					dpaa2_switch_irq0_handler_thread,
 					IRQF_NO_SUSPEND | IRQF_ONESHOT,
 					dev_name(dev), dev);
@@ -1580,7 +1579,7 @@ static int dpaa2_switch_setup_irqs(struc
 	return 0;
 
 free_devm_irq:
-	devm_free_irq(dev, irq->msi_desc->irq, dev);
+	devm_free_irq(dev, irq->virq, dev);
 free_irq:
 	fsl_mc_free_irqs(sw_dev);
 	return err;
--- a/drivers/soc/fsl/dpio/dpio-driver.c
+++ b/drivers/soc/fsl/dpio/dpio-driver.c
@@ -88,7 +88,7 @@ static void unregister_dpio_irq_handlers
 	irq = dpio_dev->irqs[0];
 
 	/* clear the affinity hint */
-	irq_set_affinity_hint(irq->msi_desc->irq, NULL);
+	irq_set_affinity_hint(irq->virq, NULL);
 }
 
 static int register_dpio_irq_handlers(struct fsl_mc_device *dpio_dev, int cpu)
@@ -98,7 +98,7 @@ static int register_dpio_irq_handlers(st
 
 	irq = dpio_dev->irqs[0];
 	error = devm_request_irq(&dpio_dev->dev,
-				 irq->msi_desc->irq,
+				 irq->virq,
 				 dpio_irq_handler,
 				 0,
 				 dev_name(&dpio_dev->dev),
@@ -111,10 +111,10 @@ static int register_dpio_irq_handlers(st
 	}
 
 	/* set the affinity hint */
-	if (irq_set_affinity_hint(irq->msi_desc->irq, cpumask_of(cpu)))
+	if (irq_set_affinity_hint(irq->virq, cpumask_of(cpu)))
 		dev_err(&dpio_dev->dev,
 			"irq_set_affinity failed irq %d cpu %d\n",
-			irq->msi_desc->irq, cpu);
+			irq->virq, cpu);
 
 	return 0;
 }
--- a/drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c
+++ b/drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c
@@ -67,7 +67,7 @@ static int vfio_set_trigger(struct vfio_
 	int hwirq;
 	int ret;
 
-	hwirq = vdev->mc_dev->irqs[index]->msi_desc->irq;
+	hwirq = vdev->mc_dev->irqs[index]->virq;
 	if (irq->trigger) {
 		free_irq(hwirq, irq);
 		kfree(irq->name);
@@ -137,7 +137,7 @@ static int vfio_fsl_mc_set_irq_trigger(s
 		return vfio_set_trigger(vdev, index, fd);
 	}
 
-	hwirq = vdev->mc_dev->irqs[index]->msi_desc->irq;
+	hwirq = vdev->mc_dev->irqs[index]->virq;
 
 	irq = &vdev->mc_irqs[index];
 
--- a/include/linux/fsl/mc.h
+++ b/include/linux/fsl/mc.h
@@ -91,13 +91,13 @@ struct fsl_mc_resource {
 
 /**
  * struct fsl_mc_device_irq - MC object device message-based interrupt
- * @msi_desc: pointer to MSI descriptor allocated by fsl_mc_msi_alloc_descs()
+ * @virq: Linux virtual interrupt number
  * @mc_dev: MC object device that owns this interrupt
  * @dev_irq_index: device-relative IRQ index
  * @resource: MC generic resource associated with the interrupt
  */
 struct fsl_mc_device_irq {
-	struct msi_desc *msi_desc;
+	unsigned int virq;
 	struct fsl_mc_device *mc_dev;
 	u8 dev_irq_index;
 	struct fsl_mc_resource resource;


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 36/37] soc: ti: ti_sci_inta_msi: Get rid of ti_sci_inta_msi_get_virq()
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (33 preceding siblings ...)
  2021-11-27  1:21 ` [patch 35/37] bus: fsl-mc: fsl-mc-allocator: Rework MSI handling Thomas Gleixner
@ 2021-11-27  1:21 ` Thomas Gleixner
  2021-11-27  1:22   ` Thomas Gleixner
  2021-11-27  1:21 ` [patch 37/37] dmaengine: qcom_hidma: Cleanup MSI handling Thomas Gleixner
                   ` (4 subsequent siblings)
  39 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Just use the core function msi_get_virq().

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/dma/ti/k3-udma-private.c       |    6 ++----
 drivers/dma/ti/k3-udma.c               |   10 ++++------
 drivers/soc/ti/k3-ringacc.c            |    2 +-
 drivers/soc/ti/ti_sci_inta_msi.c       |   12 ------------
 include/linux/soc/ti/ti_sci_inta_msi.h |    1 -
 5 files changed, 7 insertions(+), 24 deletions(-)

--- a/drivers/dma/ti/k3-udma-private.c
+++ b/drivers/dma/ti/k3-udma-private.c
@@ -168,8 +168,7 @@ int xudma_pktdma_tflow_get_irq(struct ud
 {
 	const struct udma_oes_offsets *oes = &ud->soc_data->oes;
 
-	return ti_sci_inta_msi_get_virq(ud->dev, udma_tflow_id +
-					oes->pktdma_tchan_flow);
+	return msi_get_virq(ud->dev, udma_tflow_id + oes->pktdma_tchan_flow);
 }
 EXPORT_SYMBOL(xudma_pktdma_tflow_get_irq);
 
@@ -177,7 +176,6 @@ int xudma_pktdma_rflow_get_irq(struct ud
 {
 	const struct udma_oes_offsets *oes = &ud->soc_data->oes;
 
-	return ti_sci_inta_msi_get_virq(ud->dev, udma_rflow_id +
-					oes->pktdma_rchan_flow);
+	return msi_get_virq(ud->dev, udma_rflow_id + oes->pktdma_rchan_flow);
 }
 EXPORT_SYMBOL(xudma_pktdma_rflow_get_irq);
--- a/drivers/dma/ti/k3-udma.c
+++ b/drivers/dma/ti/k3-udma.c
@@ -2313,8 +2313,7 @@ static int udma_alloc_chan_resources(str
 
 	/* Event from UDMA (TR events) only needed for slave TR mode channels */
 	if (is_slave_direction(uc->config.dir) && !uc->config.pkt_mode) {
-		uc->irq_num_udma = ti_sci_inta_msi_get_virq(ud->dev,
-							    irq_udma_idx);
+		uc->irq_num_udma = msi_get_virq(ud->dev, irq_udma_idx);
 		if (uc->irq_num_udma <= 0) {
 			dev_err(ud->dev, "Failed to get udma irq (index: %u)\n",
 				irq_udma_idx);
@@ -2486,7 +2485,7 @@ static int bcdma_alloc_chan_resources(st
 		uc->psil_paired = true;
 	}
 
-	uc->irq_num_ring = ti_sci_inta_msi_get_virq(ud->dev, irq_ring_idx);
+	uc->irq_num_ring = msi_get_virq(ud->dev, irq_ring_idx);
 	if (uc->irq_num_ring <= 0) {
 		dev_err(ud->dev, "Failed to get ring irq (index: %u)\n",
 			irq_ring_idx);
@@ -2503,8 +2502,7 @@ static int bcdma_alloc_chan_resources(st
 
 	/* Event from BCDMA (TR events) only needed for slave channels */
 	if (is_slave_direction(uc->config.dir)) {
-		uc->irq_num_udma = ti_sci_inta_msi_get_virq(ud->dev,
-							    irq_udma_idx);
+		uc->irq_num_udma = msi_get_virq(ud->dev, irq_udma_idx);
 		if (uc->irq_num_udma <= 0) {
 			dev_err(ud->dev, "Failed to get bcdma irq (index: %u)\n",
 				irq_udma_idx);
@@ -2672,7 +2670,7 @@ static int pktdma_alloc_chan_resources(s
 
 	uc->psil_paired = true;
 
-	uc->irq_num_ring = ti_sci_inta_msi_get_virq(ud->dev, irq_ring_idx);
+	uc->irq_num_ring = msi_get_virq(ud->dev, irq_ring_idx);
 	if (uc->irq_num_ring <= 0) {
 		dev_err(ud->dev, "Failed to get ring irq (index: %u)\n",
 			irq_ring_idx);
--- a/drivers/soc/ti/k3-ringacc.c
+++ b/drivers/soc/ti/k3-ringacc.c
@@ -647,7 +647,7 @@ int k3_ringacc_get_ring_irq_num(struct k
 	if (!ring)
 		return -EINVAL;
 
-	irq_num = ti_sci_inta_msi_get_virq(ring->parent->dev, ring->ring_id);
+	irq_num = msi_get_virq(ring->parent->dev, ring->ring_id);
 	if (irq_num <= 0)
 		irq_num = -EINVAL;
 	return irq_num;
--- a/drivers/soc/ti/ti_sci_inta_msi.c
+++ b/drivers/soc/ti/ti_sci_inta_msi.c
@@ -148,15 +148,3 @@ void ti_sci_inta_msi_domain_free_irqs(st
 	ti_sci_inta_msi_free_descs(dev);
 }
 EXPORT_SYMBOL_GPL(ti_sci_inta_msi_domain_free_irqs);
-
-unsigned int ti_sci_inta_msi_get_virq(struct device *dev, u32 dev_index)
-{
-	struct msi_desc *desc;
-
-	for_each_msi_entry(desc, dev)
-		if (desc->msi_index == dev_index)
-			return desc->irq;
-
-	return -ENODEV;
-}
-EXPORT_SYMBOL_GPL(ti_sci_inta_msi_get_virq);
--- a/include/linux/soc/ti/ti_sci_inta_msi.h
+++ b/include/linux/soc/ti/ti_sci_inta_msi.h
@@ -18,6 +18,5 @@ struct irq_domain
 				   struct irq_domain *parent);
 int ti_sci_inta_msi_domain_alloc_irqs(struct device *dev,
 				      struct ti_sci_resource *res);
-unsigned int ti_sci_inta_msi_get_virq(struct device *dev, u32 index);
 void ti_sci_inta_msi_domain_free_irqs(struct device *dev);
 #endif /* __INCLUDE_LINUX_IRQCHIP_TI_SCI_INTA_H */


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 37/37] dmaengine: qcom_hidma: Cleanup MSI handling
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (34 preceding siblings ...)
  2021-11-27  1:21 ` [patch 36/37] soc: ti: ti_sci_inta_msi: Get rid of ti_sci_inta_msi_get_virq() Thomas Gleixner
@ 2021-11-27  1:21 ` Thomas Gleixner
  2021-11-27  1:22   ` Thomas Gleixner
  2021-11-29 19:56   ` Sinan Kaya
  2021-11-27  1:21 ` [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (3 subsequent siblings)
  39 siblings, 2 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Sinan Kaya, dmaengine, Santosh Shilimkar,
	iommu, Stuart Yoder, Laurentiu Tudor, Nishanth Menon,
	Tero Kristo, linux-arm-kernel, x86, Vinod Koul, Mark Rutland,
	Will Deacon

There is no reason to walk the MSI descriptors to retrieve the interrupt
number for a device. Use msi_get_virq() instead.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Sinan Kaya <okaya@kernel.org>
Cc: dmaengine@vger.kernel.org
---
 drivers/dma/qcom/hidma.c |   42 ++++++++++++++++++------------------------
 1 file changed, 18 insertions(+), 24 deletions(-)

--- a/drivers/dma/qcom/hidma.c
+++ b/drivers/dma/qcom/hidma.c
@@ -678,11 +678,13 @@ static void hidma_free_msis(struct hidma
 {
 #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
 	struct device *dev = dmadev->ddev.dev;
-	struct msi_desc *desc;
+	int i, virq;
 
-	/* free allocated MSI interrupts above */
-	for_each_msi_entry(desc, dev)
-		devm_free_irq(dev, desc->irq, &dmadev->lldev);
+	for (i = 0; i < HIDMA_MSI_INTS; i++) {
+		virq = msi_get_virq(dev, i);
+		if (virq)
+			devm_free_irq(dev, virq, &dmadev->lldev);
+	}
 
 	platform_msi_domain_free_irqs(dev);
 #endif
@@ -692,45 +694,37 @@ static int hidma_request_msi(struct hidm
 			     struct platform_device *pdev)
 {
 #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
-	int rc;
-	struct msi_desc *desc;
-	struct msi_desc *failed_desc = NULL;
+	int rc, i, virq;
 
 	rc = platform_msi_domain_alloc_irqs(&pdev->dev, HIDMA_MSI_INTS,
 					    hidma_write_msi_msg);
 	if (rc)
 		return rc;
 
-	for_each_msi_entry(desc, &pdev->dev) {
-		if (!desc->msi_index)
-			dmadev->msi_virqbase = desc->irq;
-
-		rc = devm_request_irq(&pdev->dev, desc->irq,
+	for (i = 0; i < HIDMA_MSI_INTS; i++) {
+		virq = msi_get_virq(&pdev->dev, i);
+		rc = devm_request_irq(&pdev->dev, virq,
 				       hidma_chirq_handler_msi,
 				       0, "qcom-hidma-msi",
 				       &dmadev->lldev);
-		if (rc) {
-			failed_desc = desc;
+		if (rc)
 			break;
-		}
+		if (!i)
+			dmadev->msi_virqbase = virq;
 	}
 
 	if (rc) {
 		/* free allocated MSI interrupts above */
-		for_each_msi_entry(desc, &pdev->dev) {
-			if (desc == failed_desc)
-				break;
-			devm_free_irq(&pdev->dev, desc->irq,
-				      &dmadev->lldev);
+		for (--i; i >= 0; i--) {
+			virq = msi_get_virq(&pdev->dev, i);
+			devm_free_irq(&pdev->dev, virq, &dmadev->lldev);
 		}
+		dev_warn(&pdev->dev,
+			 "failed to request MSI irq, falling back to wired IRQ\n");
 	} else {
 		/* Add callback to free MSIs on teardown */
 		hidma_ll_setup_irq(dmadev->lldev, true);
-
 	}
-	if (rc)
-		dev_warn(&pdev->dev,
-			 "failed to request MSI irq, falling back to wired IRQ\n");
 	return rc;
 #else
 	return -EINVAL;


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (35 preceding siblings ...)
  2021-11-27  1:21 ` [patch 37/37] dmaengine: qcom_hidma: Cleanup MSI handling Thomas Gleixner
@ 2021-11-27  1:21 ` Thomas Gleixner
  2021-11-27  1:21 ` [patch 04/37] PCI/MSI: Use lock from msi_device_data Thomas Gleixner
                   ` (2 subsequent siblings)
  39 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

This is the second part of [PCI]MSI refactoring which aims to provide the
ability of expanding MSI-X vectors after enabling MSI-X.

The first part of this work can be found here:

    https://lore.kernel.org/r/20211126222700.862407977@linutronix.de

This second part has the following important changes:

   1) Cleanup of the MSI related data in struct device

      struct device contains at the moment various MSI related parts. Some
      of them (the irq domain pointer) cannot be moved out, but the rest
      can be allocated on first use. This is in preparation of adding more
      per device MSI data later on.

   2) Consolidation of sysfs handling

      As a first step this moves the sysfs pointer from struct msi_desc
      into the new per device MSI data structure where it belongs.

      Later changes will cleanup this code further, but that's not possible
      at this point.

   3) Store per device properties in the per device MSI data to avoid
      looking up MSI descriptors and analysing their data. Cleanup all
      related use cases.

   4) Provide a function to retrieve the Linux interrupt number for a given
      MSI index similar to pci_irq_vector() and cleanup all open coded
      variants.

The series is based on:

     git://git.kernel.org/pub/scm/linux/kernel/git/tglx/devel.git msi-v1-part-1

and also available from git:

     git://git.kernel.org/pub/scm/linux/kernel/git/tglx/devel.git msi-v1-part-2

For the curious who can't wait for the next part to arrive the full series
is available via:

     git://git.kernel.org/pub/scm/linux/kernel/git/tglx/devel.git msi-v1-part-4

Thanks,

	tglx
---
 arch/powerpc/platforms/cell/axon_msi.c              |    6 
 arch/powerpc/platforms/pseries/msi.c                |   38 +---
 arch/x86/kernel/apic/msi.c                          |    5 
 arch/x86/pci/xen.c                                  |    8 
 drivers/base/core.c                                 |    1 
 drivers/base/platform-msi.c                         |  152 ++++++++---------
 drivers/bus/fsl-mc/dprc-driver.c                    |    8 
 drivers/bus/fsl-mc/fsl-mc-allocator.c               |    9 -
 drivers/bus/fsl-mc/fsl-mc-msi.c                     |   26 +--
 drivers/dma/mv_xor_v2.c                             |   16 -
 drivers/dma/qcom/hidma.c                            |   44 ++---
 drivers/dma/ti/k3-udma-private.c                    |    6 
 drivers/dma/ti/k3-udma.c                            |   14 -
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c         |   23 --
 drivers/irqchip/irq-mbigen.c                        |    4 
 drivers/irqchip/irq-mvebu-icu.c                     |   12 -
 drivers/irqchip/irq-ti-sci-inta.c                   |    2 
 drivers/mailbox/bcm-flexrm-mailbox.c                |    9 -
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c    |    4 
 drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c    |    4 
 drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c |    5 
 drivers/pci/msi/irqdomain.c                         |   20 +-
 drivers/pci/msi/legacy.c                            |    6 
 drivers/pci/msi/msi.c                               |  118 +++++--------
 drivers/pci/xen-pcifront.c                          |    2 
 drivers/perf/arm_smmuv3_pmu.c                       |    5 
 drivers/soc/fsl/dpio/dpio-driver.c                  |    8 
 drivers/soc/ti/k3-ringacc.c                         |    6 
 drivers/soc/ti/ti_sci_inta_msi.c                    |   22 --
 drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c              |    4 
 include/linux/device.h                              |   26 ++-
 include/linux/fsl/mc.h                              |    4 
 include/linux/msi.h                                 |  118 +++++++------
 include/linux/pci.h                                 |    1 
 include/linux/soc/ti/ti_sci_inta_msi.h              |    1 
 kernel/irq/msi.c                                    |  171 +++++++++++++++-----
 36 files changed, 463 insertions(+), 445 deletions(-)

^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 01/37] device: Move MSI related data into a struct
  2021-11-27  1:20 ` [patch 01/37] device: Move MSI related data into a struct Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27 12:11   ` Greg Kroah-Hartman
  1 sibling, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

The only unconditional part of MSI data in struct device is the irqdomain
pointer. Everything else can be allocated on demand. Create a data
structure and move the irqdomain pointer into it. The other MSI specific
parts are going to be removed from struct device in later steps.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Will Deacon <will@kernel.org>
Cc: Santosh Shilimkar <ssantosh@kernel.org>
Cc: iommu@lists.linux-foundation.org
Cc: dmaengine@vger.kernel.org
---
 drivers/base/platform-msi.c                 |   12 ++++++------
 drivers/dma/ti/k3-udma.c                    |    4 ++--
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |    2 +-
 drivers/irqchip/irq-mvebu-icu.c             |    6 +++---
 drivers/soc/ti/k3-ringacc.c                 |    4 ++--
 drivers/soc/ti/ti_sci_inta_msi.c            |    2 +-
 include/linux/device.h                      |   19 +++++++++++++------
 7 files changed, 28 insertions(+), 21 deletions(-)

--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -210,10 +210,10 @@ platform_msi_alloc_priv_data(struct devi
 	 * accordingly (which would impact the max number of MSI
 	 * capable devices).
 	 */
-	if (!dev->msi_domain || !write_msi_msg || !nvec || nvec > MAX_DEV_MSIS)
+	if (!dev->msi.domain || !write_msi_msg || !nvec || nvec > MAX_DEV_MSIS)
 		return ERR_PTR(-EINVAL);
 
-	if (dev->msi_domain->bus_token != DOMAIN_BUS_PLATFORM_MSI) {
+	if (dev->msi.domain->bus_token != DOMAIN_BUS_PLATFORM_MSI) {
 		dev_err(dev, "Incompatible msi_domain, giving up\n");
 		return ERR_PTR(-EINVAL);
 	}
@@ -269,7 +269,7 @@ int platform_msi_domain_alloc_irqs(struc
 	if (err)
 		goto out_free_priv_data;
 
-	err = msi_domain_alloc_irqs(dev->msi_domain, dev, nvec);
+	err = msi_domain_alloc_irqs(dev->msi.domain, dev, nvec);
 	if (err)
 		goto out_free_desc;
 
@@ -282,7 +282,7 @@ int platform_msi_domain_alloc_irqs(struc
 	return 0;
 
 out_free_irqs:
-	msi_domain_free_irqs(dev->msi_domain, dev);
+	msi_domain_free_irqs(dev->msi.domain, dev);
 out_free_desc:
 	platform_msi_free_descs(dev, 0, nvec);
 out_free_priv_data:
@@ -306,7 +306,7 @@ void platform_msi_domain_free_irqs(struc
 		platform_msi_free_priv_data(desc->platform.msi_priv_data);
 	}
 
-	msi_domain_free_irqs(dev->msi_domain, dev);
+	msi_domain_free_irqs(dev->msi.domain, dev);
 	platform_msi_free_descs(dev, 0, MAX_DEV_MSIS);
 }
 EXPORT_SYMBOL_GPL(platform_msi_domain_free_irqs);
@@ -354,7 +354,7 @@ struct irq_domain *
 		return NULL;
 
 	data->host_data = host_data;
-	domain = irq_domain_create_hierarchy(dev->msi_domain, 0,
+	domain = irq_domain_create_hierarchy(dev->msi.domain, 0,
 					     is_tree ? 0 : nvec,
 					     dev->fwnode, ops, data);
 	if (!domain)
--- a/drivers/dma/ti/k3-udma.c
+++ b/drivers/dma/ti/k3-udma.c
@@ -5279,9 +5279,9 @@ static int udma_probe(struct platform_de
 	if (IS_ERR(ud->ringacc))
 		return PTR_ERR(ud->ringacc);
 
-	dev->msi_domain = of_msi_get_domain(dev, dev->of_node,
+	dev->msi.domain = of_msi_get_domain(dev, dev->of_node,
 					    DOMAIN_BUS_TI_SCI_INTA_MSI);
-	if (!dev->msi_domain) {
+	if (!dev->msi.domain) {
 		dev_err(dev, "Failed to get MSI domain\n");
 		return -EPROBE_DEFER;
 	}
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3170,7 +3170,7 @@ static void arm_smmu_setup_msis(struct a
 	if (!(smmu->features & ARM_SMMU_FEAT_MSI))
 		return;
 
-	if (!dev->msi_domain) {
+	if (!dev->msi.domain) {
 		dev_info(smmu->dev, "msi_domain absent - falling back to wired irqs\n");
 		return;
 	}
--- a/drivers/irqchip/irq-mvebu-icu.c
+++ b/drivers/irqchip/irq-mvebu-icu.c
@@ -314,12 +314,12 @@ static int mvebu_icu_subset_probe(struct
 		msi_data->subset_data = of_device_get_match_data(dev);
 	}
 
-	dev->msi_domain = of_msi_get_domain(dev, dev->of_node,
+	dev->msi.domain = of_msi_get_domain(dev, dev->of_node,
 					    DOMAIN_BUS_PLATFORM_MSI);
-	if (!dev->msi_domain)
+	if (!dev->msi.domain)
 		return -EPROBE_DEFER;
 
-	msi_parent_dn = irq_domain_get_of_node(dev->msi_domain);
+	msi_parent_dn = irq_domain_get_of_node(dev->msi.domain);
 	if (!msi_parent_dn)
 		return -ENODEV;
 
--- a/drivers/soc/ti/k3-ringacc.c
+++ b/drivers/soc/ti/k3-ringacc.c
@@ -1356,9 +1356,9 @@ static int k3_ringacc_init(struct platfo
 	struct resource *res;
 	int ret, i;
 
-	dev->msi_domain = of_msi_get_domain(dev, dev->of_node,
+	dev->msi.domain = of_msi_get_domain(dev, dev->of_node,
 					    DOMAIN_BUS_TI_SCI_INTA_MSI);
-	if (!dev->msi_domain) {
+	if (!dev->msi.domain) {
 		dev_err(dev, "Failed to get MSI domain\n");
 		return -EPROBE_DEFER;
 	}
--- a/drivers/soc/ti/ti_sci_inta_msi.c
+++ b/drivers/soc/ti/ti_sci_inta_msi.c
@@ -140,7 +140,7 @@ EXPORT_SYMBOL_GPL(ti_sci_inta_msi_domain
 
 void ti_sci_inta_msi_domain_free_irqs(struct device *dev)
 {
-	msi_domain_free_irqs(dev->msi_domain, dev);
+	msi_domain_free_irqs(dev->msi.domain, dev);
 	ti_sci_inta_msi_free_descs(dev);
 }
 EXPORT_SYMBOL_GPL(ti_sci_inta_msi_domain_free_irqs);
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -372,6 +372,16 @@ struct dev_links_info {
 };
 
 /**
+ * struct dev_msi_info - Device data related to MSI
+ * @domain:	The MSI interrupt domain associated to the device
+ */
+struct dev_msi_info {
+#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
+	struct irq_domain	*domain;
+#endif
+};
+
+/**
  * struct device - The basic device structure
  * @parent:	The device's "parent" device, the device to which it is attached.
  * 		In most cases, a parent device is some sort of bus or host
@@ -409,7 +419,6 @@ struct dev_links_info {
  *		See Documentation/driver-api/pin-control.rst for details.
  * @msi_lock:	Lock to protect MSI mask cache and mask register
  * @msi_list:	Hosts MSI descriptors
- * @msi_domain: The generic MSI domain this device is using.
  * @numa_node:	NUMA node this device is close to.
  * @dma_ops:    DMA mapping operations for this device.
  * @dma_mask:	Dma mask (if dma'ble device).
@@ -501,12 +510,10 @@ struct device {
 	struct em_perf_domain	*em_pd;
 #endif
 
-#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
-	struct irq_domain	*msi_domain;
-#endif
 #ifdef CONFIG_PINCTRL
 	struct dev_pin_info	*pins;
 #endif
+	struct dev_msi_info	msi;
 #ifdef CONFIG_GENERIC_MSI_IRQ
 	raw_spinlock_t		msi_lock;
 	struct list_head	msi_list;
@@ -668,7 +675,7 @@ static inline void set_dev_node(struct d
 static inline struct irq_domain *dev_get_msi_domain(const struct device *dev)
 {
 #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
-	return dev->msi_domain;
+	return dev->msi.domain;
 #else
 	return NULL;
 #endif
@@ -677,7 +684,7 @@ static inline struct irq_domain *dev_get
 static inline void dev_set_msi_domain(struct device *dev, struct irq_domain *d)
 {
 #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
-	dev->msi_domain = d;
+	dev->msi.domain = d;
 #endif
 }
 


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 02/37] device: Add device::msi_data pointer and struct msi_device_data
  2021-11-27  1:20 ` [patch 02/37] device: Add device::msi_data pointer and struct msi_device_data Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27 12:12   ` Greg Kroah-Hartman
  2021-11-28  0:14   ` Jason Gunthorpe
  2 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Create struct msi_device_data and add a pointer of that type to struct
dev_msi_info, which is part of struct device. Provide an allocator function
which can be invoked from the MSI interrupt allocation code pathes.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/device.h |    5 +++++
 include/linux/msi.h    |   12 +++++++++++-
 kernel/irq/msi.c       |   33 +++++++++++++++++++++++++++++++++
 3 files changed, 49 insertions(+), 1 deletion(-)

--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -45,6 +45,7 @@ struct iommu_ops;
 struct iommu_group;
 struct dev_pin_info;
 struct dev_iommu;
+struct msi_device_data;
 
 /**
  * struct subsys_interface - interfaces to device functions
@@ -374,11 +375,15 @@ struct dev_links_info {
 /**
  * struct dev_msi_info - Device data related to MSI
  * @domain:	The MSI interrupt domain associated to the device
+ * @data:	Pointer to MSI device data
  */
 struct dev_msi_info {
 #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
 	struct irq_domain	*domain;
 #endif
+#ifdef CONFIG_GENERIC_MSI_IRQ
+	struct msi_device_data	*data;
+#endif
 };
 
 /**
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -2,6 +2,7 @@
 #ifndef LINUX_MSI_H
 #define LINUX_MSI_H
 
+#include <linux/spinlock.h>
 #include <linux/list.h>
 #include <asm/msi.h>
 
@@ -170,6 +171,16 @@ struct msi_desc {
 	};
 };
 
+/**
+ * msi_device_data - MSI per device data
+ * @lock:		Spinlock to protect register access
+ */
+struct msi_device_data {
+	raw_spinlock_t		lock;
+};
+
+int msi_setup_device_data(struct device *dev);
+
 /* Helpers to hide struct msi_desc implementation details */
 #define msi_desc_to_dev(desc)		((desc)->dev)
 #define dev_to_msi_list(dev)		(&(dev)->msi_list)
@@ -185,7 +196,6 @@ struct msi_desc {
 			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)
 {
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -73,6 +73,39 @@ void get_cached_msi_msg(unsigned int irq
 }
 EXPORT_SYMBOL_GPL(get_cached_msi_msg);
 
+static void msi_device_data_release(struct device *dev, void *res)
+{
+	WARN_ON_ONCE(!list_empty(&dev->msi_list));
+	dev->msi.data = NULL;
+}
+
+/**
+ * msi_setup_device_data - Setup MSI device data
+ * @dev:	Device for which MSI device data should be set up
+ *
+ * Return: 0 on success, appropriate error code otherwise
+ *
+ * This can be called more than once for @dev. If the MSI device data is
+ * already allocated the call succeeds. The allocated memory is
+ * automatically released when the device is destroyed.
+ */
+int msi_setup_device_data(struct device *dev)
+{
+	struct msi_device_data *md;
+
+	if (dev->msi.data)
+		return 0;
+
+	md = devres_alloc(msi_device_data_release, sizeof(*md), GFP_KERNEL);
+	if (!md)
+		return -ENOMEM;
+
+	raw_spin_lock_init(&md->lock);
+	dev->msi.data = md;
+	devres_add(dev, md);
+	return 0;
+}
+
 #ifdef CONFIG_SYSFS
 static ssize_t msi_mode_show(struct device *dev, struct device_attribute *attr,
 			     char *buf)


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 03/37] PCI/MSI: Allocate MSI device data on first use
  2021-11-27  1:20 ` [patch 03/37] PCI/MSI: Allocate MSI device data on first use Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Allocate MSI device data on first use, i.e. when a PCI driver invokes one
of the PCI/MSI enablement functions.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/pci/msi/msi.c |   20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -889,10 +889,12 @@ static int __pci_enable_msi_range(struct
 /* deprecated, don't use */
 int pci_enable_msi(struct pci_dev *dev)
 {
-	int rc = __pci_enable_msi_range(dev, 1, 1, NULL);
-	if (rc < 0)
-		return rc;
-	return 0;
+	int rc = msi_setup_device_data(&dev->dev);
+
+	if (!rc)
+		rc = __pci_enable_msi_range(dev, 1, 1, NULL);
+
+	return rc < 0 ? rc : 0;
 }
 EXPORT_SYMBOL(pci_enable_msi);
 
@@ -947,7 +949,11 @@ static int __pci_enable_msix_range(struc
 int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries,
 		int minvec, int maxvec)
 {
-	return __pci_enable_msix_range(dev, entries, minvec, maxvec, NULL, 0);
+	int ret = msi_setup_device_data(&dev->dev);
+
+	if (!ret)
+		ret = __pci_enable_msix_range(dev, entries, minvec, maxvec, NULL, 0);
+	return ret;
 }
 EXPORT_SYMBOL(pci_enable_msix_range);
 
@@ -974,8 +980,12 @@ int pci_alloc_irq_vectors_affinity(struc
 				   struct irq_affinity *affd)
 {
 	struct irq_affinity msi_default_affd = {0};
+	int ret = msi_setup_device_data(&dev->dev);
 	int nvecs = -ENOSPC;
 
+	if (ret)
+		return ret;
+
 	if (flags & PCI_IRQ_AFFINITY) {
 		if (!affd)
 			affd = &msi_default_affd;


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 04/37] PCI/MSI: Use lock from msi_device_data
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (36 preceding siblings ...)
  2021-11-27  1:21 ` [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
@ 2021-11-27  1:21 ` Thomas Gleixner
  2021-11-27  1:20   ` Thomas Gleixner
  2021-11-27 12:13   ` Greg Kroah-Hartman
  2021-11-27 12:17 ` [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Greg Kroah-Hartman
  2021-11-28  0:39 ` Jason Gunthorpe
  39 siblings, 2 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Remove the register lock from struct device and use the one in
struct msi_device_data.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/base/core.c    |    1 -
 drivers/pci/msi/msi.c  |    2 +-
 include/linux/device.h |    2 --
 3 files changed, 1 insertion(+), 4 deletions(-)

--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -2875,7 +2875,6 @@ void device_initialize(struct device *de
 	device_pm_init(dev);
 	set_dev_node(dev, NUMA_NO_NODE);
 #ifdef CONFIG_GENERIC_MSI_IRQ
-	raw_spin_lock_init(&dev->msi_lock);
 	INIT_LIST_HEAD(&dev->msi_list);
 #endif
 	INIT_LIST_HEAD(&dev->links.consumers);
--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -18,7 +18,7 @@ int pci_msi_ignore_mask;
 
 static noinline void pci_msi_update_mask(struct msi_desc *desc, u32 clear, u32 set)
 {
-	raw_spinlock_t *lock = &desc->dev->msi_lock;
+	raw_spinlock_t *lock = &desc->dev->msi.data->lock;
 	unsigned long flags;
 
 	if (!desc->pci.msi_attrib.can_mask)
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -422,7 +422,6 @@ struct dev_msi_info {
  * @em_pd:	device's energy model performance domain
  * @pins:	For device pin management.
  *		See Documentation/driver-api/pin-control.rst for details.
- * @msi_lock:	Lock to protect MSI mask cache and mask register
  * @msi_list:	Hosts MSI descriptors
  * @numa_node:	NUMA node this device is close to.
  * @dma_ops:    DMA mapping operations for this device.
@@ -520,7 +519,6 @@ struct device {
 #endif
 	struct dev_msi_info	msi;
 #ifdef CONFIG_GENERIC_MSI_IRQ
-	raw_spinlock_t		msi_lock;
 	struct list_head	msi_list;
 #endif
 #ifdef CONFIG_DMA_OPS


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 05/37] platform-msi: Allocate MSI device data on first use
  2021-11-27  1:20 ` [patch 05/37] platform-msi: " Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Allocate the MSI device data on first invocation of the allocation function
for platform MSI private data.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/base/platform-msi.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -204,6 +204,8 @@ platform_msi_alloc_priv_data(struct devi
 			     irq_write_msi_msg_t write_msi_msg)
 {
 	struct platform_msi_priv_data *datap;
+	int err;
+
 	/*
 	 * Limit the number of interrupts to 2048 per device. Should we
 	 * need to bump this up, DEV_ID_SHIFT should be adjusted
@@ -218,6 +220,10 @@ platform_msi_alloc_priv_data(struct devi
 		return ERR_PTR(-EINVAL);
 	}
 
+	err = msi_setup_device_data(dev);
+	if (err)
+		return ERR_PTR(err);
+
 	/* Already had a helping of MSI? Greed... */
 	if (!list_empty(dev_to_msi_list(dev)))
 		return ERR_PTR(-EBUSY);
@@ -229,7 +235,7 @@ platform_msi_alloc_priv_data(struct devi
 	datap->devid = ida_simple_get(&platform_msi_devid_ida,
 				      0, 1 << DEV_ID_SHIFT, GFP_KERNEL);
 	if (datap->devid < 0) {
-		int err = datap->devid;
+		err = datap->devid;
 		kfree(datap);
 		return ERR_PTR(err);
 	}


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 06/37] bus: fsl-mc-msi: Allocate MSI device data on first use
  2021-11-27  1:20 ` [patch 06/37] bus: fsl-mc-msi: " Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Stuart Yoder, Laurentiu Tudor,
	Santosh Shilimkar, iommu, dmaengine, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Allocate the MSI device data on first invocation of the allocation function.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Stuart Yoder <stuyoder@gmail.com>
Cc: Laurentiu Tudor <laurentiu.tudor@nxp.com>
---
 drivers/bus/fsl-mc/fsl-mc-msi.c |   14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

--- a/drivers/bus/fsl-mc/fsl-mc-msi.c
+++ b/drivers/bus/fsl-mc/fsl-mc-msi.c
@@ -253,6 +253,14 @@ int fsl_mc_msi_domain_alloc_irqs(struct
 	struct irq_domain *msi_domain;
 	int error;
 
+	msi_domain = dev_get_msi_domain(dev);
+	if (!msi_domain)
+		return -EINVAL;
+
+	error = msi_setup_device_data(dev);
+	if (error)
+		return error;
+
 	if (!list_empty(dev_to_msi_list(dev)))
 		return -EINVAL;
 
@@ -260,12 +268,6 @@ int fsl_mc_msi_domain_alloc_irqs(struct
 	if (error < 0)
 		return error;
 
-	msi_domain = dev_get_msi_domain(dev);
-	if (!msi_domain) {
-		error = -EINVAL;
-		goto cleanup_msi_descs;
-	}
-
 	/*
 	 * NOTE: Calling this function will trigger the invocation of the
 	 * its_fsl_mc_msi_prepare() callback


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 07/37] soc: ti: ti_sci_inta_msi: Allocate MSI device data on first use
  2021-11-27  1:20 ` [patch 07/37] soc: ti: ti_sci_inta_msi: " Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Nishanth Menon, Tero Kristo,
	Santosh Shilimkar, linux-arm-kernel, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, x86, Vinod Koul, Mark Rutland,
	Will Deacon, Sinan Kaya

Allocate the MSI device data on first invocation of the allocation function.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Nishanth Menon <nm@ti.com>
Cc: Tero Kristo <kristo@kernel.org>
Cc: Santosh Shilimkar <ssantosh@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
---
 drivers/soc/ti/ti_sci_inta_msi.c |    4 ++++
 1 file changed, 4 insertions(+)

--- a/drivers/soc/ti/ti_sci_inta_msi.c
+++ b/drivers/soc/ti/ti_sci_inta_msi.c
@@ -120,6 +120,10 @@ int ti_sci_inta_msi_domain_alloc_irqs(st
 	if (pdev->id < 0)
 		return -ENODEV;
 
+	ret = msi_setup_device_data(dev);
+	if (ret)
+		return ret;
+
 	nvec = ti_sci_inta_msi_alloc_descs(dev, res);
 	if (nvec <= 0)
 		return nvec;


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 08/37] genirq/msi: Provide msi_device_populate/destroy_sysfs()
  2021-11-27  1:20 ` [patch 08/37] genirq/msi: Provide msi_device_populate/destroy_sysfs() Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  2021-11-30 11:53   ` Jonathan Cameron
  1 sibling, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Add new allocation functions which can be activated by domain info
flags. They store the groups pointer in struct msi_device_data.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/msi.h |   12 +++++++++++-
 kernel/irq/msi.c    |   42 ++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 51 insertions(+), 3 deletions(-)

--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -174,9 +174,11 @@ struct msi_desc {
 /**
  * msi_device_data - MSI per device data
  * @lock:		Spinlock to protect register access
+ * @attrs:		Pointer to the sysfs attribute group
  */
 struct msi_device_data {
-	raw_spinlock_t		lock;
+	raw_spinlock_t			lock;
+	const struct attribute_group    **attrs;
 };
 
 int msi_setup_device_data(struct device *dev);
@@ -242,10 +244,16 @@ void pci_msi_mask_irq(struct irq_data *d
 void pci_msi_unmask_irq(struct irq_data *data);
 
 #ifdef CONFIG_SYSFS
+int msi_device_populate_sysfs(struct device *dev);
+void msi_device_destroy_sysfs(struct device *dev);
+
 const struct attribute_group **msi_populate_sysfs(struct device *dev);
 void msi_destroy_sysfs(struct device *dev,
 		       const struct attribute_group **msi_irq_groups);
 #else
+static inline int msi_device_populate_sysfs(struct device *dev) { return 0; }
+static inline void msi_device_destroy_sysfs(struct device *dev) { }
+
 static inline const struct attribute_group **msi_populate_sysfs(struct device *dev)
 {
 	return NULL;
@@ -393,6 +401,8 @@ enum {
 	MSI_FLAG_MUST_REACTIVATE	= (1 << 5),
 	/* Is level-triggered capable, using two messages */
 	MSI_FLAG_LEVEL_CAPABLE		= (1 << 6),
+	/* Populate sysfs on alloc() and destroy it on free() */
+	MSI_FLAG_DEV_SYSFS		= (1 << 7),
 };
 
 int msi_domain_set_affinity(struct irq_data *data, const struct cpumask *mask,
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -214,6 +214,20 @@ const struct attribute_group **msi_popul
 }
 
 /**
+ * msi_device_populate_sysfs - Populate msi_irqs sysfs entries for a device
+ * @dev:	The device(PCI, platform etc) which will get sysfs entries
+ */
+int msi_device_populate_sysfs(struct device *dev)
+{
+	const struct attribute_group **group = msi_populate_sysfs(dev);
+
+	if (IS_ERR(group))
+		return PTR_ERR(group);
+	dev->msi.data->attrs = group;
+	return 0;
+}
+
+/**
  * msi_destroy_sysfs - Destroy msi_irqs sysfs entries for devices
  * @dev:		The device(PCI, platform etc) who will remove sysfs entries
  * @msi_irq_groups:	attribute_group for device msi_irqs entries
@@ -239,6 +253,17 @@ void msi_destroy_sysfs(struct device *de
 		kfree(msi_irq_groups);
 	}
 }
+
+/**
+ * msi_device_destroy_sysfs - Destroy msi_irqs sysfs entries for a device
+ * @dev:		The device(PCI, platform etc) for which to remove
+ *			sysfs entries
+ */
+void msi_device_destroy_sysfs(struct device *dev)
+{
+	msi_destroy_sysfs(dev, dev->msi.data->attrs);
+	dev->msi.data->attrs = NULL;
+}
 #endif
 
 #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
@@ -686,8 +711,19 @@ int msi_domain_alloc_irqs(struct irq_dom
 {
 	struct msi_domain_info *info = domain->host_data;
 	struct msi_domain_ops *ops = info->ops;
+	int ret;
 
-	return ops->domain_alloc_irqs(domain, dev, nvec);
+	ret = ops->domain_alloc_irqs(domain, dev, nvec);
+	if (ret)
+		return ret;
+
+	if (!(info->flags & MSI_FLAG_DEV_SYSFS))
+		return 0;
+
+	ret = msi_device_populate_sysfs(dev);
+	if (ret)
+		msi_domain_free_irqs(domain, dev);
+	return ret;
 }
 
 void __msi_domain_free_irqs(struct irq_domain *domain, struct device *dev)
@@ -726,7 +762,9 @@ void msi_domain_free_irqs(struct irq_dom
 	struct msi_domain_info *info = domain->host_data;
 	struct msi_domain_ops *ops = info->ops;
 
-	return ops->domain_free_irqs(domain, dev);
+	if (info->flags & MSI_FLAG_DEV_SYSFS)
+		msi_device_destroy_sysfs(dev);
+	ops->domain_free_irqs(domain, dev);
 }
 
 /**


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 09/37] PCI/MSI: Let the irq code handle sysfs groups
  2021-11-27  1:20 ` [patch 09/37] PCI/MSI: Let the irq code handle sysfs groups Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Set the domain info flag which makes the core code handle sysfs groups and
put an explicit invocation into the legacy code.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/pci/msi/irqdomain.c |    2 +-
 drivers/pci/msi/legacy.c    |    6 +++++-
 drivers/pci/msi/msi.c       |   23 -----------------------
 include/linux/pci.h         |    1 -
 4 files changed, 6 insertions(+), 26 deletions(-)

--- a/drivers/pci/msi/irqdomain.c
+++ b/drivers/pci/msi/irqdomain.c
@@ -159,7 +159,7 @@ struct irq_domain *pci_msi_create_irq_do
 	if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS)
 		pci_msi_domain_update_chip_ops(info);
 
-	info->flags |= MSI_FLAG_ACTIVATE_EARLY;
+	info->flags |= MSI_FLAG_ACTIVATE_EARLY | MSI_FLAG_DEV_SYSFS;
 	if (IS_ENABLED(CONFIG_GENERIC_IRQ_RESERVATION_MODE))
 		info->flags |= MSI_FLAG_MUST_REACTIVATE;
 
--- a/drivers/pci/msi/legacy.c
+++ b/drivers/pci/msi/legacy.c
@@ -71,10 +71,14 @@ int pci_msi_legacy_setup_msi_irqs(struct
 {
 	int ret = arch_setup_msi_irqs(dev, nvec, type);
 
-	return pci_msi_setup_check_result(dev, type, ret);
+	ret = pci_msi_setup_check_result(dev, type, ret);
+	if (!ret)
+		ret = msi_device_populate_sysfs(&dev->dev);
+	return ret;
 }
 
 void pci_msi_legacy_teardown_msi_irqs(struct pci_dev *dev)
 {
+	msi_device_destroy_sysfs(&dev->dev);
 	arch_teardown_msi_irqs(dev);
 }
--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -233,11 +233,6 @@ static void free_msi_irqs(struct pci_dev
 			for (i = 0; i < entry->nvec_used; i++)
 				BUG_ON(irq_has_action(entry->irq + i));
 
-	if (dev->msi_irq_groups) {
-		msi_destroy_sysfs(&dev->dev, dev->msi_irq_groups);
-		dev->msi_irq_groups = NULL;
-	}
-
 	pci_msi_teardown_msi_irqs(dev);
 
 	list_for_each_entry_safe(entry, tmp, msi_list, list) {
@@ -415,7 +410,6 @@ static int msi_verify_entries(struct pci
 static int msi_capability_init(struct pci_dev *dev, int nvec,
 			       struct irq_affinity *affd)
 {
-	const struct attribute_group **groups;
 	struct msi_desc *entry;
 	int ret;
 
@@ -439,14 +433,6 @@ static int msi_capability_init(struct pc
 	if (ret)
 		goto err;
 
-	groups = msi_populate_sysfs(&dev->dev);
-	if (IS_ERR(groups)) {
-		ret = PTR_ERR(groups);
-		goto err;
-	}
-
-	dev->msi_irq_groups = groups;
-
 	/* Set MSI enabled bits	*/
 	pci_intx_for_msi(dev, 0);
 	pci_msi_set_enable(dev, 1);
@@ -574,7 +560,6 @@ static void msix_mask_all(void __iomem *
 static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries,
 				int nvec, struct irq_affinity *affd)
 {
-	const struct attribute_group **groups;
 	void __iomem *base;
 	int ret, tsize;
 	u16 control;
@@ -616,14 +601,6 @@ static int msix_capability_init(struct p
 
 	msix_update_entries(dev, entries);
 
-	groups = msi_populate_sysfs(&dev->dev);
-	if (IS_ERR(groups)) {
-		ret = PTR_ERR(groups);
-		goto out_free;
-	}
-
-	dev->msi_irq_groups = groups;
-
 	/* Set MSI-X enabled bits and unmask the function */
 	pci_intx_for_msi(dev, 0);
 	dev->msix_enabled = 1;
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -474,7 +474,6 @@ struct pci_dev {
 #endif
 #ifdef CONFIG_PCI_MSI
 	void __iomem	*msix_base;
-	const struct attribute_group **msi_irq_groups;
 #endif
 	struct pci_vpd	vpd;
 #ifdef CONFIG_PCIE_DPC


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 10/37] platform-msi: Let the core code handle sysfs groups
  2021-11-27  1:20 ` [patch 10/37] platform-msi: Let the core " Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Set the domain info flag and remove the local sysfs code.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/base/platform-msi.c |   11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -23,7 +23,6 @@
 struct platform_msi_priv_data {
 	struct device			*dev;
 	void				*host_data;
-	const struct attribute_group    **msi_irq_groups;
 	msi_alloc_info_t		arg;
 	irq_write_msi_msg_t		write_msg;
 	int				devid;
@@ -191,6 +190,7 @@ struct irq_domain *platform_msi_create_i
 		platform_msi_update_dom_ops(info);
 	if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS)
 		platform_msi_update_chip_ops(info);
+	info->flags |= MSI_FLAG_DEV_SYSFS;
 
 	domain = msi_create_irq_domain(fwnode, info, parent);
 	if (domain)
@@ -279,16 +279,8 @@ int platform_msi_domain_alloc_irqs(struc
 	if (err)
 		goto out_free_desc;
 
-	priv_data->msi_irq_groups = msi_populate_sysfs(dev);
-	if (IS_ERR(priv_data->msi_irq_groups)) {
-		err = PTR_ERR(priv_data->msi_irq_groups);
-		goto out_free_irqs;
-	}
-
 	return 0;
 
-out_free_irqs:
-	msi_domain_free_irqs(dev->msi.domain, dev);
 out_free_desc:
 	platform_msi_free_descs(dev, 0, nvec);
 out_free_priv_data:
@@ -308,7 +300,6 @@ void platform_msi_domain_free_irqs(struc
 		struct msi_desc *desc;
 
 		desc = first_msi_entry(dev);
-		msi_destroy_sysfs(dev, desc->platform.msi_priv_data->msi_irq_groups);
 		platform_msi_free_priv_data(desc->platform.msi_priv_data);
 	}
 


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 11/37] genirq/msi: Remove the original sysfs interfaces
  2021-11-27  1:20 ` [patch 11/37] genirq/msi: Remove the original sysfs interfaces Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

No more users. Refactor the core code accordingly.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/msi.h |   12 -----------
 kernel/irq/msi.c    |   53 +++++++++++++++++++---------------------------------
 2 files changed, 20 insertions(+), 45 deletions(-)

--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -246,21 +246,9 @@ void pci_msi_unmask_irq(struct irq_data
 #ifdef CONFIG_SYSFS
 int msi_device_populate_sysfs(struct device *dev);
 void msi_device_destroy_sysfs(struct device *dev);
-
-const struct attribute_group **msi_populate_sysfs(struct device *dev);
-void msi_destroy_sysfs(struct device *dev,
-		       const struct attribute_group **msi_irq_groups);
 #else
 static inline int msi_device_populate_sysfs(struct device *dev) { return 0; }
 static inline void msi_device_destroy_sysfs(struct device *dev) { }
-
-static inline const struct attribute_group **msi_populate_sysfs(struct device *dev)
-{
-	return NULL;
-}
-static inline void msi_destroy_sysfs(struct device *dev, const struct attribute_group **msi_irq_groups)
-{
-}
 #endif
 
 /*
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -132,12 +132,8 @@ static ssize_t msi_mode_show(struct devi
 /**
  * msi_populate_sysfs - Populate msi_irqs sysfs entries for devices
  * @dev:	The device(PCI, platform etc) who will get sysfs entries
- *
- * Return attribute_group ** so that specific bus MSI can save it to
- * somewhere during initilizing msi irqs. If devices has no MSI irq,
- * return NULL; if it fails to populate sysfs, return ERR_PTR
  */
-const struct attribute_group **msi_populate_sysfs(struct device *dev)
+static const struct attribute_group **msi_populate_sysfs(struct device *dev)
 {
 	const struct attribute_group **msi_irq_groups;
 	struct attribute **msi_attrs, *msi_attr;
@@ -228,41 +224,32 @@ int msi_device_populate_sysfs(struct dev
 }
 
 /**
- * msi_destroy_sysfs - Destroy msi_irqs sysfs entries for devices
- * @dev:		The device(PCI, platform etc) who will remove sysfs entries
- * @msi_irq_groups:	attribute_group for device msi_irqs entries
- */
-void msi_destroy_sysfs(struct device *dev, const struct attribute_group **msi_irq_groups)
-{
-	struct device_attribute *dev_attr;
-	struct attribute **msi_attrs;
-	int count = 0;
-
-	if (msi_irq_groups) {
-		sysfs_remove_groups(&dev->kobj, msi_irq_groups);
-		msi_attrs = msi_irq_groups[0]->attrs;
-		while (msi_attrs[count]) {
-			dev_attr = container_of(msi_attrs[count],
-					struct device_attribute, attr);
-			kfree(dev_attr->attr.name);
-			kfree(dev_attr);
-			++count;
-		}
-		kfree(msi_attrs);
-		kfree(msi_irq_groups[0]);
-		kfree(msi_irq_groups);
-	}
-}
-
-/**
  * msi_device_destroy_sysfs - Destroy msi_irqs sysfs entries for a device
  * @dev:		The device(PCI, platform etc) for which to remove
  *			sysfs entries
  */
 void msi_device_destroy_sysfs(struct device *dev)
 {
-	msi_destroy_sysfs(dev, dev->msi.data->attrs);
+	const struct attribute_group **msi_irq_groups = dev->msi.data->attrs;
+	struct device_attribute *dev_attr;
+	struct attribute **msi_attrs;
+	int count = 0;
+
 	dev->msi.data->attrs = NULL;
+	if (!msi_irq_groups)
+		return;
+
+	sysfs_remove_groups(&dev->kobj, msi_irq_groups);
+	msi_attrs = msi_irq_groups[0]->attrs;
+	while (msi_attrs[count]) {
+		dev_attr = container_of(msi_attrs[count], struct device_attribute, attr);
+		kfree(dev_attr->attr.name);
+		kfree(dev_attr);
+		++count;
+	}
+	kfree(msi_attrs);
+	kfree(msi_irq_groups[0]);
+	kfree(msi_irq_groups);
 }
 #endif
 


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 12/37] platform-msi: Rename functions and clarify comments
  2021-11-27  1:20 ` [patch 12/37] platform-msi: Rename functions and clarify comments Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

It's hard to distinguish what platform_msi_domain_alloc() and
platform_msi_domain_alloc_irqs() are about. Make the distinction more
explicit and add comments which explain the use cases properly.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/base/platform-msi.c     |   36 +++++++++++++++++++++---------------
 drivers/irqchip/irq-mbigen.c    |    4 ++--
 drivers/irqchip/irq-mvebu-icu.c |    6 +++---
 include/linux/msi.h             |    8 ++++----
 4 files changed, 30 insertions(+), 24 deletions(-)

--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -313,17 +313,18 @@ EXPORT_SYMBOL_GPL(platform_msi_domain_fr
  *                              a platform-msi domain
  * @domain:	The platform-msi domain
  *
- * Returns the private data provided when calling
- * platform_msi_create_device_domain.
+ * Return: The private data provided when calling
+ * platform_msi_create_device_domain().
  */
 void *platform_msi_get_host_data(struct irq_domain *domain)
 {
 	struct platform_msi_priv_data *data = domain->host_data;
+
 	return data->host_data;
 }
 
 /**
- * __platform_msi_create_device_domain - Create a platform-msi domain
+ * __platform_msi_create_device_domain - Create a platform-msi device domain
  *
  * @dev:		The device generating the MSIs
  * @nvec:		The number of MSIs that need to be allocated
@@ -332,7 +333,11 @@ void *platform_msi_get_host_data(struct
  * @ops:		The hierarchy domain operations to use
  * @host_data:		Private data associated to this domain
  *
- * Returns an irqdomain for @nvec interrupts
+ * Return: An irqdomain for @nvec interrupts on success, NULL in case of error.
+ *
+ * This is for interrupt domains which stack on a platform-msi domain
+ * created by platform_msi_create_irq_domain(). @dev->msi.domain points to
+ * that platform-msi domain which is the parent for the new domain.
  */
 struct irq_domain *
 __platform_msi_create_device_domain(struct device *dev,
@@ -372,18 +377,19 @@ struct irq_domain *
 }
 
 /**
- * platform_msi_domain_free - Free interrupts associated with a platform-msi
- *                            domain
+ * platform_msi_device_domain_free - Free interrupts associated with a platform-msi
+ *				     device domain
  *
- * @domain:	The platform-msi domain
+ * @domain:	The platform-msi device domain
  * @virq:	The base irq from which to perform the free operation
  * @nvec:	How many interrupts to free from @virq
  */
-void platform_msi_domain_free(struct irq_domain *domain, unsigned int virq,
-			      unsigned int nvec)
+void platform_msi_device_domain_free(struct irq_domain *domain, unsigned int virq,
+				     unsigned int nvec)
 {
 	struct platform_msi_priv_data *data = domain->host_data;
 	struct msi_desc *desc, *tmp;
+
 	for_each_msi_entry_safe(desc, tmp, data->dev) {
 		if (WARN_ON(!desc->irq || desc->nvec_used != 1))
 			return;
@@ -397,10 +403,10 @@ void platform_msi_domain_free(struct irq
 }
 
 /**
- * platform_msi_domain_alloc - Allocate interrupts associated with
- *			       a platform-msi domain
+ * platform_msi_device_domain_alloc - Allocate interrupts associated with
+ *				      a platform-msi device domain
  *
- * @domain:	The platform-msi domain
+ * @domain:	The platform-msi device domain
  * @virq:	The base irq from which to perform the allocate operation
  * @nr_irqs:	How many interrupts to free from @virq
  *
@@ -408,8 +414,8 @@ void platform_msi_domain_free(struct irq
  * with irq_domain_mutex held (which can only be done as part of a
  * top-level interrupt allocation).
  */
-int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
-			      unsigned int nr_irqs)
+int platform_msi_device_domain_alloc(struct irq_domain *domain, unsigned int virq,
+				     unsigned int nr_irqs)
 {
 	struct platform_msi_priv_data *data = domain->host_data;
 	int err;
@@ -421,7 +427,7 @@ int platform_msi_domain_alloc(struct irq
 	err = msi_domain_populate_irqs(domain->parent, data->dev,
 				       virq, nr_irqs, &data->arg);
 	if (err)
-		platform_msi_domain_free(domain, virq, nr_irqs);
+		platform_msi_device_domain_free(domain, virq, nr_irqs);
 
 	return err;
 }
--- a/drivers/irqchip/irq-mbigen.c
+++ b/drivers/irqchip/irq-mbigen.c
@@ -207,7 +207,7 @@ static int mbigen_irq_domain_alloc(struc
 	if (err)
 		return err;
 
-	err = platform_msi_domain_alloc(domain, virq, nr_irqs);
+	err = platform_msi_device_domain_alloc(domain, virq, nr_irqs);
 	if (err)
 		return err;
 
@@ -223,7 +223,7 @@ static int mbigen_irq_domain_alloc(struc
 static void mbigen_irq_domain_free(struct irq_domain *domain, unsigned int virq,
 				   unsigned int nr_irqs)
 {
-	platform_msi_domain_free(domain, virq, nr_irqs);
+	platform_msi_device_domain_free(domain, virq, nr_irqs);
 }
 
 static const struct irq_domain_ops mbigen_domain_ops = {
--- a/drivers/irqchip/irq-mvebu-icu.c
+++ b/drivers/irqchip/irq-mvebu-icu.c
@@ -221,7 +221,7 @@ mvebu_icu_irq_domain_alloc(struct irq_do
 		icu_irqd->icu_group = msi_data->subset_data->icu_group;
 	icu_irqd->icu = icu;
 
-	err = platform_msi_domain_alloc(domain, virq, nr_irqs);
+	err = platform_msi_device_domain_alloc(domain, virq, nr_irqs);
 	if (err) {
 		dev_err(icu->dev, "failed to allocate ICU interrupt in parent domain\n");
 		goto free_irqd;
@@ -245,7 +245,7 @@ mvebu_icu_irq_domain_alloc(struct irq_do
 	return 0;
 
 free_msi:
-	platform_msi_domain_free(domain, virq, nr_irqs);
+	platform_msi_device_domain_free(domain, virq, nr_irqs);
 free_irqd:
 	kfree(icu_irqd);
 	return err;
@@ -260,7 +260,7 @@ mvebu_icu_irq_domain_free(struct irq_dom
 
 	kfree(icu_irqd);
 
-	platform_msi_domain_free(domain, virq, nr_irqs);
+	platform_msi_device_domain_free(domain, virq, nr_irqs);
 }
 
 static const struct irq_domain_ops mvebu_icu_domain_ops = {
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -432,10 +432,10 @@ struct irq_domain *
 #define platform_msi_create_device_tree_domain(dev, nvec, write, ops, data) \
 	__platform_msi_create_device_domain(dev, nvec, true, write, ops, data)
 
-int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
-			      unsigned int nr_irqs);
-void platform_msi_domain_free(struct irq_domain *domain, unsigned int virq,
-			      unsigned int nvec);
+int platform_msi_device_domain_alloc(struct irq_domain *domain, unsigned int virq,
+				     unsigned int nr_irqs);
+void platform_msi_device_domain_free(struct irq_domain *domain, unsigned int virq,
+				     unsigned int nvec);
 void *platform_msi_get_host_data(struct irq_domain *domain);
 #endif /* CONFIG_GENERIC_MSI_IRQ_DOMAIN */
 


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 13/37] platform-msi: Store platform private data pointer in msi_device_data
  2021-11-27  1:20 ` [patch 13/37] platform-msi: Store platform private data pointer in msi_device_data Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Storing the platform private data in a MSI descriptor is sloppy at
best. The data belongs to the device and not to the descriptor.
Add a pointer to struct msi_device_data and store the pointer there.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/base/platform-msi.c |   79 +++++++++++++++++---------------------------
 include/linux/msi.h         |    5 +-
 2 files changed, 35 insertions(+), 49 deletions(-)

--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -38,9 +38,7 @@ static DEFINE_IDA(platform_msi_devid_ida
  */
 static irq_hw_number_t platform_msi_calc_hwirq(struct msi_desc *desc)
 {
-	u32 devid;
-
-	devid = desc->platform.msi_priv_data->devid;
+	u32 devid = desc->dev->msi.data->platform_data->devid;
 
 	return (devid << (32 - DEV_ID_SHIFT)) | desc->platform.msi_index;
 }
@@ -85,11 +83,8 @@ static void platform_msi_update_dom_ops(
 static void platform_msi_write_msg(struct irq_data *data, struct msi_msg *msg)
 {
 	struct msi_desc *desc = irq_data_get_msi_desc(data);
-	struct platform_msi_priv_data *priv_data;
-
-	priv_data = desc->platform.msi_priv_data;
 
-	priv_data->write_msg(desc, msg);
+	desc->dev->msi.data->platform_data->write_msg(desc, msg);
 }
 
 static void platform_msi_update_chip_ops(struct msi_domain_info *info)
@@ -126,9 +121,7 @@ static void platform_msi_free_descs(stru
 }
 
 static int platform_msi_alloc_descs_with_irq(struct device *dev, int virq,
-					     int nvec,
-					     struct platform_msi_priv_data *data)
-
+					     int nvec)
 {
 	struct msi_desc *desc;
 	int i, base = 0;
@@ -144,7 +137,6 @@ static int platform_msi_alloc_descs_with
 		if (!desc)
 			break;
 
-		desc->platform.msi_priv_data = data;
 		desc->platform.msi_index = base + i;
 		desc->irq = virq ? virq + i : 0;
 
@@ -161,11 +153,9 @@ static int platform_msi_alloc_descs_with
 	return 0;
 }
 
-static int platform_msi_alloc_descs(struct device *dev, int nvec,
-				    struct platform_msi_priv_data *data)
-
+static int platform_msi_alloc_descs(struct device *dev, int nvec)
 {
-	return platform_msi_alloc_descs_with_irq(dev, 0, nvec, data);
+	return platform_msi_alloc_descs_with_irq(dev, 0, nvec);
 }
 
 /**
@@ -199,9 +189,8 @@ struct irq_domain *platform_msi_create_i
 	return domain;
 }
 
-static struct platform_msi_priv_data *
-platform_msi_alloc_priv_data(struct device *dev, unsigned int nvec,
-			     irq_write_msi_msg_t write_msi_msg)
+static int platform_msi_alloc_priv_data(struct device *dev, unsigned int nvec,
+					irq_write_msi_msg_t write_msi_msg)
 {
 	struct platform_msi_priv_data *datap;
 	int err;
@@ -213,41 +202,44 @@ platform_msi_alloc_priv_data(struct devi
 	 * capable devices).
 	 */
 	if (!dev->msi.domain || !write_msi_msg || !nvec || nvec > MAX_DEV_MSIS)
-		return ERR_PTR(-EINVAL);
+		return -EINVAL;
 
 	if (dev->msi.domain->bus_token != DOMAIN_BUS_PLATFORM_MSI) {
 		dev_err(dev, "Incompatible msi_domain, giving up\n");
-		return ERR_PTR(-EINVAL);
+		return -EINVAL;
 	}
 
 	err = msi_setup_device_data(dev);
 	if (err)
-		return ERR_PTR(err);
+		return err;
 
-	/* Already had a helping of MSI? Greed... */
-	if (!list_empty(dev_to_msi_list(dev)))
-		return ERR_PTR(-EBUSY);
+	/* Already initialized? */
+	if (dev->msi.data->platform_data)
+		return -EBUSY;
 
 	datap = kzalloc(sizeof(*datap), GFP_KERNEL);
 	if (!datap)
-		return ERR_PTR(-ENOMEM);
+		return -ENOMEM;
 
 	datap->devid = ida_simple_get(&platform_msi_devid_ida,
 				      0, 1 << DEV_ID_SHIFT, GFP_KERNEL);
 	if (datap->devid < 0) {
 		err = datap->devid;
 		kfree(datap);
-		return ERR_PTR(err);
+		return err;
 	}
 
 	datap->write_msg = write_msi_msg;
 	datap->dev = dev;
-
-	return datap;
+	dev->msi.data->platform_data = datap;
+	return 0;
 }
 
-static void platform_msi_free_priv_data(struct platform_msi_priv_data *data)
+static void platform_msi_free_priv_data(struct device *dev)
 {
+	struct platform_msi_priv_data *data = dev->msi.data->platform_data;
+
+	dev->msi.data->platform_data = NULL;
 	ida_simple_remove(&platform_msi_devid_ida, data->devid);
 	kfree(data);
 }
@@ -264,14 +256,13 @@ static void platform_msi_free_priv_data(
 int platform_msi_domain_alloc_irqs(struct device *dev, unsigned int nvec,
 				   irq_write_msi_msg_t write_msi_msg)
 {
-	struct platform_msi_priv_data *priv_data;
 	int err;
 
-	priv_data = platform_msi_alloc_priv_data(dev, nvec, write_msi_msg);
-	if (IS_ERR(priv_data))
-		return PTR_ERR(priv_data);
+	err = platform_msi_alloc_priv_data(dev, nvec, write_msi_msg);
+	if (err)
+		return err;
 
-	err = platform_msi_alloc_descs(dev, nvec, priv_data);
+	err = platform_msi_alloc_descs(dev, nvec);
 	if (err)
 		goto out_free_priv_data;
 
@@ -284,8 +275,7 @@ int platform_msi_domain_alloc_irqs(struc
 out_free_desc:
 	platform_msi_free_descs(dev, 0, nvec);
 out_free_priv_data:
-	platform_msi_free_priv_data(priv_data);
-
+	platform_msi_free_priv_data(dev);
 	return err;
 }
 EXPORT_SYMBOL_GPL(platform_msi_domain_alloc_irqs);
@@ -296,15 +286,9 @@ EXPORT_SYMBOL_GPL(platform_msi_domain_al
  */
 void platform_msi_domain_free_irqs(struct device *dev)
 {
-	if (!list_empty(dev_to_msi_list(dev))) {
-		struct msi_desc *desc;
-
-		desc = first_msi_entry(dev);
-		platform_msi_free_priv_data(desc->platform.msi_priv_data);
-	}
-
 	msi_domain_free_irqs(dev->msi.domain, dev);
 	platform_msi_free_descs(dev, 0, MAX_DEV_MSIS);
+	platform_msi_free_priv_data(dev);
 }
 EXPORT_SYMBOL_GPL(platform_msi_domain_free_irqs);
 
@@ -351,10 +335,11 @@ struct irq_domain *
 	struct irq_domain *domain;
 	int err;
 
-	data = platform_msi_alloc_priv_data(dev, nvec, write_msi_msg);
-	if (IS_ERR(data))
+	err = platform_msi_alloc_priv_data(dev, nvec, write_msi_msg);
+	if (err)
 		return NULL;
 
+	data = dev->msi.data->platform_data;
 	data->host_data = host_data;
 	domain = irq_domain_create_hierarchy(dev->msi.domain, 0,
 					     is_tree ? 0 : nvec,
@@ -372,7 +357,7 @@ struct irq_domain *
 free_domain:
 	irq_domain_remove(domain);
 free_priv:
-	platform_msi_free_priv_data(data);
+	platform_msi_free_priv_data(dev);
 	return NULL;
 }
 
@@ -420,7 +405,7 @@ int platform_msi_device_domain_alloc(str
 	struct platform_msi_priv_data *data = domain->host_data;
 	int err;
 
-	err = platform_msi_alloc_descs_with_irq(data->dev, virq, nr_irqs, data);
+	err = platform_msi_alloc_descs_with_irq(data->dev, virq, nr_irqs);
 	if (err)
 		return err;
 
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -56,6 +56,7 @@ struct irq_data;
 struct msi_desc;
 struct pci_dev;
 struct platform_msi_priv_data;
+
 void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
 #ifdef CONFIG_GENERIC_MSI_IRQ
 void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg);
@@ -106,11 +107,9 @@ struct pci_msi_desc {
 
 /**
  * platform_msi_desc - Platform device specific msi descriptor data
- * @msi_priv_data:	Pointer to platform private data
  * @msi_index:		The index of the MSI descriptor for multi MSI
  */
 struct platform_msi_desc {
-	struct platform_msi_priv_data	*msi_priv_data;
 	u16				msi_index;
 };
 
@@ -175,10 +174,12 @@ struct msi_desc {
  * msi_device_data - MSI per device data
  * @lock:		Spinlock to protect register access
  * @attrs:		Pointer to the sysfs attribute group
+ * @platform_data:	Platform-MSI specific data
  */
 struct msi_device_data {
 	raw_spinlock_t			lock;
 	const struct attribute_group    **attrs;
+	struct platform_msi_priv_data	*platform_data;
 };
 
 int msi_setup_device_data(struct device *dev);


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 14/37] genirq/msi: Consolidate MSI descriptor data
  2021-11-27  1:20 ` [patch 14/37] genirq/msi: Consolidate MSI descriptor data Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

All non PCI/MSI usage variants have data structures in struct msi_desc with
only one member: xxx_index. PCI/MSI has a entry_nr member.

Add a common msi_index member to struct msi_desc so all implementations can
share it which allows further consolidation.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/msi.h |    2 ++
 1 file changed, 2 insertions(+)

--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -142,6 +142,7 @@ struct ti_sci_inta_msi_desc {
  *			address or data changes
  * @write_msi_msg_data:	Data parameter for the callback.
  *
+ * @msi_index:	Index of the msi descriptor
  * @pci:	[PCI]	    PCI speficic msi descriptor data
  * @platform:	[platform]  Platform device specific msi descriptor data
  * @fsl_mc:	[fsl-mc]    FSL MC device specific msi descriptor data
@@ -162,6 +163,7 @@ struct msi_desc {
 	void (*write_msi_msg)(struct msi_desc *entry, void *data);
 	void *write_msi_msg_data;
 
+	u16				msi_index;
 	union {
 		struct pci_msi_desc		pci;
 		struct platform_msi_desc	platform;


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 15/37] platform-msi: Use msi_desc::msi_index
  2021-11-27  1:20 ` [patch 15/37] platform-msi: Use msi_desc::msi_index Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, linux-arm-kernel, iommu, dmaengine,
	Santosh Shilimkar, Stuart Yoder, Laurentiu Tudor, Nishanth Menon,
	Tero Kristo, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Use the common msi_index member and get rid of the pointless wrapper struct.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-arm-kernel@lists.infradead.org
Cc: iommu@lists.linux-foundation.org
Cc: dmaengine@vger.kernel.org
---
 drivers/base/platform-msi.c                 |   10 +++++-----
 drivers/dma/qcom/hidma.c                    |    4 ++--
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |    4 ++--
 drivers/mailbox/bcm-flexrm-mailbox.c        |    4 ++--
 include/linux/msi.h                         |   10 ----------
 5 files changed, 11 insertions(+), 21 deletions(-)

--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -40,7 +40,7 @@ static irq_hw_number_t platform_msi_calc
 {
 	u32 devid = desc->dev->msi.data->platform_data->devid;
 
-	return (devid << (32 - DEV_ID_SHIFT)) | desc->platform.msi_index;
+	return (devid << (32 - DEV_ID_SHIFT)) | desc->msi_index;
 }
 
 static void platform_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
@@ -112,8 +112,8 @@ static void platform_msi_free_descs(stru
 	struct msi_desc *desc, *tmp;
 
 	list_for_each_entry_safe(desc, tmp, dev_to_msi_list(dev), list) {
-		if (desc->platform.msi_index >= base &&
-		    desc->platform.msi_index < (base + nvec)) {
+		if (desc->msi_index >= base &&
+		    desc->msi_index < (base + nvec)) {
 			list_del(&desc->list);
 			free_msi_entry(desc);
 		}
@@ -129,7 +129,7 @@ static int platform_msi_alloc_descs_with
 	if (!list_empty(dev_to_msi_list(dev))) {
 		desc = list_last_entry(dev_to_msi_list(dev),
 				       struct msi_desc, list);
-		base = desc->platform.msi_index + 1;
+		base = desc->msi_index + 1;
 	}
 
 	for (i = 0; i < nvec; i++) {
@@ -137,7 +137,7 @@ static int platform_msi_alloc_descs_with
 		if (!desc)
 			break;
 
-		desc->platform.msi_index = base + i;
+		desc->msi_index = base + i;
 		desc->irq = virq ? virq + i : 0;
 
 		list_add_tail(&desc->list, dev_to_msi_list(dev));
--- a/drivers/dma/qcom/hidma.c
+++ b/drivers/dma/qcom/hidma.c
@@ -666,7 +666,7 @@ static void hidma_write_msi_msg(struct m
 	struct device *dev = msi_desc_to_dev(desc);
 	struct hidma_dev *dmadev = dev_get_drvdata(dev);
 
-	if (!desc->platform.msi_index) {
+	if (!desc->msi_index) {
 		writel(msg->address_lo, dmadev->dev_evca + 0x118);
 		writel(msg->address_hi, dmadev->dev_evca + 0x11C);
 		writel(msg->data, dmadev->dev_evca + 0x120);
@@ -702,7 +702,7 @@ static int hidma_request_msi(struct hidm
 		return rc;
 
 	for_each_msi_entry(desc, &pdev->dev) {
-		if (!desc->platform.msi_index)
+		if (!desc->msi_index)
 			dmadev->msi_virqbase = desc->irq;
 
 		rc = devm_request_irq(&pdev->dev, desc->irq,
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3142,7 +3142,7 @@ static void arm_smmu_write_msi_msg(struc
 	phys_addr_t doorbell;
 	struct device *dev = msi_desc_to_dev(desc);
 	struct arm_smmu_device *smmu = dev_get_drvdata(dev);
-	phys_addr_t *cfg = arm_smmu_msi_cfg[desc->platform.msi_index];
+	phys_addr_t *cfg = arm_smmu_msi_cfg[desc->msi_index];
 
 	doorbell = (((u64)msg->address_hi) << 32) | msg->address_lo;
 	doorbell &= MSI_CFG0_ADDR_MASK;
@@ -3183,7 +3183,7 @@ static void arm_smmu_setup_msis(struct a
 	}
 
 	for_each_msi_entry(desc, dev) {
-		switch (desc->platform.msi_index) {
+		switch (desc->msi_index) {
 		case EVTQ_MSI_INDEX:
 			smmu->evtq.q.irq = desc->irq;
 			break;
--- a/drivers/mailbox/bcm-flexrm-mailbox.c
+++ b/drivers/mailbox/bcm-flexrm-mailbox.c
@@ -1484,7 +1484,7 @@ static void flexrm_mbox_msi_write(struct
 {
 	struct device *dev = msi_desc_to_dev(desc);
 	struct flexrm_mbox *mbox = dev_get_drvdata(dev);
-	struct flexrm_ring *ring = &mbox->rings[desc->platform.msi_index];
+	struct flexrm_ring *ring = &mbox->rings[desc->msi_index];
 
 	/* Configure per-Ring MSI registers */
 	writel_relaxed(msg->address_lo, ring->regs + RING_MSI_ADDR_LS);
@@ -1609,7 +1609,7 @@ static int flexrm_mbox_probe(struct plat
 
 	/* Save alloced IRQ numbers for each ring */
 	for_each_msi_entry(desc, dev) {
-		ring = &mbox->rings[desc->platform.msi_index];
+		ring = &mbox->rings[desc->msi_index];
 		ring->irq = desc->irq;
 	}
 
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -106,14 +106,6 @@ struct pci_msi_desc {
 };
 
 /**
- * platform_msi_desc - Platform device specific msi descriptor data
- * @msi_index:		The index of the MSI descriptor for multi MSI
- */
-struct platform_msi_desc {
-	u16				msi_index;
-};
-
-/**
  * fsl_mc_msi_desc - FSL-MC device specific msi descriptor data
  * @msi_index:		The index of the MSI descriptor
  */
@@ -144,7 +136,6 @@ struct ti_sci_inta_msi_desc {
  *
  * @msi_index:	Index of the msi descriptor
  * @pci:	[PCI]	    PCI speficic msi descriptor data
- * @platform:	[platform]  Platform device specific msi descriptor data
  * @fsl_mc:	[fsl-mc]    FSL MC device specific msi descriptor data
  * @inta:	[INTA]	    TISCI based INTA specific msi descriptor data
  */
@@ -166,7 +157,6 @@ struct msi_desc {
 	u16				msi_index;
 	union {
 		struct pci_msi_desc		pci;
-		struct platform_msi_desc	platform;
 		struct fsl_mc_msi_desc		fsl_mc;
 		struct ti_sci_inta_msi_desc	inta;
 	};


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 16/37] bus: fsl-mc-msi: Use msi_desc::msi_index
  2021-11-27  1:20 ` [patch 16/37] bus: fsl-mc-msi: " Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Use the common msi_index member and get rid of the pointless wrapper struct.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/bus/fsl-mc/fsl-mc-allocator.c |    2 +-
 drivers/bus/fsl-mc/fsl-mc-msi.c       |    6 +++---
 include/linux/msi.h                   |   10 ----------
 3 files changed, 4 insertions(+), 14 deletions(-)

--- a/drivers/bus/fsl-mc/fsl-mc-allocator.c
+++ b/drivers/bus/fsl-mc/fsl-mc-allocator.c
@@ -393,7 +393,7 @@ int fsl_mc_populate_irq_pool(struct fsl_
 	}
 
 	for_each_msi_entry(msi_desc, &mc_bus_dev->dev) {
-		mc_dev_irq = &irq_resources[msi_desc->fsl_mc.msi_index];
+		mc_dev_irq = &irq_resources[msi_desc->msi_index];
 		mc_dev_irq->msi_desc = msi_desc;
 		mc_dev_irq->resource.id = msi_desc->irq;
 	}
--- a/drivers/bus/fsl-mc/fsl-mc-msi.c
+++ b/drivers/bus/fsl-mc/fsl-mc-msi.c
@@ -29,7 +29,7 @@ static irq_hw_number_t fsl_mc_domain_cal
 	 * Make the base hwirq value for ICID*10000 so it is readable
 	 * as a decimal value in /proc/interrupts.
 	 */
-	return (irq_hw_number_t)(desc->fsl_mc.msi_index + (dev->icid * 10000));
+	return (irq_hw_number_t)(desc->msi_index + (dev->icid * 10000));
 }
 
 static void fsl_mc_msi_set_desc(msi_alloc_info_t *arg,
@@ -122,7 +122,7 @@ static void fsl_mc_msi_write_msg(struct
 	struct fsl_mc_device *mc_bus_dev = to_fsl_mc_device(msi_desc->dev);
 	struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);
 	struct fsl_mc_device_irq *mc_dev_irq =
-		&mc_bus->irq_resources[msi_desc->fsl_mc.msi_index];
+		&mc_bus->irq_resources[msi_desc->msi_index];
 
 	msi_desc->msg = *msg;
 
@@ -235,7 +235,7 @@ static int fsl_mc_msi_alloc_descs(struct
 			goto cleanup_msi_descs;
 		}
 
-		msi_desc->fsl_mc.msi_index = i;
+		msi_desc->msi_index = i;
 		INIT_LIST_HEAD(&msi_desc->list);
 		list_add_tail(&msi_desc->list, dev_to_msi_list(dev));
 	}
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -106,14 +106,6 @@ struct pci_msi_desc {
 };
 
 /**
- * fsl_mc_msi_desc - FSL-MC device specific msi descriptor data
- * @msi_index:		The index of the MSI descriptor
- */
-struct fsl_mc_msi_desc {
-	u16				msi_index;
-};
-
-/**
  * ti_sci_inta_msi_desc - TISCI based INTA specific msi descriptor data
  * @dev_index: TISCI device index
  */
@@ -136,7 +128,6 @@ struct ti_sci_inta_msi_desc {
  *
  * @msi_index:	Index of the msi descriptor
  * @pci:	[PCI]	    PCI speficic msi descriptor data
- * @fsl_mc:	[fsl-mc]    FSL MC device specific msi descriptor data
  * @inta:	[INTA]	    TISCI based INTA specific msi descriptor data
  */
 struct msi_desc {
@@ -157,7 +148,6 @@ struct msi_desc {
 	u16				msi_index;
 	union {
 		struct pci_msi_desc		pci;
-		struct fsl_mc_msi_desc		fsl_mc;
 		struct ti_sci_inta_msi_desc	inta;
 	};
 };


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 17/37] soc: ti: ti_sci_inta_msi: Use msi_desc::msi_index
  2021-11-27  1:20 ` [patch 17/37] soc: ti: ti_sci_inta_msi: " Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Use the common msi_index member and get rid of the pointless wrapper struct.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/irqchip/irq-ti-sci-inta.c |    2 +-
 drivers/soc/ti/ti_sci_inta_msi.c  |    6 +++---
 include/linux/msi.h               |   16 ++--------------
 3 files changed, 6 insertions(+), 18 deletions(-)

--- a/drivers/irqchip/irq-ti-sci-inta.c
+++ b/drivers/irqchip/irq-ti-sci-inta.c
@@ -595,7 +595,7 @@ static void ti_sci_inta_msi_set_desc(msi
 	struct platform_device *pdev = to_platform_device(desc->dev);
 
 	arg->desc = desc;
-	arg->hwirq = TO_HWIRQ(pdev->id, desc->inta.dev_index);
+	arg->hwirq = TO_HWIRQ(pdev->id, desc->msi_index);
 }
 
 static struct msi_domain_ops ti_sci_inta_msi_ops = {
--- a/drivers/soc/ti/ti_sci_inta_msi.c
+++ b/drivers/soc/ti/ti_sci_inta_msi.c
@@ -84,7 +84,7 @@ static int ti_sci_inta_msi_alloc_descs(s
 				return -ENOMEM;
 			}
 
-			msi_desc->inta.dev_index = res->desc[set].start + i;
+			msi_desc->msi_index = res->desc[set].start + i;
 			INIT_LIST_HEAD(&msi_desc->list);
 			list_add_tail(&msi_desc->list, dev_to_msi_list(dev));
 			count++;
@@ -96,7 +96,7 @@ static int ti_sci_inta_msi_alloc_descs(s
 				return -ENOMEM;
 			}
 
-			msi_desc->inta.dev_index = res->desc[set].start_sec + i;
+			msi_desc->msi_index = res->desc[set].start_sec + i;
 			INIT_LIST_HEAD(&msi_desc->list);
 			list_add_tail(&msi_desc->list, dev_to_msi_list(dev));
 			count++;
@@ -154,7 +154,7 @@ unsigned int ti_sci_inta_msi_get_virq(st
 	struct msi_desc *desc;
 
 	for_each_msi_entry(desc, dev)
-		if (desc->inta.dev_index == dev_index)
+		if (desc->msi_index == dev_index)
 			return desc->irq;
 
 	return -ENODEV;
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -106,14 +106,6 @@ struct pci_msi_desc {
 };
 
 /**
- * ti_sci_inta_msi_desc - TISCI based INTA specific msi descriptor data
- * @dev_index: TISCI device index
- */
-struct ti_sci_inta_msi_desc {
-	u16	dev_index;
-};
-
-/**
  * struct msi_desc - Descriptor structure for MSI based interrupts
  * @list:	List head for management
  * @irq:	The base interrupt number
@@ -127,8 +119,7 @@ struct ti_sci_inta_msi_desc {
  * @write_msi_msg_data:	Data parameter for the callback.
  *
  * @msi_index:	Index of the msi descriptor
- * @pci:	[PCI]	    PCI speficic msi descriptor data
- * @inta:	[INTA]	    TISCI based INTA specific msi descriptor data
+ * @pci:	PCI speficic msi descriptor data
  */
 struct msi_desc {
 	/* Shared device/bus type independent data */
@@ -146,10 +137,7 @@ struct msi_desc {
 	void *write_msi_msg_data;
 
 	u16				msi_index;
-	union {
-		struct pci_msi_desc		pci;
-		struct ti_sci_inta_msi_desc	inta;
-	};
+	struct pci_msi_desc		pci;
 };
 
 /**


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 18/37] PCI/MSI: Use msi_desc::msi_index
  2021-11-27  1:20 ` [patch 18/37] PCI/MSI: " Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

The usage of msi_desc::pci::entry_nr is confusing at best. It's the index
into the MSI[X] descriptor table.

Use msi_desc::msi_index which is shared between all MSI incarnations
instead of having a PCI specific storage for no value.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/powerpc/platforms/pseries/msi.c |    4 ++--
 arch/x86/pci/xen.c                   |    2 +-
 drivers/pci/msi/irqdomain.c          |    2 +-
 drivers/pci/msi/msi.c                |   20 ++++++++------------
 drivers/pci/xen-pcifront.c           |    2 +-
 include/linux/msi.h                  |    2 --
 6 files changed, 13 insertions(+), 19 deletions(-)

--- a/arch/powerpc/platforms/pseries/msi.c
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -332,7 +332,7 @@ static int check_msix_entries(struct pci
 
 	expected = 0;
 	for_each_pci_msi_entry(entry, pdev) {
-		if (entry->pci.msi_attrib.entry_nr != expected) {
+		if (entry->msi_index != expected) {
 			pr_debug("rtas_msi: bad MSI-X entries.\n");
 			return -EINVAL;
 		}
@@ -580,7 +580,7 @@ static int pseries_irq_domain_alloc(stru
 	int hwirq;
 	int i, ret;
 
-	hwirq = rtas_query_irq_number(pci_get_pdn(pdev), desc->pci.msi_attrib.entry_nr);
+	hwirq = rtas_query_irq_number(pci_get_pdn(pdev), desc->msi_index);
 	if (hwirq < 0) {
 		dev_err(&pdev->dev, "Failed to query HW IRQ: %d\n", hwirq);
 		return hwirq;
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -306,7 +306,7 @@ static int xen_initdom_setup_msi_irqs(st
 				return -EINVAL;
 
 			map_irq.table_base = pci_resource_start(dev, bir);
-			map_irq.entry_nr = msidesc->pci.msi_attrib.entry_nr;
+			map_irq.entry_nr = msidesc->msi_index;
 		}
 
 		ret = -EINVAL;
--- a/drivers/pci/msi/irqdomain.c
+++ b/drivers/pci/msi/irqdomain.c
@@ -57,7 +57,7 @@ static irq_hw_number_t pci_msi_domain_ca
 {
 	struct pci_dev *dev = msi_desc_to_pci_dev(desc);
 
-	return (irq_hw_number_t)desc->pci.msi_attrib.entry_nr |
+	return (irq_hw_number_t)desc->msi_index |
 		pci_dev_id(dev) << 11 |
 		(pci_domain_nr(dev->bus) & 0xFFFFFFFF) << 27;
 }
--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -44,7 +44,7 @@ static inline void pci_msi_unmask(struct
 
 static inline void __iomem *pci_msix_desc_addr(struct msi_desc *desc)
 {
-	return desc->pci.mask_base + desc->pci.msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
+	return desc->pci.mask_base + desc->msi_index * PCI_MSIX_ENTRY_SIZE;
 }
 
 /*
@@ -354,13 +354,10 @@ msi_setup_entry(struct pci_dev *dev, int
 	if (dev->dev_flags & PCI_DEV_FLAGS_HAS_MSI_MASKING)
 		control |= PCI_MSI_FLAGS_MASKBIT;
 
-	entry->pci.msi_attrib.is_msix	= 0;
-	entry->pci.msi_attrib.is_64		= !!(control & PCI_MSI_FLAGS_64BIT);
-	entry->pci.msi_attrib.is_virtual    = 0;
-	entry->pci.msi_attrib.entry_nr	= 0;
+	entry->pci.msi_attrib.is_64	= !!(control & PCI_MSI_FLAGS_64BIT);
 	entry->pci.msi_attrib.can_mask	= !pci_msi_ignore_mask &&
 					  !!(control & PCI_MSI_FLAGS_MASKBIT);
-	entry->pci.msi_attrib.default_irq	= dev->irq;	/* Save IOAPIC IRQ */
+	entry->pci.msi_attrib.default_irq = dev->irq;
 	entry->pci.msi_attrib.multi_cap	= (control & PCI_MSI_FLAGS_QMASK) >> 1;
 	entry->pci.msi_attrib.multiple	= ilog2(__roundup_pow_of_two(nvec));
 
@@ -494,12 +491,11 @@ static int msix_setup_entries(struct pci
 		entry->pci.msi_attrib.is_64	= 1;
 
 		if (entries)
-			entry->pci.msi_attrib.entry_nr = entries[i].entry;
+			entry->msi_index = entries[i].entry;
 		else
-			entry->pci.msi_attrib.entry_nr = i;
+			entry->msi_index = i;
 
-		entry->pci.msi_attrib.is_virtual =
-			entry->pci.msi_attrib.entry_nr >= vec_count;
+		entry->pci.msi_attrib.is_virtual = entry->msi_index >= vec_count;
 
 		entry->pci.msi_attrib.can_mask	= !pci_msi_ignore_mask &&
 						  !entry->pci.msi_attrib.is_virtual;
@@ -1025,7 +1021,7 @@ int pci_irq_vector(struct pci_dev *dev,
 		struct msi_desc *entry;
 
 		for_each_pci_msi_entry(entry, dev) {
-			if (entry->pci.msi_attrib.entry_nr == nr)
+			if (entry->msi_index == nr)
 				return entry->irq;
 		}
 		WARN_ON_ONCE(1);
@@ -1057,7 +1053,7 @@ const struct cpumask *pci_irq_get_affini
 		struct msi_desc *entry;
 
 		for_each_pci_msi_entry(entry, dev) {
-			if (entry->pci.msi_attrib.entry_nr == nr)
+			if (entry->msi_index == nr)
 				return &entry->affinity->mask;
 		}
 		WARN_ON_ONCE(1);
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -263,7 +263,7 @@ static int pci_frontend_enable_msix(stru
 
 	i = 0;
 	for_each_pci_msi_entry(entry, dev) {
-		op.msix_entries[i].entry = entry->pci.msi_attrib.entry_nr;
+		op.msix_entries[i].entry = entry->msi_index;
 		/* Vector is useless at this point. */
 		op.msix_entries[i].vector = -1;
 		i++;
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -79,7 +79,6 @@ typedef void (*irq_write_msi_msg_t)(stru
  * @multi_cap:	[PCI MSI/X] log2 num of messages supported
  * @can_mask:	[PCI MSI/X] Masking supported?
  * @is_64:	[PCI MSI/X] Address size: 0=32bit 1=64bit
- * @entry_nr:	[PCI MSI/X] Entry which is described by this descriptor
  * @default_irq:[PCI MSI/X] The default pre-assigned non-MSI irq
  * @mask_pos:	[PCI MSI]   Mask register position
  * @mask_base:	[PCI MSI-X] Mask register base address
@@ -96,7 +95,6 @@ struct pci_msi_desc {
 		u8	can_mask	: 1;
 		u8	is_64		: 1;
 		u8	is_virtual	: 1;
-		u16	entry_nr;
 		unsigned default_irq;
 	} msi_attrib;
 	union {


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 19/37] genirq/msi: Add msi_device_data::properties
  2021-11-27  1:20 ` [patch 19/37] genirq/msi: Add msi_device_data::properties Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Add a properties field which allows core code to store information for easy
retrieval in order to replace MSI descriptor fiddling.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/msi.h |   17 +++++++++++++++++
 kernel/irq/msi.c    |   12 ++++++++++++
 2 files changed, 29 insertions(+)

--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -4,6 +4,7 @@
 
 #include <linux/spinlock.h>
 #include <linux/list.h>
+#include <linux/bits.h>
 #include <asm/msi.h>
 
 /* Dummy shadow structures if an architecture does not define them */
@@ -141,17 +142,33 @@ struct msi_desc {
 /**
  * msi_device_data - MSI per device data
  * @lock:		Spinlock to protect register access
+ * @properties:		MSI properties which are interesting to drivers
  * @attrs:		Pointer to the sysfs attribute group
  * @platform_data:	Platform-MSI specific data
  */
 struct msi_device_data {
 	raw_spinlock_t			lock;
+	unsigned long			properties;
 	const struct attribute_group    **attrs;
 	struct platform_msi_priv_data	*platform_data;
 };
 
 int msi_setup_device_data(struct device *dev);
 
+/* MSI device properties */
+#define MSI_PROP_PCI_MSI		BIT(0)
+#define MSI_PROP_PCI_MSIX		BIT(1)
+#define MSI_PROP_64BIT			BIT(2)
+
+#ifdef CONFIG_GENERIC_MSI_IRQ
+bool msi_device_has_property(struct device *dev, unsigned long prop);
+#else
+static inline bool msi_device_has_property(struct device *dev, unsigned long prop)
+{
+	return false;
+}
+#endif
+
 /* Helpers to hide struct msi_desc implementation details */
 #define msi_desc_to_dev(desc)		((desc)->dev)
 #define dev_to_msi_list(dev)		(&(dev)->msi_list)
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -60,6 +60,18 @@ void free_msi_entry(struct msi_desc *ent
 	kfree(entry);
 }
 
+/**
+ * msi_device_has_property - Check whether a device has a specific MSI property
+ * @dev:	Pointer to the device which is queried
+ * @prop:	Property to check for
+ */
+bool msi_device_has_property(struct device *dev, unsigned long prop)
+{
+	if (!dev->msi.data)
+		return false;
+	return !!(dev->msi.data->properties & prop);
+}
+
 void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
 {
 	*msg = entry->msg;


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 20/37] PCI/MSI: Store properties in device::msi::data
  2021-11-27  1:20 ` [patch 20/37] PCI/MSI: Store properties in device::msi::data Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Store the properties which are interesting for various places so the MSI
descriptor fiddling can be removed.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/pci/msi/msi.c |    6 ++++++
 1 file changed, 6 insertions(+)

--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -244,6 +244,8 @@ static void free_msi_irqs(struct pci_dev
 		iounmap(dev->msix_base);
 		dev->msix_base = NULL;
 	}
+
+	dev->dev.msi.data->properties = 0;
 }
 
 static void pci_intx_for_msi(struct pci_dev *dev, int enable)
@@ -372,6 +374,9 @@ msi_setup_entry(struct pci_dev *dev, int
 	if (entry->pci.msi_attrib.can_mask)
 		pci_read_config_dword(dev, entry->pci.mask_pos, &entry->pci.msi_mask);
 
+	dev->dev.msi.data->properties = MSI_PROP_PCI_MSI;
+	if (entry->pci.msi_attrib.is_64)
+		dev->dev.msi.data->properties |= MSI_PROP_64BIT;
 out:
 	kfree(masks);
 	return entry;
@@ -514,6 +519,7 @@ static int msix_setup_entries(struct pci
 		if (masks)
 			curmsk++;
 	}
+	dev->dev.msi.data->properties = MSI_PROP_PCI_MSIX | MSI_PROP_64BIT;
 	ret = 0;
 out:
 	kfree(masks);


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 21/37] x86/pci/XEN: Use device MSI properties
  2021-11-27  1:20 ` [patch 21/37] x86/pci/XEN: Use device MSI properties Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

instead of fiddling with MSI descriptors.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/pci/xen.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -399,9 +399,7 @@ static void xen_teardown_msi_irqs(struct
 
 static void xen_pv_teardown_msi_irqs(struct pci_dev *dev)
 {
-	struct msi_desc *msidesc = first_pci_msi_entry(dev);
-
-	if (msidesc->pci.msi_attrib.is_msix)
+	if (msi_device_has_property(&dev->dev, MSI_PROP_PCI_MSIX))
 		xen_pci_frontend_disable_msix(dev);
 	else
 		xen_pci_frontend_disable_msi(dev);
@@ -417,7 +415,7 @@ static int xen_msi_domain_alloc_irqs(str
 	if (WARN_ON_ONCE(!dev_is_pci(dev)))
 		return -EINVAL;
 
-	if (first_msi_entry(dev)->pci.msi_attrib.is_msix)
+	if (msi_device_has_property(dev, MSI_PROP_PCI_MSIX))
 		type = PCI_CAP_ID_MSIX;
 	else
 		type = PCI_CAP_ID_MSI;


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 22/37] x86/apic/msi: Use device MSI properties
  2021-11-27  1:20 ` [patch 22/37] x86/apic/msi: " Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

instead of fiddling with MSI descriptors.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/apic/msi.c |    5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

--- a/arch/x86/kernel/apic/msi.c
+++ b/arch/x86/kernel/apic/msi.c
@@ -160,11 +160,8 @@ static struct irq_chip pci_msi_controlle
 int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
 		    msi_alloc_info_t *arg)
 {
-	struct pci_dev *pdev = to_pci_dev(dev);
-	struct msi_desc *desc = first_pci_msi_entry(pdev);
-
 	init_irq_alloc_info(arg, NULL);
-	if (desc->pci.msi_attrib.is_msix) {
+	if (msi_device_has_property(dev, MSI_PROP_PCI_MSIX)) {
 		arg->type = X86_IRQ_ALLOC_TYPE_PCI_MSIX;
 	} else {
 		arg->type = X86_IRQ_ALLOC_TYPE_PCI_MSI;


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 23/37] genirq/msi: Use device MSI properties
  2021-11-27  1:20 ` [patch 23/37] genirq/msi: " Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, x86, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

instead of fiddling with MSI descriptors.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: x86@kernel.org
---
 kernel/irq/msi.c |   17 ++---------------
 1 file changed, 2 insertions(+), 15 deletions(-)

--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -114,21 +114,8 @@ int msi_setup_device_data(struct device
 static ssize_t msi_mode_show(struct device *dev, struct device_attribute *attr,
 			     char *buf)
 {
-	struct msi_desc *entry;
-	bool is_msix = false;
-	unsigned long irq;
-	int retval;
-
-	retval = kstrtoul(attr->attr.name, 10, &irq);
-	if (retval)
-		return retval;
-
-	entry = irq_get_msi_desc(irq);
-	if (!entry)
-		return -ENODEV;
-
-	if (dev_is_pci(dev))
-		is_msix = entry->pci.msi_attrib.is_msix;
+	/* MSI vs. MSIX is per device not per interrupt */
+	bool is_msix = msi_device_has_property(dev, MSI_PROP_PCI_MSIX);
 
 	return sysfs_emit(buf, "%s\n", is_msix ? "msix" : "msi");
 }


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 24/37] powerpc/cell/axon_msi: Use MSI device properties
  2021-11-27  1:20 ` [patch 24/37] powerpc/cell/axon_msi: Use MSI device properties Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

instead of fiddling with MSI descriptors.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/powerpc/platforms/cell/axon_msi.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -199,7 +199,7 @@ static struct axon_msic *find_msi_transl
 static int setup_msi_msg_address(struct pci_dev *dev, struct msi_msg *msg)
 {
 	struct device_node *dn;
-	struct msi_desc *entry;
+	bool is_64bit;
 	int len;
 	const u32 *prop;
 
@@ -209,10 +209,10 @@ static int setup_msi_msg_address(struct
 		return -ENODEV;
 	}
 
-	entry = first_pci_msi_entry(dev);
+	is_64bit = msi_device_has_property(MSI_PROP_64BIT);
 
 	for (; dn; dn = of_get_next_parent(dn)) {
-		if (entry->pci.msi_attrib.is_64) {
+		if (is_64bit) {
 			prop = of_get_property(dn, "msi-address-64", &len);
 			if (prop)
 				break;


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 25/37] powerpc/pseries/msi: Use MSI device properties
  2021-11-27  1:20 ` [patch 25/37] powerpc/pseries/msi: " Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

instead of fiddling with MSI descriptors.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/powerpc/platforms/pseries/msi.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/arch/powerpc/platforms/pseries/msi.c
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -447,9 +447,9 @@ static int rtas_prepare_msi_irqs(struct
 static int pseries_msi_ops_prepare(struct irq_domain *domain, struct device *dev,
 				   int nvec, msi_alloc_info_t *arg)
 {
+	bool is_msix = msi_device_has_property(dev, MSI_PROP_PCI_MSIX);
+	int type = is_msix ? PCI_CAP_ID_MSIX : PCI_CAP_ID_MSI;
 	struct pci_dev *pdev = to_pci_dev(dev);
-	struct msi_desc *desc = first_pci_msi_entry(pdev);
-	int type = desc->pci.msi_attrib.is_msix ? PCI_CAP_ID_MSIX : PCI_CAP_ID_MSI;
 
 	return rtas_prepare_msi_irqs(pdev, nvec, type, arg);
 }


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 26/37] PCI/MSI: Provide MSI_FLAG_MSIX_CONTIGUOUS
  2021-11-27  1:20 ` [patch 26/37] PCI/MSI: Provide MSI_FLAG_MSIX_CONTIGUOUS Thomas Gleixner
@ 2021-11-27  1:21   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:21 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Provide a domain info flag which makes the core code check for a contiguous
MSI-X index on allocation. That's simpler than checking it at some other
domain callback in architecture code.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/pci/msi/irqdomain.c |   16 ++++++++++++++--
 include/linux/msi.h         |    2 ++
 2 files changed, 16 insertions(+), 2 deletions(-)

--- a/drivers/pci/msi/irqdomain.c
+++ b/drivers/pci/msi/irqdomain.c
@@ -89,9 +89,21 @@ static int pci_msi_domain_check_cap(stru
 	if (pci_msi_desc_is_multi_msi(desc) &&
 	    !(info->flags & MSI_FLAG_MULTI_PCI_MSI))
 		return 1;
-	else if (desc->pci.msi_attrib.is_msix && !(info->flags & MSI_FLAG_PCI_MSIX))
-		return -ENOTSUPP;
 
+	if (desc->pci.msi_attrib.is_msix) {
+		if (!(info->flags & MSI_FLAG_PCI_MSIX))
+			return -ENOTSUPP;
+
+		if (info->flags & MSI_FLAG_MSIX_CONTIGUOUS) {
+			unsigned int idx = 0;
+
+			/* Check for gaps in the entry indices */
+			for_each_msi_entry(desc, dev) {
+				if (desc->msi_index != idx++)
+					return -ENOTSUPP;
+			}
+		}
+	}
 	return 0;
 }
 
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -378,6 +378,8 @@ enum {
 	MSI_FLAG_LEVEL_CAPABLE		= (1 << 6),
 	/* Populate sysfs on alloc() and destroy it on free() */
 	MSI_FLAG_DEV_SYSFS		= (1 << 7),
+	/* MSI-X entries must be contiguous */
+	MSI_FLAG_MSIX_CONTIGUOUS	= (1 << 8),
 };
 
 int msi_domain_set_affinity(struct irq_data *data, const struct cpumask *mask,


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 27/37] powerpc/pseries/msi: Let core code check for contiguous entries
  2021-11-27  1:20 ` [patch 27/37] powerpc/pseries/msi: Let core code check for contiguous entries Thomas Gleixner
@ 2021-11-27  1:22   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:22 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Set the domain info flag and remove the check.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/powerpc/platforms/pseries/msi.c |   32 +++++++++-----------------------
 1 file changed, 9 insertions(+), 23 deletions(-)

--- a/arch/powerpc/platforms/pseries/msi.c
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -321,27 +321,6 @@ static int msi_quota_for_device(struct p
 	return request;
 }
 
-static int check_msix_entries(struct pci_dev *pdev)
-{
-	struct msi_desc *entry;
-	int expected;
-
-	/* There's no way for us to express to firmware that we want
-	 * a discontiguous, or non-zero based, range of MSI-X entries.
-	 * So we must reject such requests. */
-
-	expected = 0;
-	for_each_pci_msi_entry(entry, pdev) {
-		if (entry->msi_index != expected) {
-			pr_debug("rtas_msi: bad MSI-X entries.\n");
-			return -EINVAL;
-		}
-		expected++;
-	}
-
-	return 0;
-}
-
 static void rtas_hack_32bit_msi_gen2(struct pci_dev *pdev)
 {
 	u32 addr_hi, addr_lo;
@@ -380,7 +359,7 @@ static int rtas_prepare_msi_irqs(struct
 	if (quota && quota < nvec)
 		return quota;
 
-	if (type == PCI_CAP_ID_MSIX && check_msix_entries(pdev))
+	if (type == PCI_CAP_ID_MSIX)
 		return -EINVAL;
 
 	/*
@@ -530,9 +509,16 @@ static struct irq_chip pseries_pci_msi_i
 	.irq_write_msi_msg	= pseries_msi_write_msg,
 };
 
+
+/*
+ * Set MSI_FLAG_MSIX_CONTIGUOUS as there is no way to express to
+ * firmware to request a discontiguous or non-zero based range of
+ * MSI-X entries. Core code will reject such setup attempts.
+ */
 static struct msi_domain_info pseries_msi_domain_info = {
 	.flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-		  MSI_FLAG_MULTI_PCI_MSI  | MSI_FLAG_PCI_MSIX),
+		  MSI_FLAG_MULTI_PCI_MSI  | MSI_FLAG_PCI_MSIX |
+		  MSI_FLAG_MSIX_CONTIGUOUS),
 	.ops   = &pseries_pci_msi_domain_ops,
 	.chip  = &pseries_pci_msi_irq_chip,
 };


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 28/37] genirq/msi: Provide interface to retrieve Linux interrupt number
  2021-11-27  1:20 ` [patch 28/37] genirq/msi: Provide interface to retrieve Linux interrupt number Thomas Gleixner
@ 2021-11-27  1:22   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:22 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

This allows drivers to retrieve the Linux interrupt number instead of
fiddling with MSI descriptors.

msi_get_virq() returns the Linux interrupt number or 0, __msi_get_virq()
has more detailed return codes so pci_irq_vector() can use it as well.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/msi.h |   16 ++++++++++++++++
 kernel/irq/msi.c    |   38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+)

--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -169,6 +169,22 @@ static inline bool msi_device_has_proper
 }
 #endif
 
+int __msi_get_virq(struct device *dev, unsigned int index);
+
+/**
+ * msi_get_virq - Return Linux interrupt number of a MSI interrupt
+ * @dev:	Device to operate on
+ * @index:	MSI interrupt index to look for (0-based)
+ *
+ * Return: The Linux interrupt number on success (> 0), 0 if not found
+ */
+static inline unsigned int msi_get_virq(struct device *dev, unsigned int index)
+{
+	int ret = __msi_get_virq(dev, index);
+
+	return ret < 0 ? 0 : ret;
+}
+
 /* Helpers to hide struct msi_desc implementation details */
 #define msi_desc_to_dev(desc)		((desc)->dev)
 #define dev_to_msi_list(dev)		(&(dev)->msi_list)
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -120,6 +120,44 @@ int msi_setup_device_data(struct device
 	return 0;
 }
 
+/**
+ * __msi_get_virq - Return Linux interrupt number of a MSI interrupt
+ * @dev:	Device to operate on
+ * @index:	MSI interrupt index to look for (0-based)
+ *
+ * Return: The Linux interrupt number on success (> 0)
+ *	   -ENODEV when the device is not using MSI
+ *	   -ENOENT if no such entry exists
+ */
+int __msi_get_virq(struct device *dev, unsigned int index)
+{
+	struct msi_desc *desc;
+	bool pcimsi;
+
+	if (!dev->msi.data)
+		return -ENODEV;
+
+	pcimsi = msi_device_has_property(dev, MSI_PROP_PCI_MSI);
+
+	for_each_msi_entry(desc, dev) {
+		/* PCI-MSI has only one descriptor for multiple interrupts. */
+		if (pcimsi) {
+			if (desc->irq && index < desc->nvec_used)
+				return desc->irq + index;
+			break;
+		}
+
+		/*
+		 * PCI-MSIX and platform MSI use a descriptor per
+		 * interrupt.
+		 */
+		if (desc->msi_index == index)
+			return desc->irq;
+	}
+	return -ENOENT;
+}
+EXPORT_SYMBOL_GPL(__msi_get_virq);
+
 #ifdef CONFIG_SYSFS
 static ssize_t msi_mode_show(struct device *dev, struct device_attribute *attr,
 			     char *buf)


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 29/37] PCI/MSI: Use __msi_get_virq() in pci_get_vector()
  2021-11-27  1:20 ` [patch 29/37] PCI/MSI: Use __msi_get_virq() in pci_get_vector() Thomas Gleixner
@ 2021-11-27  1:22   ` Thomas Gleixner
  2021-11-28 19:37   ` Marc Zyngier
  1 sibling, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:22 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Use __msi_get_vector() and handle the return values to be compatible.

No functional change intended.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/pci/msi/msi.c |   25 +++++--------------------
 1 file changed, 5 insertions(+), 20 deletions(-)

--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -1023,28 +1023,13 @@ EXPORT_SYMBOL(pci_free_irq_vectors);
  */
 int pci_irq_vector(struct pci_dev *dev, unsigned int nr)
 {
-	if (dev->msix_enabled) {
-		struct msi_desc *entry;
+	int irq = __msi_get_virq(&dev->dev, nr);
 
-		for_each_pci_msi_entry(entry, dev) {
-			if (entry->msi_index == nr)
-				return entry->irq;
-		}
-		WARN_ON_ONCE(1);
-		return -EINVAL;
+	switch (irq) {
+	case -ENODEV: return !nr ? dev->irq : -EINVAL;
+	case -ENOENT: return -EINVAL;
 	}
-
-	if (dev->msi_enabled) {
-		struct msi_desc *entry = first_pci_msi_entry(dev);
-
-		if (WARN_ON_ONCE(nr >= entry->nvec_used))
-			return -EINVAL;
-	} else {
-		if (WARN_ON_ONCE(nr > 0))
-			return -EINVAL;
-	}
-
-	return dev->irq + nr;
+	return irq;
 }
 EXPORT_SYMBOL(pci_irq_vector);
 


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 30/37] PCI/MSI: Simplify pci_irq_get_affinity()
  2021-11-27  1:20 ` [patch 30/37] PCI/MSI: Simplify pci_irq_get_affinity() Thomas Gleixner
@ 2021-11-27  1:22   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:22 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Replace open coded MSI descriptor chasing and use the proper accessor
functions instead.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/pci/msi/msi.c |   26 ++++++++++----------------
 1 file changed, 10 insertions(+), 16 deletions(-)

--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -1040,26 +1040,20 @@ EXPORT_SYMBOL(pci_irq_vector);
  */
 const struct cpumask *pci_irq_get_affinity(struct pci_dev *dev, int nr)
 {
-	if (dev->msix_enabled) {
-		struct msi_desc *entry;
+	int irq = pci_irq_vector(dev, nr);
+	struct msi_desc *desc;
 
-		for_each_pci_msi_entry(entry, dev) {
-			if (entry->msi_index == nr)
-				return &entry->affinity->mask;
-		}
-		WARN_ON_ONCE(1);
+	if (WARN_ON_ONCE(irq <= 0))
 		return NULL;
-	} else if (dev->msi_enabled) {
-		struct msi_desc *entry = first_pci_msi_entry(dev);
 
-		if (WARN_ON_ONCE(!entry || !entry->affinity ||
-				 nr >= entry->nvec_used))
-			return NULL;
-
-		return &entry->affinity[nr].mask;
-	} else {
+	desc = irq_get_msi_desc(irq);
+	/* Non-MSI does not have the information handy */
+	if (!desc)
 		return cpu_possible_mask;
-	}
+
+	if (WARN_ON_ONCE(!desc->affinity))
+		return NULL;
+	return &desc->affinity[nr].mask;
 }
 EXPORT_SYMBOL(pci_irq_get_affinity);
 


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 31/37] dmaengine: mv_xor_v2: Get rid of msi_desc abuse
  2021-11-27  1:20 ` [patch 31/37] dmaengine: mv_xor_v2: Get rid of msi_desc abuse Thomas Gleixner
@ 2021-11-27  1:22   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:22 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, dmaengine, Vinod Koul, Santosh Shilimkar,
	iommu, Stuart Yoder, Laurentiu Tudor, Nishanth Menon,
	Tero Kristo, linux-arm-kernel, x86, Mark Rutland, Will Deacon,
	Sinan Kaya

Storing a pointer to the MSI descriptor just to keep track of the Linux
interrupt number is daft. Use msi_get_virq() instead.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: dmaengine@vger.kernel.org
Cc: Vinod Koul <vkoul@kernel.org>
---
 drivers/dma/mv_xor_v2.c |   16 +++++-----------
 1 file changed, 5 insertions(+), 11 deletions(-)

--- a/drivers/dma/mv_xor_v2.c
+++ b/drivers/dma/mv_xor_v2.c
@@ -149,7 +149,7 @@ struct mv_xor_v2_descriptor {
  * @desc_size: HW descriptor size
  * @npendings: number of pending descriptors (for which tx_submit has
  * @hw_queue_idx: HW queue index
- * @msi_desc: local interrupt descriptor information
+ * @irq: The Linux interrupt number
  * been called, but not yet issue_pending)
  */
 struct mv_xor_v2_device {
@@ -168,7 +168,7 @@ struct mv_xor_v2_device {
 	int desc_size;
 	unsigned int npendings;
 	unsigned int hw_queue_idx;
-	struct msi_desc *msi_desc;
+	unsigned int irq;
 };
 
 /**
@@ -718,7 +718,6 @@ static int mv_xor_v2_probe(struct platfo
 	int i, ret = 0;
 	struct dma_device *dma_dev;
 	struct mv_xor_v2_sw_desc *sw_desc;
-	struct msi_desc *msi_desc;
 
 	BUILD_BUG_ON(sizeof(struct mv_xor_v2_descriptor) !=
 		     MV_XOR_V2_EXT_DESC_SIZE);
@@ -770,14 +769,9 @@ static int mv_xor_v2_probe(struct platfo
 	if (ret)
 		goto disable_clk;
 
-	msi_desc = first_msi_entry(&pdev->dev);
-	if (!msi_desc) {
-		ret = -ENODEV;
-		goto free_msi_irqs;
-	}
-	xor_dev->msi_desc = msi_desc;
+	xor_dev->irq = msi_get_virq(&pdev->dev, 0);
 
-	ret = devm_request_irq(&pdev->dev, msi_desc->irq,
+	ret = devm_request_irq(&pdev->dev, xor_dev->irq,
 			       mv_xor_v2_interrupt_handler, 0,
 			       dev_name(&pdev->dev), xor_dev);
 	if (ret)
@@ -892,7 +886,7 @@ static int mv_xor_v2_remove(struct platf
 			  xor_dev->desc_size * MV_XOR_V2_DESC_NUM,
 			  xor_dev->hw_desq_virt, xor_dev->hw_desq);
 
-	devm_free_irq(&pdev->dev, xor_dev->msi_desc->irq, xor_dev);
+	devm_free_irq(&pdev->dev, xor_dev->irq, xor_dev);
 
 	platform_msi_domain_free_irqs(&pdev->dev);
 


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 32/37] perf/smmuv3: Use msi_get_virq()
  2021-11-27  1:20 ` [patch 32/37] perf/smmuv3: Use msi_get_virq() Thomas Gleixner
@ 2021-11-27  1:22   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:22 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Mark Rutland, Will Deacon, linux-arm-kernel,
	Santosh Shilimkar, iommu, dmaengine, Stuart Yoder,
	Laurentiu Tudor, Nishanth Menon, Tero Kristo, x86, Vinod Koul,
	Sinan Kaya

Let the core code fiddle with the MSI descriptor retrieval.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
---
 drivers/perf/arm_smmuv3_pmu.c |    5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

--- a/drivers/perf/arm_smmuv3_pmu.c
+++ b/drivers/perf/arm_smmuv3_pmu.c
@@ -684,7 +684,6 @@ static void smmu_pmu_write_msi_msg(struc
 
 static void smmu_pmu_setup_msi(struct smmu_pmu *pmu)
 {
-	struct msi_desc *desc;
 	struct device *dev = pmu->dev;
 	int ret;
 
@@ -701,9 +700,7 @@ static void smmu_pmu_setup_msi(struct sm
 		return;
 	}
 
-	desc = first_msi_entry(dev);
-	if (desc)
-		pmu->irq = desc->irq;
+	pmu->irq = msi_get_virq(dev, 0);
 
 	/* Add callback to free MSIs on teardown */
 	devm_add_action(dev, smmu_pmu_free_msis, dev);


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 33/37] iommu/arm-smmu-v3: Use msi_get_virq()
  2021-11-27  1:20 ` [patch 33/37] iommu/arm-smmu-v3: " Thomas Gleixner
@ 2021-11-27  1:22   ` Thomas Gleixner
  2021-11-29 10:55   ` Will Deacon
  2021-11-29 13:25   ` Robin Murphy
  2 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:22 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Let the core code fiddle with the MSI descriptor retrieval.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |   19 +++----------------
 1 file changed, 3 insertions(+), 16 deletions(-)

--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3154,7 +3154,6 @@ static void arm_smmu_write_msi_msg(struc
 
 static void arm_smmu_setup_msis(struct arm_smmu_device *smmu)
 {
-	struct msi_desc *desc;
 	int ret, nvec = ARM_SMMU_MAX_MSIS;
 	struct device *dev = smmu->dev;
 
@@ -3182,21 +3181,9 @@ static void arm_smmu_setup_msis(struct a
 		return;
 	}
 
-	for_each_msi_entry(desc, dev) {
-		switch (desc->msi_index) {
-		case EVTQ_MSI_INDEX:
-			smmu->evtq.q.irq = desc->irq;
-			break;
-		case GERROR_MSI_INDEX:
-			smmu->gerr_irq = desc->irq;
-			break;
-		case PRIQ_MSI_INDEX:
-			smmu->priq.q.irq = desc->irq;
-			break;
-		default:	/* Unknown */
-			continue;
-		}
-	}
+	smmu->evtq.q.irq = msi_get_virq(dev, EVTQ_MSI_INDEX);
+	smmu->gerr_irq = msi_get_virq(dev, GERROR_MSI_INDEX);
+	smmu->priq.q.irq = msi_get_virq(dev, PRIQ_MSI_INDEX);
 
 	/* Add callback to free MSIs on teardown */
 	devm_add_action(dev, arm_smmu_free_msis, dev);


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 34/37] mailbox: bcm-flexrm-mailbox: Rework MSI interrupt handling
  2021-11-27  1:21 ` [patch 34/37] mailbox: bcm-flexrm-mailbox: Rework MSI interrupt handling Thomas Gleixner
@ 2021-11-27  1:22   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:22 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

No point in retrieving the MSI descriptors. Just query the Linux interrupt
number.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/mailbox/bcm-flexrm-mailbox.c |    7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

--- a/drivers/mailbox/bcm-flexrm-mailbox.c
+++ b/drivers/mailbox/bcm-flexrm-mailbox.c
@@ -1497,7 +1497,6 @@ static int flexrm_mbox_probe(struct plat
 	int index, ret = 0;
 	void __iomem *regs;
 	void __iomem *regs_end;
-	struct msi_desc *desc;
 	struct resource *iomem;
 	struct flexrm_ring *ring;
 	struct flexrm_mbox *mbox;
@@ -1608,10 +1607,8 @@ static int flexrm_mbox_probe(struct plat
 		goto fail_destroy_cmpl_pool;
 
 	/* Save alloced IRQ numbers for each ring */
-	for_each_msi_entry(desc, dev) {
-		ring = &mbox->rings[desc->msi_index];
-		ring->irq = desc->irq;
-	}
+	for (index = 0; index < mbox->num_rings; index++)
+		mbox->rings[index].irq = msi_get_virq(dev, index);
 
 	/* Check availability of debugfs */
 	if (!debugfs_initialized())


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 35/37] bus: fsl-mc: fsl-mc-allocator: Rework MSI handling
  2021-11-27  1:21 ` [patch 35/37] bus: fsl-mc: fsl-mc-allocator: Rework MSI handling Thomas Gleixner
@ 2021-11-27  1:22   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:22 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Stuart Yoder, Santosh Shilimkar, iommu,
	dmaengine, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Storing a pointer to the MSI descriptor just to track the Linux interrupt
number is daft. Just store the interrupt number and be done with it.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Stuart Yoder <stuyoder@gmail.com>
---
 drivers/bus/fsl-mc/dprc-driver.c                    |    8 ++++----
 drivers/bus/fsl-mc/fsl-mc-allocator.c               |    9 ++-------
 drivers/bus/fsl-mc/fsl-mc-msi.c                     |    6 +++---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c    |    4 ++--
 drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c    |    4 +---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c |    5 ++---
 drivers/soc/fsl/dpio/dpio-driver.c                  |    8 ++++----
 drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c              |    4 ++--
 include/linux/fsl/mc.h                              |    4 ++--
 9 files changed, 22 insertions(+), 30 deletions(-)

--- a/drivers/bus/fsl-mc/dprc-driver.c
+++ b/drivers/bus/fsl-mc/dprc-driver.c
@@ -400,7 +400,7 @@ static irqreturn_t dprc_irq0_handler_thr
 	struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
 	struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
 	struct fsl_mc_io *mc_io = mc_dev->mc_io;
-	struct msi_desc *msi_desc = mc_dev->irqs[0]->msi_desc;
+	int irq = mc_dev->irqs[0]->virq;
 
 	dev_dbg(dev, "DPRC IRQ %d triggered on CPU %u\n",
 		irq_num, smp_processor_id());
@@ -409,7 +409,7 @@ static irqreturn_t dprc_irq0_handler_thr
 		return IRQ_HANDLED;
 
 	mutex_lock(&mc_bus->scan_mutex);
-	if (!msi_desc || msi_desc->irq != (u32)irq_num)
+	if (irq != (u32)irq_num)
 		goto out;
 
 	status = 0;
@@ -521,7 +521,7 @@ static int register_dprc_irq_handler(str
 	 * function that programs the MSI physically in the device
 	 */
 	error = devm_request_threaded_irq(&mc_dev->dev,
-					  irq->msi_desc->irq,
+					  irq->virq,
 					  dprc_irq0_handler,
 					  dprc_irq0_handler_thread,
 					  IRQF_NO_SUSPEND | IRQF_ONESHOT,
@@ -771,7 +771,7 @@ static void dprc_teardown_irq(struct fsl
 
 	(void)disable_dprc_irq(mc_dev);
 
-	devm_free_irq(&mc_dev->dev, irq->msi_desc->irq, &mc_dev->dev);
+	devm_free_irq(&mc_dev->dev, irq->virq, &mc_dev->dev);
 
 	fsl_mc_free_irqs(mc_dev);
 }
--- a/drivers/bus/fsl-mc/fsl-mc-allocator.c
+++ b/drivers/bus/fsl-mc/fsl-mc-allocator.c
@@ -350,7 +350,6 @@ int fsl_mc_populate_irq_pool(struct fsl_
 			     unsigned int irq_count)
 {
 	unsigned int i;
-	struct msi_desc *msi_desc;
 	struct fsl_mc_device_irq *irq_resources;
 	struct fsl_mc_device_irq *mc_dev_irq;
 	int error;
@@ -388,16 +387,12 @@ int fsl_mc_populate_irq_pool(struct fsl_
 		mc_dev_irq->resource.type = res_pool->type;
 		mc_dev_irq->resource.data = mc_dev_irq;
 		mc_dev_irq->resource.parent_pool = res_pool;
+		mc_dev_irq->virq = msi_get_virq(&mc_bus_dev->dev, i);
+		mc_dev_irq->resource.id = mc_dev_irq->virq;
 		INIT_LIST_HEAD(&mc_dev_irq->resource.node);
 		list_add_tail(&mc_dev_irq->resource.node, &res_pool->free_list);
 	}
 
-	for_each_msi_entry(msi_desc, &mc_bus_dev->dev) {
-		mc_dev_irq = &irq_resources[msi_desc->msi_index];
-		mc_dev_irq->msi_desc = msi_desc;
-		mc_dev_irq->resource.id = msi_desc->irq;
-	}
-
 	res_pool->max_count = irq_count;
 	res_pool->free_count = irq_count;
 	mc_bus->irq_resources = irq_resources;
--- a/drivers/bus/fsl-mc/fsl-mc-msi.c
+++ b/drivers/bus/fsl-mc/fsl-mc-msi.c
@@ -58,11 +58,11 @@ static void fsl_mc_msi_update_dom_ops(st
 }
 
 static void __fsl_mc_msi_write_msg(struct fsl_mc_device *mc_bus_dev,
-				   struct fsl_mc_device_irq *mc_dev_irq)
+				   struct fsl_mc_device_irq *mc_dev_irq,
+				   struct msi_desc *msi_desc)
 {
 	int error;
 	struct fsl_mc_device *owner_mc_dev = mc_dev_irq->mc_dev;
-	struct msi_desc *msi_desc = mc_dev_irq->msi_desc;
 	struct dprc_irq_cfg irq_cfg;
 
 	/*
@@ -129,7 +129,7 @@ static void fsl_mc_msi_write_msg(struct
 	/*
 	 * Program the MSI (paddr, value) pair in the device:
 	 */
-	__fsl_mc_msi_write_msg(mc_bus_dev, mc_dev_irq);
+	__fsl_mc_msi_write_msg(mc_bus_dev, mc_dev_irq, msi_desc);
 }
 
 static void fsl_mc_msi_update_chip_ops(struct msi_domain_info *info)
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -4246,7 +4246,7 @@ static int dpaa2_eth_setup_irqs(struct f
 	}
 
 	irq = ls_dev->irqs[0];
-	err = devm_request_threaded_irq(&ls_dev->dev, irq->msi_desc->irq,
+	err = devm_request_threaded_irq(&ls_dev->dev, irq->virq,
 					NULL, dpni_irq0_handler_thread,
 					IRQF_NO_SUSPEND | IRQF_ONESHOT,
 					dev_name(&ls_dev->dev), &ls_dev->dev);
@@ -4273,7 +4273,7 @@ static int dpaa2_eth_setup_irqs(struct f
 	return 0;
 
 free_irq:
-	devm_free_irq(&ls_dev->dev, irq->msi_desc->irq, &ls_dev->dev);
+	devm_free_irq(&ls_dev->dev, irq->virq, &ls_dev->dev);
 free_mc_irq:
 	fsl_mc_free_irqs(ls_dev);
 
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c
@@ -129,7 +129,6 @@ static irqreturn_t dpaa2_ptp_irq_handler
 static int dpaa2_ptp_probe(struct fsl_mc_device *mc_dev)
 {
 	struct device *dev = &mc_dev->dev;
-	struct fsl_mc_device_irq *irq;
 	struct ptp_qoriq *ptp_qoriq;
 	struct device_node *node;
 	void __iomem *base;
@@ -177,8 +176,7 @@ static int dpaa2_ptp_probe(struct fsl_mc
 		goto err_unmap;
 	}
 
-	irq = mc_dev->irqs[0];
-	ptp_qoriq->irq = irq->msi_desc->irq;
+	ptp_qoriq->irq = mc_dev->irqs[0]->virq;
 
 	err = request_threaded_irq(ptp_qoriq->irq, NULL,
 				   dpaa2_ptp_irq_handler_thread,
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
@@ -1553,8 +1553,7 @@ static int dpaa2_switch_setup_irqs(struc
 
 	irq = sw_dev->irqs[DPSW_IRQ_INDEX_IF];
 
-	err = devm_request_threaded_irq(dev, irq->msi_desc->irq,
-					NULL,
+	err = devm_request_threaded_irq(dev, irq->virq, NULL,
 					dpaa2_switch_irq0_handler_thread,
 					IRQF_NO_SUSPEND | IRQF_ONESHOT,
 					dev_name(dev), dev);
@@ -1580,7 +1579,7 @@ static int dpaa2_switch_setup_irqs(struc
 	return 0;
 
 free_devm_irq:
-	devm_free_irq(dev, irq->msi_desc->irq, dev);
+	devm_free_irq(dev, irq->virq, dev);
 free_irq:
 	fsl_mc_free_irqs(sw_dev);
 	return err;
--- a/drivers/soc/fsl/dpio/dpio-driver.c
+++ b/drivers/soc/fsl/dpio/dpio-driver.c
@@ -88,7 +88,7 @@ static void unregister_dpio_irq_handlers
 	irq = dpio_dev->irqs[0];
 
 	/* clear the affinity hint */
-	irq_set_affinity_hint(irq->msi_desc->irq, NULL);
+	irq_set_affinity_hint(irq->virq, NULL);
 }
 
 static int register_dpio_irq_handlers(struct fsl_mc_device *dpio_dev, int cpu)
@@ -98,7 +98,7 @@ static int register_dpio_irq_handlers(st
 
 	irq = dpio_dev->irqs[0];
 	error = devm_request_irq(&dpio_dev->dev,
-				 irq->msi_desc->irq,
+				 irq->virq,
 				 dpio_irq_handler,
 				 0,
 				 dev_name(&dpio_dev->dev),
@@ -111,10 +111,10 @@ static int register_dpio_irq_handlers(st
 	}
 
 	/* set the affinity hint */
-	if (irq_set_affinity_hint(irq->msi_desc->irq, cpumask_of(cpu)))
+	if (irq_set_affinity_hint(irq->virq, cpumask_of(cpu)))
 		dev_err(&dpio_dev->dev,
 			"irq_set_affinity failed irq %d cpu %d\n",
-			irq->msi_desc->irq, cpu);
+			irq->virq, cpu);
 
 	return 0;
 }
--- a/drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c
+++ b/drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c
@@ -67,7 +67,7 @@ static int vfio_set_trigger(struct vfio_
 	int hwirq;
 	int ret;
 
-	hwirq = vdev->mc_dev->irqs[index]->msi_desc->irq;
+	hwirq = vdev->mc_dev->irqs[index]->virq;
 	if (irq->trigger) {
 		free_irq(hwirq, irq);
 		kfree(irq->name);
@@ -137,7 +137,7 @@ static int vfio_fsl_mc_set_irq_trigger(s
 		return vfio_set_trigger(vdev, index, fd);
 	}
 
-	hwirq = vdev->mc_dev->irqs[index]->msi_desc->irq;
+	hwirq = vdev->mc_dev->irqs[index]->virq;
 
 	irq = &vdev->mc_irqs[index];
 
--- a/include/linux/fsl/mc.h
+++ b/include/linux/fsl/mc.h
@@ -91,13 +91,13 @@ struct fsl_mc_resource {
 
 /**
  * struct fsl_mc_device_irq - MC object device message-based interrupt
- * @msi_desc: pointer to MSI descriptor allocated by fsl_mc_msi_alloc_descs()
+ * @virq: Linux virtual interrupt number
  * @mc_dev: MC object device that owns this interrupt
  * @dev_irq_index: device-relative IRQ index
  * @resource: MC generic resource associated with the interrupt
  */
 struct fsl_mc_device_irq {
-	struct msi_desc *msi_desc;
+	unsigned int virq;
 	struct fsl_mc_device *mc_dev;
 	u8 dev_irq_index;
 	struct fsl_mc_resource resource;


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 36/37] soc: ti: ti_sci_inta_msi: Get rid of ti_sci_inta_msi_get_virq()
  2021-11-27  1:21 ` [patch 36/37] soc: ti: ti_sci_inta_msi: Get rid of ti_sci_inta_msi_get_virq() Thomas Gleixner
@ 2021-11-27  1:22   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:22 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

Just use the core function msi_get_virq().

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/dma/ti/k3-udma-private.c       |    6 ++----
 drivers/dma/ti/k3-udma.c               |   10 ++++------
 drivers/soc/ti/k3-ringacc.c            |    2 +-
 drivers/soc/ti/ti_sci_inta_msi.c       |   12 ------------
 include/linux/soc/ti/ti_sci_inta_msi.h |    1 -
 5 files changed, 7 insertions(+), 24 deletions(-)

--- a/drivers/dma/ti/k3-udma-private.c
+++ b/drivers/dma/ti/k3-udma-private.c
@@ -168,8 +168,7 @@ int xudma_pktdma_tflow_get_irq(struct ud
 {
 	const struct udma_oes_offsets *oes = &ud->soc_data->oes;
 
-	return ti_sci_inta_msi_get_virq(ud->dev, udma_tflow_id +
-					oes->pktdma_tchan_flow);
+	return msi_get_virq(ud->dev, udma_tflow_id + oes->pktdma_tchan_flow);
 }
 EXPORT_SYMBOL(xudma_pktdma_tflow_get_irq);
 
@@ -177,7 +176,6 @@ int xudma_pktdma_rflow_get_irq(struct ud
 {
 	const struct udma_oes_offsets *oes = &ud->soc_data->oes;
 
-	return ti_sci_inta_msi_get_virq(ud->dev, udma_rflow_id +
-					oes->pktdma_rchan_flow);
+	return msi_get_virq(ud->dev, udma_rflow_id + oes->pktdma_rchan_flow);
 }
 EXPORT_SYMBOL(xudma_pktdma_rflow_get_irq);
--- a/drivers/dma/ti/k3-udma.c
+++ b/drivers/dma/ti/k3-udma.c
@@ -2313,8 +2313,7 @@ static int udma_alloc_chan_resources(str
 
 	/* Event from UDMA (TR events) only needed for slave TR mode channels */
 	if (is_slave_direction(uc->config.dir) && !uc->config.pkt_mode) {
-		uc->irq_num_udma = ti_sci_inta_msi_get_virq(ud->dev,
-							    irq_udma_idx);
+		uc->irq_num_udma = msi_get_virq(ud->dev, irq_udma_idx);
 		if (uc->irq_num_udma <= 0) {
 			dev_err(ud->dev, "Failed to get udma irq (index: %u)\n",
 				irq_udma_idx);
@@ -2486,7 +2485,7 @@ static int bcdma_alloc_chan_resources(st
 		uc->psil_paired = true;
 	}
 
-	uc->irq_num_ring = ti_sci_inta_msi_get_virq(ud->dev, irq_ring_idx);
+	uc->irq_num_ring = msi_get_virq(ud->dev, irq_ring_idx);
 	if (uc->irq_num_ring <= 0) {
 		dev_err(ud->dev, "Failed to get ring irq (index: %u)\n",
 			irq_ring_idx);
@@ -2503,8 +2502,7 @@ static int bcdma_alloc_chan_resources(st
 
 	/* Event from BCDMA (TR events) only needed for slave channels */
 	if (is_slave_direction(uc->config.dir)) {
-		uc->irq_num_udma = ti_sci_inta_msi_get_virq(ud->dev,
-							    irq_udma_idx);
+		uc->irq_num_udma = msi_get_virq(ud->dev, irq_udma_idx);
 		if (uc->irq_num_udma <= 0) {
 			dev_err(ud->dev, "Failed to get bcdma irq (index: %u)\n",
 				irq_udma_idx);
@@ -2672,7 +2670,7 @@ static int pktdma_alloc_chan_resources(s
 
 	uc->psil_paired = true;
 
-	uc->irq_num_ring = ti_sci_inta_msi_get_virq(ud->dev, irq_ring_idx);
+	uc->irq_num_ring = msi_get_virq(ud->dev, irq_ring_idx);
 	if (uc->irq_num_ring <= 0) {
 		dev_err(ud->dev, "Failed to get ring irq (index: %u)\n",
 			irq_ring_idx);
--- a/drivers/soc/ti/k3-ringacc.c
+++ b/drivers/soc/ti/k3-ringacc.c
@@ -647,7 +647,7 @@ int k3_ringacc_get_ring_irq_num(struct k
 	if (!ring)
 		return -EINVAL;
 
-	irq_num = ti_sci_inta_msi_get_virq(ring->parent->dev, ring->ring_id);
+	irq_num = msi_get_virq(ring->parent->dev, ring->ring_id);
 	if (irq_num <= 0)
 		irq_num = -EINVAL;
 	return irq_num;
--- a/drivers/soc/ti/ti_sci_inta_msi.c
+++ b/drivers/soc/ti/ti_sci_inta_msi.c
@@ -148,15 +148,3 @@ void ti_sci_inta_msi_domain_free_irqs(st
 	ti_sci_inta_msi_free_descs(dev);
 }
 EXPORT_SYMBOL_GPL(ti_sci_inta_msi_domain_free_irqs);
-
-unsigned int ti_sci_inta_msi_get_virq(struct device *dev, u32 dev_index)
-{
-	struct msi_desc *desc;
-
-	for_each_msi_entry(desc, dev)
-		if (desc->msi_index == dev_index)
-			return desc->irq;
-
-	return -ENODEV;
-}
-EXPORT_SYMBOL_GPL(ti_sci_inta_msi_get_virq);
--- a/include/linux/soc/ti/ti_sci_inta_msi.h
+++ b/include/linux/soc/ti/ti_sci_inta_msi.h
@@ -18,6 +18,5 @@ struct irq_domain
 				   struct irq_domain *parent);
 int ti_sci_inta_msi_domain_alloc_irqs(struct device *dev,
 				      struct ti_sci_resource *res);
-unsigned int ti_sci_inta_msi_get_virq(struct device *dev, u32 index);
 void ti_sci_inta_msi_domain_free_irqs(struct device *dev);
 #endif /* __INCLUDE_LINUX_IRQCHIP_TI_SCI_INTA_H */


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [patch 37/37] dmaengine: qcom_hidma: Cleanup MSI handling
  2021-11-27  1:21 ` [patch 37/37] dmaengine: qcom_hidma: Cleanup MSI handling Thomas Gleixner
@ 2021-11-27  1:22   ` Thomas Gleixner
  2021-11-29 19:56   ` Sinan Kaya
  1 sibling, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-27  1:22 UTC (permalink / raw)
  To: LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Sinan Kaya, dmaengine, Santosh Shilimkar,
	iommu, Stuart Yoder, Laurentiu Tudor, Nishanth Menon,
	Tero Kristo, linux-arm-kernel, x86, Vinod Koul, Mark Rutland,
	Will Deacon

There is no reason to walk the MSI descriptors to retrieve the interrupt
number for a device. Use msi_get_virq() instead.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Sinan Kaya <okaya@kernel.org>
Cc: dmaengine@vger.kernel.org
---
 drivers/dma/qcom/hidma.c |   42 ++++++++++++++++++------------------------
 1 file changed, 18 insertions(+), 24 deletions(-)

--- a/drivers/dma/qcom/hidma.c
+++ b/drivers/dma/qcom/hidma.c
@@ -678,11 +678,13 @@ static void hidma_free_msis(struct hidma
 {
 #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
 	struct device *dev = dmadev->ddev.dev;
-	struct msi_desc *desc;
+	int i, virq;
 
-	/* free allocated MSI interrupts above */
-	for_each_msi_entry(desc, dev)
-		devm_free_irq(dev, desc->irq, &dmadev->lldev);
+	for (i = 0; i < HIDMA_MSI_INTS; i++) {
+		virq = msi_get_virq(dev, i);
+		if (virq)
+			devm_free_irq(dev, virq, &dmadev->lldev);
+	}
 
 	platform_msi_domain_free_irqs(dev);
 #endif
@@ -692,45 +694,37 @@ static int hidma_request_msi(struct hidm
 			     struct platform_device *pdev)
 {
 #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
-	int rc;
-	struct msi_desc *desc;
-	struct msi_desc *failed_desc = NULL;
+	int rc, i, virq;
 
 	rc = platform_msi_domain_alloc_irqs(&pdev->dev, HIDMA_MSI_INTS,
 					    hidma_write_msi_msg);
 	if (rc)
 		return rc;
 
-	for_each_msi_entry(desc, &pdev->dev) {
-		if (!desc->msi_index)
-			dmadev->msi_virqbase = desc->irq;
-
-		rc = devm_request_irq(&pdev->dev, desc->irq,
+	for (i = 0; i < HIDMA_MSI_INTS; i++) {
+		virq = msi_get_virq(&pdev->dev, i);
+		rc = devm_request_irq(&pdev->dev, virq,
 				       hidma_chirq_handler_msi,
 				       0, "qcom-hidma-msi",
 				       &dmadev->lldev);
-		if (rc) {
-			failed_desc = desc;
+		if (rc)
 			break;
-		}
+		if (!i)
+			dmadev->msi_virqbase = virq;
 	}
 
 	if (rc) {
 		/* free allocated MSI interrupts above */
-		for_each_msi_entry(desc, &pdev->dev) {
-			if (desc == failed_desc)
-				break;
-			devm_free_irq(&pdev->dev, desc->irq,
-				      &dmadev->lldev);
+		for (--i; i >= 0; i--) {
+			virq = msi_get_virq(&pdev->dev, i);
+			devm_free_irq(&pdev->dev, virq, &dmadev->lldev);
 		}
+		dev_warn(&pdev->dev,
+			 "failed to request MSI irq, falling back to wired IRQ\n");
 	} else {
 		/* Add callback to free MSIs on teardown */
 		hidma_ll_setup_irq(dmadev->lldev, true);
-
 	}
-	if (rc)
-		dev_warn(&pdev->dev,
-			 "failed to request MSI irq, falling back to wired IRQ\n");
 	return rc;
 #else
 	return -EINVAL;


^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [patch 01/37] device: Move MSI related data into a struct
  2021-11-27  1:20 ` [patch 01/37] device: Move MSI related data into a struct Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
@ 2021-11-27 12:11   ` Greg Kroah-Hartman
  1 sibling, 0 replies; 97+ messages in thread
From: Greg Kroah-Hartman @ 2021-11-27 12:11 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Santosh Shilimkar, iommu, dmaengine, Stuart Yoder,
	Laurentiu Tudor, Nishanth Menon, Tero Kristo, linux-arm-kernel,
	x86, Vinod Koul, Mark Rutland, Will Deacon, Sinan Kaya

On Sat, Nov 27, 2021 at 02:20:08AM +0100, Thomas Gleixner wrote:
> The only unconditional part of MSI data in struct device is the irqdomain
> pointer. Everything else can be allocated on demand. Create a data
> structure and move the irqdomain pointer into it. The other MSI specific
> parts are going to be removed from struct device in later steps.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Will Deacon <will@kernel.org>
> Cc: Santosh Shilimkar <ssantosh@kernel.org>
> Cc: iommu@lists.linux-foundation.org
> Cc: dmaengine@vger.kernel.org
> ---
>  drivers/base/platform-msi.c                 |   12 ++++++------
>  drivers/dma/ti/k3-udma.c                    |    4 ++--
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |    2 +-
>  drivers/irqchip/irq-mvebu-icu.c             |    6 +++---
>  drivers/soc/ti/k3-ringacc.c                 |    4 ++--
>  drivers/soc/ti/ti_sci_inta_msi.c            |    2 +-
>  include/linux/device.h                      |   19 +++++++++++++------
>  7 files changed, 28 insertions(+), 21 deletions(-)

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [patch 02/37] device: Add device::msi_data pointer and struct msi_device_data
  2021-11-27  1:20 ` [patch 02/37] device: Add device::msi_data pointer and struct msi_device_data Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
@ 2021-11-27 12:12   ` Greg Kroah-Hartman
  2021-11-28  0:14   ` Jason Gunthorpe
  2 siblings, 0 replies; 97+ messages in thread
From: Greg Kroah-Hartman @ 2021-11-27 12:12 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Santosh Shilimkar, iommu, dmaengine, Stuart Yoder,
	Laurentiu Tudor, Nishanth Menon, Tero Kristo, linux-arm-kernel,
	x86, Vinod Koul, Mark Rutland, Will Deacon, Sinan Kaya

On Sat, Nov 27, 2021 at 02:20:09AM +0100, Thomas Gleixner wrote:
> Create struct msi_device_data and add a pointer of that type to struct
> dev_msi_info, which is part of struct device. Provide an allocator function
> which can be invoked from the MSI interrupt allocation code pathes.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
>  include/linux/device.h |    5 +++++
>  include/linux/msi.h    |   12 +++++++++++-
>  kernel/irq/msi.c       |   33 +++++++++++++++++++++++++++++++++
>  3 files changed, 49 insertions(+), 1 deletion(-)

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [patch 04/37] PCI/MSI: Use lock from msi_device_data
  2021-11-27  1:21 ` [patch 04/37] PCI/MSI: Use lock from msi_device_data Thomas Gleixner
  2021-11-27  1:20   ` Thomas Gleixner
@ 2021-11-27 12:13   ` Greg Kroah-Hartman
  1 sibling, 0 replies; 97+ messages in thread
From: Greg Kroah-Hartman @ 2021-11-27 12:13 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Santosh Shilimkar, iommu, dmaengine, Stuart Yoder,
	Laurentiu Tudor, Nishanth Menon, Tero Kristo, linux-arm-kernel,
	x86, Vinod Koul, Mark Rutland, Will Deacon, Sinan Kaya

On Sat, Nov 27, 2021 at 02:20:13AM +0100, Thomas Gleixner wrote:
> Remove the register lock from struct device and use the one in
> struct msi_device_data.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
>  drivers/base/core.c    |    1 -
>  drivers/pci/msi/msi.c  |    2 +-
>  include/linux/device.h |    2 --
>  3 files changed, 1 insertion(+), 4 deletions(-)

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (37 preceding siblings ...)
  2021-11-27  1:21 ` [patch 04/37] PCI/MSI: Use lock from msi_device_data Thomas Gleixner
@ 2021-11-27 12:17 ` Greg Kroah-Hartman
  2021-11-28  0:39 ` Jason Gunthorpe
  39 siblings, 0 replies; 97+ messages in thread
From: Greg Kroah-Hartman @ 2021-11-27 12:17 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Santosh Shilimkar, iommu, dmaengine, Stuart Yoder,
	Laurentiu Tudor, Nishanth Menon, Tero Kristo, linux-arm-kernel,
	x86, Vinod Koul, Mark Rutland, Will Deacon, Sinan Kaya

On Sat, Nov 27, 2021 at 02:20:06AM +0100, Thomas Gleixner wrote:
> This is the second part of [PCI]MSI refactoring which aims to provide the
> ability of expanding MSI-X vectors after enabling MSI-X.
> 
> The first part of this work can be found here:
> 
>     https://lore.kernel.org/r/20211126222700.862407977@linutronix.de
> 
> This second part has the following important changes:
> 
>    1) Cleanup of the MSI related data in struct device
> 
>       struct device contains at the moment various MSI related parts. Some
>       of them (the irq domain pointer) cannot be moved out, but the rest
>       can be allocated on first use. This is in preparation of adding more
>       per device MSI data later on.
> 
>    2) Consolidation of sysfs handling
> 
>       As a first step this moves the sysfs pointer from struct msi_desc
>       into the new per device MSI data structure where it belongs.
> 
>       Later changes will cleanup this code further, but that's not possible
>       at this point.
> 
>    3) Store per device properties in the per device MSI data to avoid
>       looking up MSI descriptors and analysing their data. Cleanup all
>       related use cases.
> 
>    4) Provide a function to retrieve the Linux interrupt number for a given
>       MSI index similar to pci_irq_vector() and cleanup all open coded
>       variants.
> 
> This second series is based on:
> 
>      git://git.kernel.org/pub/scm/linux/kernel/git/tglx/devel.git msi-v1-part-1
> 
> and also available from git:
> 
>      git://git.kernel.org/pub/scm/linux/kernel/git/tglx/devel.git msi-v1-part-2
> 

Instead of responding to each individual patch, I've read them all,
thanks for the cleanups, look good to me:

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [patch 02/37] device: Add device::msi_data pointer and struct msi_device_data
  2021-11-27  1:20 ` [patch 02/37] device: Add device::msi_data pointer and struct msi_device_data Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
  2021-11-27 12:12   ` Greg Kroah-Hartman
@ 2021-11-28  0:14   ` Jason Gunthorpe
  2021-11-28 19:09     ` Thomas Gleixner
  2 siblings, 1 reply; 97+ messages in thread
From: Jason Gunthorpe @ 2021-11-28  0:14 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Megha Dey, Ashok Raj, linux-pci, Greg Kroah-Hartman,
	Santosh Shilimkar, iommu, dmaengine, Stuart Yoder,
	Laurentiu Tudor, Nishanth Menon, Tero Kristo, linux-arm-kernel,
	x86, Vinod Koul, Mark Rutland, Will Deacon, Sinan Kaya

On Sat, Nov 27, 2021 at 02:20:09AM +0100, Thomas Gleixner wrote:

> +/**
> + * msi_setup_device_data - Setup MSI device data
> + * @dev:	Device for which MSI device data should be set up
> + *
> + * Return: 0 on success, appropriate error code otherwise
> + *
> + * This can be called more than once for @dev. If the MSI device data is
> + * already allocated the call succeeds. The allocated memory is
> + * automatically released when the device is destroyed.

I would say 'by devres when the driver is removed' rather than device
is destroyed - to me the latter implies it would happen at device_del
or perhaps during release..

> +int msi_setup_device_data(struct device *dev)
> +{
> +	struct msi_device_data *md;
> +
> +	if (dev->msi.data)
> +		return 0;
> +
> +	md = devres_alloc(msi_device_data_release, sizeof(*md), GFP_KERNEL);
> +	if (!md)
> +		return -ENOMEM;
> +
> +	raw_spin_lock_init(&md->lock);

I also couldn't guess why this needed to be raw?

Jason

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2
  2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
                   ` (38 preceding siblings ...)
  2021-11-27 12:17 ` [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Greg Kroah-Hartman
@ 2021-11-28  0:39 ` Jason Gunthorpe
  2021-11-28 20:27   ` Thomas Gleixner
  39 siblings, 1 reply; 97+ messages in thread
From: Jason Gunthorpe @ 2021-11-28  0:39 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Megha Dey, Ashok Raj, linux-pci, Greg Kroah-Hartman,
	Santosh Shilimkar, iommu, dmaengine, Stuart Yoder,
	Laurentiu Tudor, Nishanth Menon, Tero Kristo, linux-arm-kernel,
	x86, Vinod Koul, Mark Rutland, Will Deacon, Sinan Kaya

On Sat, Nov 27, 2021 at 02:21:17AM +0100, Thomas Gleixner wrote:
> This is the second part of [PCI]MSI refactoring which aims to provide the
> ability of expanding MSI-X vectors after enabling MSI-X.
> 
> The first part of this work can be found here:
> 
>     https://lore.kernel.org/r/20211126222700.862407977@linutronix.de
> 
> This second part has the following important changes:
> 
>    1) Cleanup of the MSI related data in struct device
> 
>       struct device contains at the moment various MSI related parts. Some
>       of them (the irq domain pointer) cannot be moved out, but the rest
>       can be allocated on first use. This is in preparation of adding more
>       per device MSI data later on.
> 
>    2) Consolidation of sysfs handling
> 
>       As a first step this moves the sysfs pointer from struct msi_desc
>       into the new per device MSI data structure where it belongs.
> 
>       Later changes will cleanup this code further, but that's not possible
>       at this point.
> 
>    3) Store per device properties in the per device MSI data to avoid
>       looking up MSI descriptors and analysing their data. Cleanup all
>       related use cases.
> 
>    4) Provide a function to retrieve the Linux interrupt number for a given
>       MSI index similar to pci_irq_vector() and cleanup all open coded
>       variants.

The msi_get_virq() sure does make a big difference.. Though it does
highlight there is some asymmetry with how platform and PCI works here
where PCI fills some 'struct msix_entry *'. Many drivers would be
quite happy to just call msi_get_virq() and avoid the extra memory, so
I think the msi_get_virq() version is good.

Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>

Thanks,
Jason

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [patch 02/37] device: Add device::msi_data pointer and struct msi_device_data
  2021-11-28  0:14   ` Jason Gunthorpe
@ 2021-11-28 19:09     ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-28 19:09 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: LKML, Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Megha Dey, Ashok Raj, linux-pci, Greg Kroah-Hartman,
	Santosh Shilimkar, iommu, dmaengine, Stuart Yoder,
	Laurentiu Tudor, Nishanth Menon, Tero Kristo, linux-arm-kernel,
	x86, Vinod Koul, Mark Rutland, Will Deacon, Sinan Kaya

On Sat, Nov 27 2021 at 20:14, Jason Gunthorpe wrote:
> On Sat, Nov 27, 2021 at 02:20:09AM +0100, Thomas Gleixner wrote:
>
>> +/**
>> + * msi_setup_device_data - Setup MSI device data
>> + * @dev:	Device for which MSI device data should be set up
>> + *
>> + * Return: 0 on success, appropriate error code otherwise
>> + *
>> + * This can be called more than once for @dev. If the MSI device data is
>> + * already allocated the call succeeds. The allocated memory is
>> + * automatically released when the device is destroyed.
>
> I would say 'by devres when the driver is removed' rather than device
> is destroyed - to me the latter implies it would happen at device_del
> or perhaps during release..

Ah. Indeed it's when the driver unbinds because that's what disables MSI.

>> +int msi_setup_device_data(struct device *dev)
>> +{
>> +	struct msi_device_data *md;
>> +
>> +	if (dev->msi.data)
>> +		return 0;
>> +
>> +	md = devres_alloc(msi_device_data_release, sizeof(*md), GFP_KERNEL);
>> +	if (!md)
>> +		return -ENOMEM;
>> +
>> +	raw_spin_lock_init(&md->lock);
>
> I also couldn't guess why this needed to be raw?

That lock is to replace the raw spinlock we have in struct device right
now, which is protecting low level register access and that's called
from within irq_desc::lock held regions with interrupts disabled. I had
to stick something into the data structure because allocating 0 bytes is
invalid. But yes, I should have mentioned it in the changelog.

Thanks,

        tglx



^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [patch 29/37] PCI/MSI: Use __msi_get_virq() in pci_get_vector()
  2021-11-27  1:20 ` [patch 29/37] PCI/MSI: Use __msi_get_virq() in pci_get_vector() Thomas Gleixner
  2021-11-27  1:22   ` Thomas Gleixner
@ 2021-11-28 19:37   ` Marc Zyngier
  2021-11-28 21:00     ` Thomas Gleixner
  1 sibling, 1 reply; 97+ messages in thread
From: Marc Zyngier @ 2021-11-28 19:37 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, Bjorn Helgaas, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

On Sat, 27 Nov 2021 01:22:03 +0000,
Thomas Gleixner <tglx@linutronix.de> wrote:
> 
> Use __msi_get_vector() and handle the return values to be compatible.
> 
> No functional change intended.

You wish ;-).

[   15.779540] pcieport 0001:00:01.0: AER: request AER IRQ -22 failed

Notice how amusing the IRQ number is?

> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
>  drivers/pci/msi/msi.c |   25 +++++--------------------
>  1 file changed, 5 insertions(+), 20 deletions(-)
> 
> --- a/drivers/pci/msi/msi.c
> +++ b/drivers/pci/msi/msi.c
> @@ -1023,28 +1023,13 @@ EXPORT_SYMBOL(pci_free_irq_vectors);
>   */
>  int pci_irq_vector(struct pci_dev *dev, unsigned int nr)
>  {
> -	if (dev->msix_enabled) {
> -		struct msi_desc *entry;
> +	int irq = __msi_get_virq(&dev->dev, nr);
>  
> -		for_each_pci_msi_entry(entry, dev) {
> -			if (entry->msi_index == nr)
> -				return entry->irq;
> -		}
> -		WARN_ON_ONCE(1);
> -		return -EINVAL;
> +	switch (irq) {
> +	case -ENODEV: return !nr ? dev->irq : -EINVAL;
> +	case -ENOENT: return -EINVAL;
>  	}
> -
> -	if (dev->msi_enabled) {
> -		struct msi_desc *entry = first_pci_msi_entry(dev);
> -
> -		if (WARN_ON_ONCE(nr >= entry->nvec_used))
> -			return -EINVAL;
> -	} else {
> -		if (WARN_ON_ONCE(nr > 0))
> -			return -EINVAL;
> -	}
> -
> -	return dev->irq + nr;
> +	return irq;
>  }
>  EXPORT_SYMBOL(pci_irq_vector);

I worked around it with the hack below, but I doubt this is the real
thing. portdrv_core.c does complicated things, and I don't completely
understand its logic.

	M.

diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c
index 1f72bc734226..b15278a5fb4b 100644
--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -1092,8 +1092,9 @@ int pci_irq_vector(struct pci_dev *dev, unsigned int nr)
 	int irq = __msi_get_virq(&dev->dev, nr);
 
 	switch (irq) {
-	case -ENODEV: return !nr ? dev->irq : -EINVAL;
-	case -ENOENT: return -EINVAL;
+	case -ENOENT:
+	case -ENODEV:
+		return !nr ? dev->irq : -EINVAL;
 	}
 	return irq;
 }

-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply related	[flat|nested] 97+ messages in thread

* Re: [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2
  2021-11-28  0:39 ` Jason Gunthorpe
@ 2021-11-28 20:27   ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-28 20:27 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: LKML, Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Megha Dey, Ashok Raj, linux-pci, Greg Kroah-Hartman,
	Santosh Shilimkar, iommu, dmaengine, Stuart Yoder,
	Laurentiu Tudor, Nishanth Menon, Tero Kristo, linux-arm-kernel,
	x86, Vinod Koul, Mark Rutland, Will Deacon, Sinan Kaya

On Sat, Nov 27 2021 at 20:39, Jason Gunthorpe wrote:
> On Sat, Nov 27, 2021 at 02:21:17AM +0100, Thomas Gleixner wrote:
>>    4) Provide a function to retrieve the Linux interrupt number for a given
>>       MSI index similar to pci_irq_vector() and cleanup all open coded
>>       variants.
>
> The msi_get_virq() sure does make a big difference.. Though it does
> highlight there is some asymmetry with how platform and PCI works here
> where PCI fills some 'struct msix_entry *'. Many drivers would be
> quite happy to just call msi_get_virq() and avoid the extra memory, so
> I think the msi_get_virq() version is good.

struct msix_entry should just go away.

90+% of the use cases fill it with a linear index range 0...N and then
use the virq entry for request_irq(). So they can just use
pci_alloc_irs_vectors_affinity() and retrieve the interrupt number via
pci_irq_vector().

The few drivers which actually use it to allocate a sparse populated MSI
index, e.g. 0, 12, 14 can be converted over to alloc vector 0 and then
use the dynamic extenstion for the rest.

Thanks,

        tglx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [patch 29/37] PCI/MSI: Use __msi_get_virq() in pci_get_vector()
  2021-11-28 19:37   ` Marc Zyngier
@ 2021-11-28 21:00     ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-28 21:00 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: LKML, Bjorn Helgaas, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon,
	Sinan Kaya

On Sun, Nov 28 2021 at 19:37, Marc Zyngier wrote:
> On Sat, 27 Nov 2021 01:22:03 +0000,
> Thomas Gleixner <tglx@linutronix.de> wrote:
>
> I worked around it with the hack below, but I doubt this is the real
> thing. portdrv_core.c does complicated things, and I don't completely
> understand its logic.
>
> 	M.
>
> diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c
> index 1f72bc734226..b15278a5fb4b 100644
> --- a/drivers/pci/msi/msi.c
> +++ b/drivers/pci/msi/msi.c
> @@ -1092,8 +1092,9 @@ int pci_irq_vector(struct pci_dev *dev, unsigned int nr)
>  	int irq = __msi_get_virq(&dev->dev, nr);
>  
>  	switch (irq) {
> -	case -ENODEV: return !nr ? dev->irq : -EINVAL;
> -	case -ENOENT: return -EINVAL;
> +	case -ENOENT:
> +	case -ENODEV:
> +		return !nr ? dev->irq : -EINVAL;

Hrm. ENODEV is returned when dev->msi.data == NULL, ENOENT when there is
no MSI entry. But yes, that goes south when the device tried to enable
MSI[X} and then ended up with INTx. It still has dev->msi.data, which
causes it to return -ENOENT, which makes the above go belly up.

Moo, what was I thinking?

Thanks,

        tglx
---
--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -1032,13 +1032,13 @@ EXPORT_SYMBOL(pci_free_irq_vectors);
  */
 int pci_irq_vector(struct pci_dev *dev, unsigned int nr)
 {
-	int irq = __msi_get_virq(&dev->dev, nr);
+	unsigned int irq;
 
-	switch (irq) {
-	case -ENODEV: return !nr ? dev->irq : -EINVAL;
-	case -ENOENT: return -EINVAL;
-	}
-	return irq;
+	if (!dev->msi_enabled && !dev->msix_enabled)
+		return !nr ? dev->irq : -EINVAL;
+
+	irq = msi_get_virq(&dev->dev, nr);
+	return irq ? irq : -EINVAL;
 }
 EXPORT_SYMBOL(pci_irq_vector);
 
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -169,21 +169,7 @@ static inline bool msi_device_has_proper
 }
 #endif
 
-int __msi_get_virq(struct device *dev, unsigned int index);
-
-/**
- * msi_get_virq - Return Linux interrupt number of a MSI interrupt
- * @dev:	Device to operate on
- * @index:	MSI interrupt index to look for (0-based)
- *
- * Return: The Linux interrupt number on success (> 0), 0 if not found
- */
-static inline unsigned int msi_get_virq(struct device *dev, unsigned int index)
-{
-	int ret = __msi_get_virq(dev, index);
-
-	return ret < 0 ? 0 : ret;
-}
+unsigned int msi_get_virq(struct device *dev, unsigned int index);
 
 /* Helpers to hide struct msi_desc implementation details */
 #define msi_desc_to_dev(desc)		((desc)->dev)
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -119,21 +119,19 @@ int msi_setup_device_data(struct device
 }
 
 /**
- * __msi_get_virq - Return Linux interrupt number of a MSI interrupt
+ * msi_get_virq - Return Linux interrupt number of a MSI interrupt
  * @dev:	Device to operate on
  * @index:	MSI interrupt index to look for (0-based)
  *
- * Return: The Linux interrupt number on success (> 0)
- *	   -ENODEV when the device is not using MSI
- *	   -ENOENT if no such entry exists
+ * Return: The Linux interrupt number on success (> 0), 0 if not found
  */
-int __msi_get_virq(struct device *dev, unsigned int index)
+unsigned int msi_get_virq(struct device *dev, unsigned int index)
 {
 	struct msi_desc *desc;
 	bool pcimsi;
 
 	if (!dev->msi.data)
-		return -ENODEV;
+		return 0;
 
 	pcimsi = msi_device_has_property(dev, MSI_PROP_PCI_MSI);
 
@@ -152,9 +150,9 @@ int __msi_get_virq(struct device *dev, u
 		if (desc->msi_index == index)
 			return desc->irq;
 	}
-	return -ENOENT;
+	return 0;
 }
-EXPORT_SYMBOL_GPL(__msi_get_virq);
+EXPORT_SYMBOL_GPL(msi_get_virq);
 
 #ifdef CONFIG_SYSFS
 static ssize_t msi_mode_show(struct device *dev, struct device_attribute *attr,

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [patch 33/37] iommu/arm-smmu-v3: Use msi_get_virq()
  2021-11-27  1:20 ` [patch 33/37] iommu/arm-smmu-v3: " Thomas Gleixner
  2021-11-27  1:22   ` Thomas Gleixner
@ 2021-11-29 10:55   ` Will Deacon
  2021-11-29 12:52     ` Thomas Gleixner
  2021-11-29 13:13     ` Robin Murphy
  2021-11-29 13:25   ` Robin Murphy
  2 siblings, 2 replies; 97+ messages in thread
From: Will Deacon @ 2021-11-29 10:55 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Sinan Kaya

Hi Thomas,

On Sat, Nov 27, 2021 at 02:20:59AM +0100, Thomas Gleixner wrote:
> Let the core code fiddle with the MSI descriptor retrieval.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |   19 +++----------------
>  1 file changed, 3 insertions(+), 16 deletions(-)
> 
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -3154,7 +3154,6 @@ static void arm_smmu_write_msi_msg(struc
>  
>  static void arm_smmu_setup_msis(struct arm_smmu_device *smmu)
>  {
> -	struct msi_desc *desc;
>  	int ret, nvec = ARM_SMMU_MAX_MSIS;
>  	struct device *dev = smmu->dev;
>  
> @@ -3182,21 +3181,9 @@ static void arm_smmu_setup_msis(struct a
>  		return;
>  	}
>  
> -	for_each_msi_entry(desc, dev) {
> -		switch (desc->msi_index) {
> -		case EVTQ_MSI_INDEX:
> -			smmu->evtq.q.irq = desc->irq;
> -			break;
> -		case GERROR_MSI_INDEX:
> -			smmu->gerr_irq = desc->irq;
> -			break;
> -		case PRIQ_MSI_INDEX:
> -			smmu->priq.q.irq = desc->irq;
> -			break;
> -		default:	/* Unknown */
> -			continue;
> -		}
> -	}
> +	smmu->evtq.q.irq = msi_get_virq(dev, EVTQ_MSI_INDEX);
> +	smmu->gerr_irq = msi_get_virq(dev, GERROR_MSI_INDEX);
> +	smmu->priq.q.irq = msi_get_virq(dev, PRIQ_MSI_INDEX);

Prviously, if retrieval of the MSI failed then we'd fall back to wired
interrupts. Now, I think we'll clobber the interrupt with 0 instead. Can
we make the assignments to smmu->*irq here conditional on the MSI being
valid, please?

Cheers,

Will

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [patch 33/37] iommu/arm-smmu-v3: Use msi_get_virq()
  2021-11-29 10:55   ` Will Deacon
@ 2021-11-29 12:52     ` Thomas Gleixner
  2021-11-29 12:58       ` Thomas Gleixner
  2021-11-29 13:13     ` Robin Murphy
  1 sibling, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-29 12:52 UTC (permalink / raw)
  To: Will Deacon
  Cc: LKML, Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Sinan Kaya

Will,

On Mon, Nov 29 2021 at 10:55, Will Deacon wrote:
> On Sat, Nov 27, 2021 at 02:20:59AM +0100, Thomas Gleixner wrote:
>> +	smmu->evtq.q.irq = msi_get_virq(dev, EVTQ_MSI_INDEX);
>> +	smmu->gerr_irq = msi_get_virq(dev, GERROR_MSI_INDEX);
>> +	smmu->priq.q.irq = msi_get_virq(dev, PRIQ_MSI_INDEX);
>
> Prviously, if retrieval of the MSI failed then we'd fall back to wired
> interrupts. Now, I think we'll clobber the interrupt with 0 instead. Can
> we make the assignments to smmu->*irq here conditional on the MSI being
> valid, please?

So the wired irq number is in ->irq already and MSI does an override
if available. Not really obvious...

Thanks,

        tglx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [patch 33/37] iommu/arm-smmu-v3: Use msi_get_virq()
  2021-11-29 12:52     ` Thomas Gleixner
@ 2021-11-29 12:58       ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-29 12:58 UTC (permalink / raw)
  To: Will Deacon
  Cc: LKML, Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, Santosh Shilimkar, iommu, dmaengine,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Sinan Kaya

On Mon, Nov 29 2021 at 13:52, Thomas Gleixner wrote:
> On Mon, Nov 29 2021 at 10:55, Will Deacon wrote:
>> On Sat, Nov 27, 2021 at 02:20:59AM +0100, Thomas Gleixner wrote:
>>> +	smmu->evtq.q.irq = msi_get_virq(dev, EVTQ_MSI_INDEX);
>>> +	smmu->gerr_irq = msi_get_virq(dev, GERROR_MSI_INDEX);
>>> +	smmu->priq.q.irq = msi_get_virq(dev, PRIQ_MSI_INDEX);
>>
>> Prviously, if retrieval of the MSI failed then we'd fall back to wired
>> interrupts. Now, I think we'll clobber the interrupt with 0 instead. Can
>> we make the assignments to smmu->*irq here conditional on the MSI being
>> valid, please?
>
> So the wired irq number is in ->irq already and MSI does an override
> if available. Not really obvious...

But, this happens right after:

     ret = platform_msi_domain_alloc_irqs(dev, nvec, arm_smmu_write_msi_msg);

So if that succeeded then the descriptors exist and have interrupts
assigned.

Thanks,

        tglx




^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [patch 33/37] iommu/arm-smmu-v3: Use msi_get_virq()
  2021-11-29 10:55   ` Will Deacon
  2021-11-29 12:52     ` Thomas Gleixner
@ 2021-11-29 13:13     ` Robin Murphy
  2021-11-29 14:42       ` Thomas Gleixner
  1 sibling, 1 reply; 97+ messages in thread
From: Robin Murphy @ 2021-11-29 13:13 UTC (permalink / raw)
  To: Will Deacon, Thomas Gleixner
  Cc: Nishanth Menon, Mark Rutland, Stuart Yoder, linux-pci, Ashok Raj,
	Marc Zygnier, x86, Sinan Kaya, iommu, Bjorn Helgaas, Megha Dey,
	Jason Gunthorpe, Kevin Tian, Alex Williamson, Santosh Shilimkar,
	linux-arm-kernel, Tero Kristo, Greg Kroah-Hartman, LKML,
	Vinod Koul, dmaengine

On 2021-11-29 10:55, Will Deacon wrote:
> Hi Thomas,
> 
> On Sat, Nov 27, 2021 at 02:20:59AM +0100, Thomas Gleixner wrote:
>> Let the core code fiddle with the MSI descriptor retrieval.
>>
>> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
>> ---
>>   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |   19 +++----------------
>>   1 file changed, 3 insertions(+), 16 deletions(-)
>>
>> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> @@ -3154,7 +3154,6 @@ static void arm_smmu_write_msi_msg(struc
>>   
>>   static void arm_smmu_setup_msis(struct arm_smmu_device *smmu)
>>   {
>> -	struct msi_desc *desc;
>>   	int ret, nvec = ARM_SMMU_MAX_MSIS;
>>   	struct device *dev = smmu->dev;
>>   
>> @@ -3182,21 +3181,9 @@ static void arm_smmu_setup_msis(struct a
>>   		return;
>>   	}
>>   
>> -	for_each_msi_entry(desc, dev) {
>> -		switch (desc->msi_index) {
>> -		case EVTQ_MSI_INDEX:
>> -			smmu->evtq.q.irq = desc->irq;
>> -			break;
>> -		case GERROR_MSI_INDEX:
>> -			smmu->gerr_irq = desc->irq;
>> -			break;
>> -		case PRIQ_MSI_INDEX:
>> -			smmu->priq.q.irq = desc->irq;
>> -			break;
>> -		default:	/* Unknown */
>> -			continue;
>> -		}
>> -	}
>> +	smmu->evtq.q.irq = msi_get_virq(dev, EVTQ_MSI_INDEX);
>> +	smmu->gerr_irq = msi_get_virq(dev, GERROR_MSI_INDEX);
>> +	smmu->priq.q.irq = msi_get_virq(dev, PRIQ_MSI_INDEX);
> 
> Prviously, if retrieval of the MSI failed then we'd fall back to wired
> interrupts. Now, I think we'll clobber the interrupt with 0 instead. Can
> we make the assignments to smmu->*irq here conditional on the MSI being
> valid, please?

I was just looking at that too, but reached the conclusion that it's 
probably OK, since consumption of this value later is gated on 
ARM_SMMU_FEAT_PRI, so the fact that it changes from 0 to an error value 
in the absence of PRI should make no practical difference. If we don't 
have MSIs at all, we'd presumably still fail earlier either at the 
dev->msi_domain check or upon trying to allocate the vectors, so we'll 
still fall back to any previously-set wired values before getting here. 
The only remaining case is if we've *successfully* allocated the 
expected number of vectors yet are then somehow unable to retrieve one 
or more of them - presumably the system has to be massively borked for 
that to happen, at which point do we really want to bother trying to 
reason about anything?

Robin.

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [patch 33/37] iommu/arm-smmu-v3: Use msi_get_virq()
  2021-11-27  1:20 ` [patch 33/37] iommu/arm-smmu-v3: " Thomas Gleixner
  2021-11-27  1:22   ` Thomas Gleixner
  2021-11-29 10:55   ` Will Deacon
@ 2021-11-29 13:25   ` Robin Murphy
  2 siblings, 0 replies; 97+ messages in thread
From: Robin Murphy @ 2021-11-29 13:25 UTC (permalink / raw)
  To: Thomas Gleixner, LKML, Will Deacon
  Cc: Nishanth Menon, Mark Rutland, Stuart Yoder, linux-pci, Ashok Raj,
	Marc Zygnier, x86, Sinan Kaya, iommu, Bjorn Helgaas, Megha Dey,
	Jason Gunthorpe, Kevin Tian, Alex Williamson, Santosh Shilimkar,
	linux-arm-kernel, Tero Kristo, Greg Kroah-Hartman, Vinod Koul,
	dmaengine

On 2021-11-27 01:22, Thomas Gleixner wrote:
> Let the core code fiddle with the MSI descriptor retrieval.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
>   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |   19 +++----------------
>   1 file changed, 3 insertions(+), 16 deletions(-)
> 
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -3154,7 +3154,6 @@ static void arm_smmu_write_msi_msg(struc
>   
>   static void arm_smmu_setup_msis(struct arm_smmu_device *smmu)
>   {
> -	struct msi_desc *desc;
>   	int ret, nvec = ARM_SMMU_MAX_MSIS;
>   	struct device *dev = smmu->dev;
>   
> @@ -3182,21 +3181,9 @@ static void arm_smmu_setup_msis(struct a
>   		return;
>   	}
>   
> -	for_each_msi_entry(desc, dev) {
> -		switch (desc->msi_index) {
> -		case EVTQ_MSI_INDEX:
> -			smmu->evtq.q.irq = desc->irq;
> -			break;
> -		case GERROR_MSI_INDEX:
> -			smmu->gerr_irq = desc->irq;
> -			break;
> -		case PRIQ_MSI_INDEX:
> -			smmu->priq.q.irq = desc->irq;
> -			break;
> -		default:	/* Unknown */
> -			continue;
> -		}
> -	}
> +	smmu->evtq.q.irq = msi_get_virq(dev, EVTQ_MSI_INDEX);
> +	smmu->gerr_irq = msi_get_virq(dev, GERROR_MSI_INDEX);
> +	smmu->priq.q.irq = msi_get_virq(dev, PRIQ_MSI_INDEX);

FWIW I've just quickly booted the msi-v1-part-2 branch on a platform 
with MSIs but no PRI such that this now sets priq.q.irq to an error 
value, and as I predicted it's still happy.

Tested-by: Robin Murphy <robin.murphy@arm.com>

Cheers,
Robin.

>   	/* Add callback to free MSIs on teardown */
>   	devm_add_action(dev, arm_smmu_free_msis, dev);
> 
> _______________________________________________
> iommu mailing list
> iommu@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu
> 

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [patch 33/37] iommu/arm-smmu-v3: Use msi_get_virq()
  2021-11-29 13:13     ` Robin Murphy
@ 2021-11-29 14:42       ` Thomas Gleixner
  2021-11-29 14:54         ` Robin Murphy
  0 siblings, 1 reply; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-29 14:42 UTC (permalink / raw)
  To: Robin Murphy, Will Deacon
  Cc: Nishanth Menon, Mark Rutland, Stuart Yoder, linux-pci, Ashok Raj,
	Marc Zygnier, x86, Sinan Kaya, iommu, Bjorn Helgaas, Megha Dey,
	Jason Gunthorpe, Kevin Tian, Alex Williamson, Santosh Shilimkar,
	linux-arm-kernel, Tero Kristo, Greg Kroah-Hartman, LKML,
	Vinod Koul, dmaengine

On Mon, Nov 29 2021 at 13:13, Robin Murphy wrote:
> On 2021-11-29 10:55, Will Deacon wrote:
>>> -	}
>>> +	smmu->evtq.q.irq = msi_get_virq(dev, EVTQ_MSI_INDEX);
>>> +	smmu->gerr_irq = msi_get_virq(dev, GERROR_MSI_INDEX);
>>> +	smmu->priq.q.irq = msi_get_virq(dev, PRIQ_MSI_INDEX);
>> 
>> Prviously, if retrieval of the MSI failed then we'd fall back to wired
>> interrupts. Now, I think we'll clobber the interrupt with 0 instead. Can
>> we make the assignments to smmu->*irq here conditional on the MSI being
>> valid, please?
>
> I was just looking at that too, but reached the conclusion that it's 
> probably OK, since consumption of this value later is gated on 
> ARM_SMMU_FEAT_PRI, so the fact that it changes from 0 to an error value 
> in the absence of PRI should make no practical difference.

It's actually 0 when the vector cannot be found.

> If we don't have MSIs at all, we'd presumably still fail earlier
> either at the dev->msi_domain check or upon trying to allocate the
> vectors, so we'll still fall back to any previously-set wired values
> before getting here.  The only remaining case is if we've
> *successfully* allocated the expected number of vectors yet are then
> somehow unable to retrieve one or more of them - presumably the system
> has to be massively borked for that to happen, at which point do we
> really want to bother trying to reason about anything?

Probably not. At that point something is going to explode sooner than
later in colorful ways.

Thanks,

        tglx

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [patch 33/37] iommu/arm-smmu-v3: Use msi_get_virq()
  2021-11-29 14:42       ` Thomas Gleixner
@ 2021-11-29 14:54         ` Robin Murphy
  2021-11-30  9:36           ` Will Deacon
  0 siblings, 1 reply; 97+ messages in thread
From: Robin Murphy @ 2021-11-29 14:54 UTC (permalink / raw)
  To: Thomas Gleixner, Will Deacon
  Cc: Nishanth Menon, Mark Rutland, Stuart Yoder, linux-pci, Ashok Raj,
	Marc Zygnier, x86, Sinan Kaya, iommu, Bjorn Helgaas, Megha Dey,
	Jason Gunthorpe, Kevin Tian, Alex Williamson, Santosh Shilimkar,
	linux-arm-kernel, Tero Kristo, Greg Kroah-Hartman, LKML,
	Vinod Koul, dmaengine

On 2021-11-29 14:42, Thomas Gleixner wrote:
> On Mon, Nov 29 2021 at 13:13, Robin Murphy wrote:
>> On 2021-11-29 10:55, Will Deacon wrote:
>>>> -	}
>>>> +	smmu->evtq.q.irq = msi_get_virq(dev, EVTQ_MSI_INDEX);
>>>> +	smmu->gerr_irq = msi_get_virq(dev, GERROR_MSI_INDEX);
>>>> +	smmu->priq.q.irq = msi_get_virq(dev, PRIQ_MSI_INDEX);
>>>
>>> Prviously, if retrieval of the MSI failed then we'd fall back to wired
>>> interrupts. Now, I think we'll clobber the interrupt with 0 instead. Can
>>> we make the assignments to smmu->*irq here conditional on the MSI being
>>> valid, please?
>>
>> I was just looking at that too, but reached the conclusion that it's
>> probably OK, since consumption of this value later is gated on
>> ARM_SMMU_FEAT_PRI, so the fact that it changes from 0 to an error value
>> in the absence of PRI should make no practical difference.
> 
> It's actually 0 when the vector cannot be found.

Oh, -1 for my reading comprehension but +1 for my confidence in the 
patch then :)

I'll let Will have the final say over how cautious we really want to be 
here, but as far as I'm concerned it's a welcome cleanup as-is. Ditto 
for patch #32 based on the same reasoning, although I don't have a 
suitable test platform on-hand to sanity-check that one.

Cheers,
Robin.

>> If we don't have MSIs at all, we'd presumably still fail earlier
>> either at the dev->msi_domain check or upon trying to allocate the
>> vectors, so we'll still fall back to any previously-set wired values
>> before getting here.  The only remaining case is if we've
>> *successfully* allocated the expected number of vectors yet are then
>> somehow unable to retrieve one or more of them - presumably the system
>> has to be massively borked for that to happen, at which point do we
>> really want to bother trying to reason about anything?
> 
> Probably not. At that point something is going to explode sooner than
> later in colorful ways.
> 
> Thanks,
> 
>          tglx
> 

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [patch 37/37] dmaengine: qcom_hidma: Cleanup MSI handling
  2021-11-27  1:21 ` [patch 37/37] dmaengine: qcom_hidma: Cleanup MSI handling Thomas Gleixner
  2021-11-27  1:22   ` Thomas Gleixner
@ 2021-11-29 19:56   ` Sinan Kaya
  1 sibling, 0 replies; 97+ messages in thread
From: Sinan Kaya @ 2021-11-29 19:56 UTC (permalink / raw)
  To: Thomas Gleixner, LKML
  Cc: Bjorn Helgaas, Marc Zygnier, Alex Williamson, Kevin Tian,
	Jason Gunthorpe, Megha Dey, Ashok Raj, linux-pci,
	Greg Kroah-Hartman, dmaengine, Santosh Shilimkar, iommu,
	Stuart Yoder, Laurentiu Tudor, Nishanth Menon, Tero Kristo,
	linux-arm-kernel, x86, Vinod Koul, Mark Rutland, Will Deacon

On 11/26/2021 8:22 PM, Thomas Gleixner wrote:
> There is no reason to walk the MSI descriptors to retrieve the interrupt
> number for a device. Use msi_get_virq() instead.
> 
> Signed-off-by: Thomas Gleixner<tglx@linutronix.de>
> Cc: Sinan Kaya<okaya@kernel.org>
> Cc:dmaengine@vger.kernel.org

Acked-by: Sinan Kaya <okaya@kernel.org>

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [patch 33/37] iommu/arm-smmu-v3: Use msi_get_virq()
  2021-11-29 14:54         ` Robin Murphy
@ 2021-11-30  9:36           ` Will Deacon
  2021-11-30 12:30             ` Thomas Gleixner
  0 siblings, 1 reply; 97+ messages in thread
From: Will Deacon @ 2021-11-30  9:36 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Thomas Gleixner, Nishanth Menon, Mark Rutland, Stuart Yoder,
	linux-pci, Ashok Raj, Marc Zygnier, x86, Sinan Kaya, iommu,
	Bjorn Helgaas, Megha Dey, Jason Gunthorpe, Kevin Tian,
	Alex Williamson, Santosh Shilimkar, linux-arm-kernel,
	Tero Kristo, Greg Kroah-Hartman, LKML, Vinod Koul, dmaengine

On Mon, Nov 29, 2021 at 02:54:18PM +0000, Robin Murphy wrote:
> On 2021-11-29 14:42, Thomas Gleixner wrote:
> > On Mon, Nov 29 2021 at 13:13, Robin Murphy wrote:
> > > On 2021-11-29 10:55, Will Deacon wrote:
> > > > > -	}
> > > > > +	smmu->evtq.q.irq = msi_get_virq(dev, EVTQ_MSI_INDEX);
> > > > > +	smmu->gerr_irq = msi_get_virq(dev, GERROR_MSI_INDEX);
> > > > > +	smmu->priq.q.irq = msi_get_virq(dev, PRIQ_MSI_INDEX);
> > > > 
> > > > Prviously, if retrieval of the MSI failed then we'd fall back to wired
> > > > interrupts. Now, I think we'll clobber the interrupt with 0 instead. Can
> > > > we make the assignments to smmu->*irq here conditional on the MSI being
> > > > valid, please?
> > > 
> > > I was just looking at that too, but reached the conclusion that it's
> > > probably OK, since consumption of this value later is gated on
> > > ARM_SMMU_FEAT_PRI, so the fact that it changes from 0 to an error value
> > > in the absence of PRI should make no practical difference.
> > 
> > It's actually 0 when the vector cannot be found.
> 
> Oh, -1 for my reading comprehension but +1 for my confidence in the patch
> then :)
> 
> I'll let Will have the final say over how cautious we really want to be
> here, but as far as I'm concerned it's a welcome cleanup as-is. Ditto for
> patch #32 based on the same reasoning, although I don't have a suitable test
> platform on-hand to sanity-check that one.

If, as it appears, msi_get_virq() isn't going to fail meaningfully after
we've successfully called platform_msi_domain_alloc_irqs() then it sounds
like the patch is fine. Just wanted to check though, as Spring cleaning at
the end of November raised an eyebrow over here :)

Will

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [patch 08/37] genirq/msi: Provide msi_device_populate/destroy_sysfs()
  2021-11-27  1:20 ` [patch 08/37] genirq/msi: Provide msi_device_populate/destroy_sysfs() Thomas Gleixner
  2021-11-27  1:21   ` Thomas Gleixner
@ 2021-11-30 11:53   ` Jonathan Cameron
  1 sibling, 0 replies; 97+ messages in thread
From: Jonathan Cameron @ 2021-11-30 11:53 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, Nishanth Menon, Mark Rutland, Stuart Yoder, linux-pci,
	Will Deacon, Ashok Raj, Marc Zygnier, x86, Sinan Kaya, iommu,
	Bjorn Helgaas, Megha Dey, Jason Gunthorpe, Kevin Tian,
	Alex Williamson, Santosh Shilimkar, linux-arm-kernel,
	Tero Kristo, Greg Kroah-Hartman, Vinod Koul, dmaengine

On Sat, 27 Nov 2021 02:20:19 +0100 (CET)
Thomas Gleixner <tglx@linutronix.de> wrote:

> Add new allocation functions which can be activated by domain info
> flags. They store the groups pointer in struct msi_device_data.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

A few trivial comments...

> ---
>  include/linux/msi.h |   12 +++++++++++-
>  kernel/irq/msi.c    |   42 ++++++++++++++++++++++++++++++++++++++++--
>  2 files changed, 51 insertions(+), 3 deletions(-)
> 
> --- a/include/linux/msi.h
> +++ b/include/linux/msi.h
> @@ -174,9 +174,11 @@ struct msi_desc {
>  /**
>   * msi_device_data - MSI per device data
>   * @lock:		Spinlock to protect register access
> + * @attrs:		Pointer to the sysfs attribute group
>   */
>  struct msi_device_data {
> -	raw_spinlock_t		lock;
> +	raw_spinlock_t			lock;

Trivial: Move the alignment change back to patch 2.

> +	const struct attribute_group    **attrs;
>  };
>  
>  int msi_setup_device_data(struct device *dev);
> @@ -242,10 +244,16 @@ void pci_msi_mask_irq(struct irq_data *d
>  void pci_msi_unmask_irq(struct irq_data *data);
>  
>  #ifdef CONFIG_SYSFS
> +int msi_device_populate_sysfs(struct device *dev);
> +void msi_device_destroy_sysfs(struct device *dev);
> +
>  const struct attribute_group **msi_populate_sysfs(struct device *dev);
>  void msi_destroy_sysfs(struct device *dev,
>  		       const struct attribute_group **msi_irq_groups);
>  #else
> +static inline int msi_device_populate_sysfs(struct device *dev) { return 0; }
> +static inline void msi_device_destroy_sysfs(struct device *dev) { }
> +
>  static inline const struct attribute_group **msi_populate_sysfs(struct device *dev)
>  {
>  	return NULL;
> @@ -393,6 +401,8 @@ enum {
>  	MSI_FLAG_MUST_REACTIVATE	= (1 << 5),
>  	/* Is level-triggered capable, using two messages */
>  	MSI_FLAG_LEVEL_CAPABLE		= (1 << 6),
> +	/* Populate sysfs on alloc() and destroy it on free() */
> +	MSI_FLAG_DEV_SYSFS		= (1 << 7),
>  };
>  
>  int msi_domain_set_affinity(struct irq_data *data, const struct cpumask *mask,
> --- a/kernel/irq/msi.c
> +++ b/kernel/irq/msi.c
> @@ -214,6 +214,20 @@ const struct attribute_group **msi_popul
>  }
>  
>  /**
> + * msi_device_populate_sysfs - Populate msi_irqs sysfs entries for a device
> + * @dev:	The device(PCI, platform etc) which will get sysfs entries

Space after device

> + */
> +int msi_device_populate_sysfs(struct device *dev)
> +{
> +	const struct attribute_group **group = msi_populate_sysfs(dev);
> +
> +	if (IS_ERR(group))
> +		return PTR_ERR(group);
> +	dev->msi.data->attrs = group;
> +	return 0;
> +}
> +
> +/**
>   * msi_destroy_sysfs - Destroy msi_irqs sysfs entries for devices
>   * @dev:		The device(PCI, platform etc) who will remove sysfs entries
>   * @msi_irq_groups:	attribute_group for device msi_irqs entries
> @@ -239,6 +253,17 @@ void msi_destroy_sysfs(struct device *de
>  		kfree(msi_irq_groups);
>  	}
>  }
> +
> +/**
> + * msi_device_destroy_sysfs - Destroy msi_irqs sysfs entries for a device
> + * @dev:		The device(PCI, platform etc) for which to remove
> + *			sysfs entries
> + */
> +void msi_device_destroy_sysfs(struct device *dev)
> +{
> +	msi_destroy_sysfs(dev, dev->msi.data->attrs);
> +	dev->msi.data->attrs = NULL;
> +}
>  #endif
>  
>  #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
> @@ -686,8 +711,19 @@ int msi_domain_alloc_irqs(struct irq_dom
>  {
>  	struct msi_domain_info *info = domain->host_data;
>  	struct msi_domain_ops *ops = info->ops;
> +	int ret;
>  
> -	return ops->domain_alloc_irqs(domain, dev, nvec);
> +	ret = ops->domain_alloc_irqs(domain, dev, nvec);
> +	if (ret)
> +		return ret;
> +
> +	if (!(info->flags & MSI_FLAG_DEV_SYSFS))
> +		return 0;
> +
> +	ret = msi_device_populate_sysfs(dev);
> +	if (ret)
> +		msi_domain_free_irqs(domain, dev);
> +	return ret;
>  }
>  
>  void __msi_domain_free_irqs(struct irq_domain *domain, struct device *dev)
> @@ -726,7 +762,9 @@ void msi_domain_free_irqs(struct irq_dom
>  	struct msi_domain_info *info = domain->host_data;
>  	struct msi_domain_ops *ops = info->ops;
>  
> -	return ops->domain_free_irqs(domain, dev);
> +	if (info->flags & MSI_FLAG_DEV_SYSFS)
> +		msi_device_destroy_sysfs(dev);
> +	ops->domain_free_irqs(domain, dev);
>  }
>  
>  /**
> 
> _______________________________________________
> iommu mailing list
> iommu@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu


^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [patch 33/37] iommu/arm-smmu-v3: Use msi_get_virq()
  2021-11-30  9:36           ` Will Deacon
@ 2021-11-30 12:30             ` Thomas Gleixner
  0 siblings, 0 replies; 97+ messages in thread
From: Thomas Gleixner @ 2021-11-30 12:30 UTC (permalink / raw)
  To: Will Deacon, Robin Murphy
  Cc: Nishanth Menon, Mark Rutland, Stuart Yoder, linux-pci, Ashok Raj,
	Marc Zygnier, x86, Sinan Kaya, iommu, Bjorn Helgaas, Megha Dey,
	Jason Gunthorpe, Kevin Tian, Alex Williamson, Santosh Shilimkar,
	linux-arm-kernel, Tero Kristo, Greg Kroah-Hartman, LKML,
	Vinod Koul, dmaengine

On Tue, Nov 30 2021 at 09:36, Will Deacon wrote:
> On Mon, Nov 29, 2021 at 02:54:18PM +0000, Robin Murphy wrote:
>> On 2021-11-29 14:42, Thomas Gleixner wrote:
>> > It's actually 0 when the vector cannot be found.
>> 
>> Oh, -1 for my reading comprehension but +1 for my confidence in the patch
>> then :)
>> 
>> I'll let Will have the final say over how cautious we really want to be
>> here, but as far as I'm concerned it's a welcome cleanup as-is. Ditto for
>> patch #32 based on the same reasoning, although I don't have a suitable test
>> platform on-hand to sanity-check that one.
>
> If, as it appears, msi_get_virq() isn't going to fail meaningfully after
> we've successfully called platform_msi_domain_alloc_irqs() then it sounds
> like the patch is fine. Just wanted to check though, as Spring cleaning at
> the end of November raised an eyebrow over here :)

Fair enough. Next time I'll name it 'Cleaning the Augean stables' when
it's the wrong season.

Thanks,

        tglx


^ permalink raw reply	[flat|nested] 97+ messages in thread

end of thread, other threads:[~2021-11-30 12:30 UTC | newest]

Thread overview: 97+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-27  1:20 [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
2021-11-27  1:20 ` [patch 01/37] device: Move MSI related data into a struct Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-27 12:11   ` Greg Kroah-Hartman
2021-11-27  1:20 ` [patch 02/37] device: Add device::msi_data pointer and struct msi_device_data Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-27 12:12   ` Greg Kroah-Hartman
2021-11-28  0:14   ` Jason Gunthorpe
2021-11-28 19:09     ` Thomas Gleixner
2021-11-27  1:20 ` [patch 03/37] PCI/MSI: Allocate MSI device data on first use Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 05/37] platform-msi: " Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 06/37] bus: fsl-mc-msi: " Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 07/37] soc: ti: ti_sci_inta_msi: " Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 08/37] genirq/msi: Provide msi_device_populate/destroy_sysfs() Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-30 11:53   ` Jonathan Cameron
2021-11-27  1:20 ` [patch 09/37] PCI/MSI: Let the irq code handle sysfs groups Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 10/37] platform-msi: Let the core " Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 11/37] genirq/msi: Remove the original sysfs interfaces Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 12/37] platform-msi: Rename functions and clarify comments Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 13/37] platform-msi: Store platform private data pointer in msi_device_data Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 14/37] genirq/msi: Consolidate MSI descriptor data Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 15/37] platform-msi: Use msi_desc::msi_index Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 16/37] bus: fsl-mc-msi: " Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 17/37] soc: ti: ti_sci_inta_msi: " Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 18/37] PCI/MSI: " Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 19/37] genirq/msi: Add msi_device_data::properties Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 20/37] PCI/MSI: Store properties in device::msi::data Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 21/37] x86/pci/XEN: Use device MSI properties Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 22/37] x86/apic/msi: " Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 23/37] genirq/msi: " Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 24/37] powerpc/cell/axon_msi: Use MSI device properties Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 25/37] powerpc/pseries/msi: " Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 26/37] PCI/MSI: Provide MSI_FLAG_MSIX_CONTIGUOUS Thomas Gleixner
2021-11-27  1:21   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 27/37] powerpc/pseries/msi: Let core code check for contiguous entries Thomas Gleixner
2021-11-27  1:22   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 28/37] genirq/msi: Provide interface to retrieve Linux interrupt number Thomas Gleixner
2021-11-27  1:22   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 29/37] PCI/MSI: Use __msi_get_virq() in pci_get_vector() Thomas Gleixner
2021-11-27  1:22   ` Thomas Gleixner
2021-11-28 19:37   ` Marc Zyngier
2021-11-28 21:00     ` Thomas Gleixner
2021-11-27  1:20 ` [patch 30/37] PCI/MSI: Simplify pci_irq_get_affinity() Thomas Gleixner
2021-11-27  1:22   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 31/37] dmaengine: mv_xor_v2: Get rid of msi_desc abuse Thomas Gleixner
2021-11-27  1:22   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 32/37] perf/smmuv3: Use msi_get_virq() Thomas Gleixner
2021-11-27  1:22   ` Thomas Gleixner
2021-11-27  1:20 ` [patch 33/37] iommu/arm-smmu-v3: " Thomas Gleixner
2021-11-27  1:22   ` Thomas Gleixner
2021-11-29 10:55   ` Will Deacon
2021-11-29 12:52     ` Thomas Gleixner
2021-11-29 12:58       ` Thomas Gleixner
2021-11-29 13:13     ` Robin Murphy
2021-11-29 14:42       ` Thomas Gleixner
2021-11-29 14:54         ` Robin Murphy
2021-11-30  9:36           ` Will Deacon
2021-11-30 12:30             ` Thomas Gleixner
2021-11-29 13:25   ` Robin Murphy
2021-11-27  1:21 ` [patch 34/37] mailbox: bcm-flexrm-mailbox: Rework MSI interrupt handling Thomas Gleixner
2021-11-27  1:22   ` Thomas Gleixner
2021-11-27  1:21 ` [patch 35/37] bus: fsl-mc: fsl-mc-allocator: Rework MSI handling Thomas Gleixner
2021-11-27  1:22   ` Thomas Gleixner
2021-11-27  1:21 ` [patch 36/37] soc: ti: ti_sci_inta_msi: Get rid of ti_sci_inta_msi_get_virq() Thomas Gleixner
2021-11-27  1:22   ` Thomas Gleixner
2021-11-27  1:21 ` [patch 37/37] dmaengine: qcom_hidma: Cleanup MSI handling Thomas Gleixner
2021-11-27  1:22   ` Thomas Gleixner
2021-11-29 19:56   ` Sinan Kaya
2021-11-27  1:21 ` [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Thomas Gleixner
2021-11-27  1:21 ` [patch 04/37] PCI/MSI: Use lock from msi_device_data Thomas Gleixner
2021-11-27  1:20   ` Thomas Gleixner
2021-11-27 12:13   ` Greg Kroah-Hartman
2021-11-27 12:17 ` [patch 00/37] genirq/msi, PCI/MSI: Spring cleaning - Part 2 Greg Kroah-Hartman
2021-11-28  0:39 ` Jason Gunthorpe
2021-11-28 20:27   ` Thomas Gleixner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).