[PATCH 4/7] powerpc/powernv: Patch MSI EOI handler on P8
Gavin Shan
shangw at linux.vnet.ibm.com
Thu Apr 25 18:08:37 EST 2013
On Thu, Apr 25, 2013 at 06:49:40AM +1000, Benjamin Herrenschmidt wrote:
>On Wed, 2013-04-24 at 17:37 +0800, Gavin Shan wrote:
>> The EOI handler of MSI/MSI-X interrupts for P8 (PHB3) need additional
>> steps to handle the P/Q bits in IVE before EOIing the corresponding
>> interrupt. The patch changes the EOI handler to cover that.
>
> .../...
>
>> static void pnv_pci_init_ioda_msis(struct pnv_phb *phb)
>> {
>> unsigned int count;
>> @@ -667,6 +681,8 @@ static void pnv_pci_init_ioda_msis(struct pnv_phb *phb)
>> }
>>
>> phb->msi_setup = pnv_pci_ioda_msi_setup;
>> + if (phb->type == PNV_PHB_IODA2)
>> + phb->msi_eoi = pnv_pci_ioda_msi_eoi;
>
>Ouch, another function pointer call in a hot path...
>
Yeah. I've removed it in next version (not send out yet) :-)
>> phb->msi32_support = 1;
>> pr_info(" Allocated bitmap for %d MSIs (base IRQ 0x%x)\n",
>> count, phb->msi_base);
>> diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
>> index a11b5a6..ea6a93d 100644
>> --- a/arch/powerpc/platforms/powernv/pci.c
>> +++ b/arch/powerpc/platforms/powernv/pci.c
>> @@ -115,6 +115,25 @@ static void pnv_teardown_msi_irqs(struct pci_dev *pdev)
>> irq_dispose_mapping(entry->irq);
>> }
>> }
>> +
>> +int pnv_pci_msi_eoi(unsigned int hw_irq)
>> +{
>> + struct pci_controller *hose, *tmp;
>> + struct pnv_phb *phb = NULL;
>> +
>> + list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
>> + phb = hose->private_data;
>> + if (hw_irq >= phb->msi_base &&
>> + hw_irq < phb->msi_base + phb->msi_bmp.irq_count) {
>> + if (!phb->msi_eoi)
>> + return -EEXIST;
>> + return phb->msi_eoi(phb, hw_irq);
>> + }
>> + }
>> +
>> + /* For LSI interrupts, we needn't do it */
>> + return 0;
>> +}
>
>And a list walk ... that's not right.
>
>Also, you do it for all XICS interrupts, including the non-PCI ones, the
>LSIs, etc... only to figure out that some might not be MSIs later in
>the loop.
>
>Why not instead look at changing the irq_chip for the MSIs ?
>
>IE. When setting up the MSIs for IODA2, use a different irq_chip which
>is a copy of the original one with a different ->eoi callback, which
>does the original xics eoi and then the OPAL stuff ?
>
>You might even be able to use something like container_of to get back
>to the struct phb, no need to iterate them all.
>
Thanks for the detailed explaining, Ben.
I found irq_data hasn't been fully utilized until this moment. I already
have code to start use that. Firstly, "irq_data" is set to the PHB OPAL ID
or invalid value (0xffs) during mapping stage (there, we call irq_set_chip_data()
to trace the PHB OPAL ID or invalid value). Before EOIing the interrupt, we
will check "irq_data" and do special handling on P/Q bits if it has valid value.
With it, the "hot" path should be fast enough and the function pointer (mentioned
above) can be removed.
Thanks,
Gavin
More information about the Linuxppc-dev
mailing list