[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v5 08/10] x86/PCI: read MSI-X table entry count early
On Tue, Aug 06, 2019 at 03:10:40PM +0200, Jan Beulich wrote: > Rather than doing this every time we set up interrupts for a device > anew (and then in two distinct places) fill this invariant field > right after allocating struct arch_msix. > > While at it also obtain the MSI-X capability structure position just > once, in msix_capability_init(), rather than in each caller. > > Furthermore take the opportunity and eliminate the multi_msix_capable() > alias of msix_table_size(). > > Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> > --- > v5: New. > > --- a/xen/arch/x86/msi.c > +++ b/xen/arch/x86/msi.c > @@ -821,10 +821,8 @@ static u64 read_pci_mem_bar(u16 seg, u8 > * requested MSI-X entries with allocated irqs or non-zero for otherwise. > **/ > static int msix_capability_init(struct pci_dev *dev, > - unsigned int pos, > struct msi_info *msi, > - struct msi_desc **desc, > - unsigned int nr_entries) > + struct msi_desc **desc) > { > struct arch_msix *msix = dev->msix; > struct msi_desc *entry = NULL; > @@ -838,6 +836,11 @@ static int msix_capability_init(struct p > u8 slot = PCI_SLOT(dev->devfn); > u8 func = PCI_FUNC(dev->devfn); > bool maskall = msix->host_maskall; > + unsigned int pos = pci_find_cap_offset(seg, bus, slot, func, > + PCI_CAP_ID_MSIX); > + > + if ( !pos ) > + return -ENODEV; > ASSERT(pcidevs_locked()); > @@ -912,10 +915,9 @@ static int msix_capability_init(struct p > u64 pba_paddr; > u32 pba_offset; > - msix->nr_entries = nr_entries; > msix->table.first = PFN_DOWN(table_paddr); > msix->table.last = PFN_DOWN(table_paddr + > - nr_entries * PCI_MSIX_ENTRY_SIZE - 1); > + msix->nr_entries * PCI_MSIX_ENTRY_SIZE - > 1); > WARN_ON(rangeset_overlaps_range(mmio_ro_ranges, msix->table.first, > msix->table.last)); > @@ -927,7 +929,7 @@ static int msix_capability_init(struct p > msix->pba.first = PFN_DOWN(pba_paddr); > msix->pba.last = PFN_DOWN(pba_paddr + > - BITS_TO_LONGS(nr_entries) - 1); > + BITS_TO_LONGS(msix->nr_entries) - 1); > WARN_ON(rangeset_overlaps_range(mmio_ro_ranges, msix->pba.first, > msix->pba.last)); > } > @@ -999,7 +1001,6 @@ static int msix_capability_init(struct p > /* XXX How to deal with existing mappings? */ > } > } > - WARN_ON(msix->nr_entries != nr_entries); > WARN_ON(msix->table.first != (table_paddr >> PAGE_SHIFT)); > ++msix->used_entries; > @@ -1093,22 +1094,17 @@ static void __pci_disable_msi(struct msi > **/ > static int __pci_enable_msix(struct msi_info *msi, struct msi_desc **desc) > { > - int pos, nr_entries; > struct pci_dev *pdev; > - u16 control; > u8 slot = PCI_SLOT(msi->devfn); > u8 func = PCI_FUNC(msi->devfn); > struct msi_desc *old_desc; Missing newline. > ASSERT(pcidevs_locked()); > pdev = pci_get_pdev(msi->seg, msi->bus, msi->devfn); > - pos = pci_find_cap_offset(msi->seg, msi->bus, slot, func, > PCI_CAP_ID_MSIX); > - if ( !pdev || !pos ) > + if ( !pdev || !pdev->msix ) > return -ENODEV; > - control = pci_conf_read16(pdev->sbdf, msix_control_reg(pos)); > - nr_entries = multi_msix_capable(control); > - if ( msi->entry_nr >= nr_entries ) > + if ( msi->entry_nr >= pdev->msix->nr_entries ) > return -EINVAL; > old_desc = find_msi_entry(pdev, msi->irq, PCI_CAP_ID_MSIX); > @@ -1127,7 +1123,7 @@ static int __pci_enable_msix(struct msi_ > __pci_disable_msi(old_desc); > } > - return msix_capability_init(pdev, pos, msi, desc, nr_entries); > + return msix_capability_init(pdev, msi, desc); > } > static void _pci_cleanup_msix(struct arch_msix *msix) > @@ -1187,16 +1183,10 @@ int pci_prepare_msix(u16 seg, u8 bus, u8 > { > int rc; > struct pci_dev *pdev; > - u8 slot = PCI_SLOT(devfn), func = PCI_FUNC(devfn); > - unsigned int pos = pci_find_cap_offset(seg, bus, slot, func, > - PCI_CAP_ID_MSIX); You seem to be missing an empty newline here? > if ( !use_msi ) > return 0; Same here. > - if ( !pos ) > - return -ENODEV; > - > pcidevs_lock(); > pdev = pci_get_pdev(seg, bus, devfn); > if ( !pdev ) > @@ -1209,13 +1199,7 @@ int pci_prepare_msix(u16 seg, u8 bus, u8 > rc = 0; > } > else > - { > - uint16_t control = pci_conf_read16(PCI_SBDF3(seg, bus, devfn), > - msix_control_reg(pos)); > - > - rc = msix_capability_init(pdev, pos, NULL, NULL, > - multi_msix_capable(control)); > - } > + rc = msix_capability_init(pdev, NULL, NULL); > pcidevs_unlock(); > return rc; > --- a/xen/drivers/passthrough/pci.c > +++ b/xen/drivers/passthrough/pci.c > @@ -324,6 +324,7 @@ static void apply_quirks(struct pci_dev > static struct pci_dev *alloc_pdev(struct pci_seg *pseg, u8 bus, u8 devfn) > { > struct pci_dev *pdev; > + unsigned int pos; This chunk doesn't seem to match my current code, as there's an empty newline between the declarations and list_for_each_entry. > list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list ) > if ( pdev->bus == bus && pdev->devfn == devfn ) > @@ -339,10 +340,12 @@ static struct pci_dev *alloc_pdev(struct > pdev->domain = NULL; > INIT_LIST_HEAD(&pdev->msi_list); > - if ( pci_find_cap_offset(pseg->nr, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), > - PCI_CAP_ID_MSIX) ) > + pos = pci_find_cap_offset(pseg->nr, bus, PCI_SLOT(devfn), > PCI_FUNC(devfn), > + PCI_CAP_ID_MSIX); > + if ( pos ) > { > struct arch_msix *msix = xzalloc(struct arch_msix); > + uint16_t ctrl; > if ( !msix ) > { > @@ -350,6 +353,10 @@ static struct pci_dev *alloc_pdev(struct > return NULL; > } > spin_lock_init(&msix->table_lock); > + > + ctrl = pci_conf_read16(pdev->sbdf, msix_control_reg(pos)); > + msix->nr_entries = msix_table_size(ctrl); Since you store the number of entries here, why not also store the position of the MSI-X capability since it's also immutable? That would prevent having to fetch it again in msix_capability_init. Thanks, Roger. _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |