Re: [patch RFC 34/38] x86/msi: Let pci_msi_prepare() handle non-PCI MSI

From: Bjorn Helgaas
Date: Tue Aug 25 2020 - 16:24:24 EST


On Fri, Aug 21, 2020 at 02:24:58AM +0200, Thomas Gleixner wrote:
> Rename it to x86_msi_prepare() and handle the allocation type setup
> depending on the device type.

I see what you're doing, but the subject reads a little strangely
("pci_msi_prepare() handling non-PCI" stuff) since it doesn't mention
the rename. Maybe not practical or worthwhile to split into a rename
+ make generic, I dunno.

> Add a new arch_msi_prepare define which will be utilized by the upcoming
> device MSI support. Define it to NULL if not provided by an architecture in
> the generic MSI header.
>
> One arch specific function for MSI support is truly enough.
>
> Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
> Cc: linux-pci@xxxxxxxxxxxxxxx
> Cc: linux-hyperv@xxxxxxxxxxxxxxx
> ---
> arch/x86/include/asm/msi.h | 4 +++-
> arch/x86/kernel/apic/msi.c | 27 ++++++++++++++++++++-------
> drivers/pci/controller/pci-hyperv.c | 2 +-
> include/linux/msi.h | 4 ++++
> 4 files changed, 28 insertions(+), 9 deletions(-)
>
> --- a/arch/x86/include/asm/msi.h
> +++ b/arch/x86/include/asm/msi.h
> @@ -6,7 +6,9 @@
>
> typedef struct irq_alloc_info msi_alloc_info_t;
>
> -int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
> +int x86_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
> msi_alloc_info_t *arg);
>
> +#define arch_msi_prepare x86_msi_prepare
> +
> #endif /* _ASM_X86_MSI_H */
> --- a/arch/x86/kernel/apic/msi.c
> +++ b/arch/x86/kernel/apic/msi.c
> @@ -182,26 +182,39 @@ static struct irq_chip pci_msi_controlle
> .flags = IRQCHIP_SKIP_SET_WAKE,
> };
>
> -int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
> - msi_alloc_info_t *arg)
> +static void pci_msi_prepare(struct device *dev, msi_alloc_info_t *arg)
> {
> - struct pci_dev *pdev = to_pci_dev(dev);
> - struct msi_desc *desc = first_pci_msi_entry(pdev);
> + struct msi_desc *desc = first_msi_entry(dev);
>
> - init_irq_alloc_info(arg, NULL);
> if (desc->msi_attrib.is_msix) {
> arg->type = X86_IRQ_ALLOC_TYPE_PCI_MSIX;
> } else {
> arg->type = X86_IRQ_ALLOC_TYPE_PCI_MSI;
> arg->flags |= X86_IRQ_ALLOC_CONTIGUOUS_VECTORS;
> }
> +}
> +
> +static void dev_msi_prepare(struct device *dev, msi_alloc_info_t *arg)
> +{
> + arg->type = X86_IRQ_ALLOC_TYPE_DEV_MSI;
> +}
> +
> +int x86_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
> + msi_alloc_info_t *arg)
> +{
> + init_irq_alloc_info(arg, NULL);
> +
> + if (dev_is_pci(dev))
> + pci_msi_prepare(dev, arg);
> + else
> + dev_msi_prepare(dev, arg);
>
> return 0;
> }
> -EXPORT_SYMBOL_GPL(pci_msi_prepare);
> +EXPORT_SYMBOL_GPL(x86_msi_prepare);
>
> static struct msi_domain_ops pci_msi_domain_ops = {
> - .msi_prepare = pci_msi_prepare,
> + .msi_prepare = x86_msi_prepare,
> };
>
> static struct msi_domain_info pci_msi_domain_info = {
> --- a/drivers/pci/controller/pci-hyperv.c
> +++ b/drivers/pci/controller/pci-hyperv.c
> @@ -1532,7 +1532,7 @@ static struct irq_chip hv_msi_irq_chip =
> };
>
> static struct msi_domain_ops hv_msi_ops = {
> - .msi_prepare = pci_msi_prepare,
> + .msi_prepare = arch_msi_prepare,
> .msi_free = hv_msi_free,
> };
>
> --- a/include/linux/msi.h
> +++ b/include/linux/msi.h
> @@ -430,4 +430,8 @@ static inline struct irq_domain *pci_msi
> }
> #endif /* CONFIG_PCI_MSI_IRQ_DOMAIN */
>
> +#ifndef arch_msi_prepare
> +# define arch_msi_prepare NULL
> +#endif
> +
> #endif /* LINUX_MSI_H */
>