From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Jan Beulich" Subject: [PATCH v3 03/10] x86/MSI-X: reduce fiddling with control register during restore Date: Fri, 05 Jun 2015 12:21:20 +0100 Message-ID: <5571A250020000780008145E@mail.emea.novell.com> References: <55719F9D0200007800081425@mail.emea.novell.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1Z0pgg-0003OL-Dj for xen-devel@lists.xenproject.org; Fri, 05 Jun 2015 11:21:22 +0000 In-Reply-To: <55719F9D0200007800081425@mail.emea.novell.com> Content-Disposition: inline List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel Cc: Andrew Cooper , Keir Fraser List-Id: xen-devel@lists.xenproject.org Rather than disabling and enabling MSI-X once per vector, do it just once per device. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper --- a/xen/arch/x86/msi.c +++ b/xen/arch/x86/msi.c @@ -1243,6 +1243,9 @@ int pci_restore_msi_state(struct pci_dev struct msi_desc *entry, *tmp; struct irq_desc *desc; struct msi_msg msg; + u8 slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn); + unsigned int type = 0, pos = 0; + u16 control = 0; ASSERT(spin_is_locked(&pcidevs_lock)); @@ -1259,8 +1262,6 @@ int pci_restore_msi_state(struct pci_dev list_for_each_entry_safe( entry, tmp, &pdev->msi_list, list ) { unsigned int i = 0, nr = 1; - u16 control = 0; - u8 slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn); irq = entry->irq; desc = &irq_desc[irq]; @@ -1277,31 +1278,38 @@ int pci_restore_msi_state(struct pci_dev pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), i); spin_unlock_irqrestore(&desc->lock, flags); + if ( type == PCI_CAP_ID_MSIX ) + pci_conf_write16(pdev->seg, pdev->bus, slot, func, + msix_control_reg(pos), + control & ~PCI_MSIX_FLAGS_ENABLE); return -EINVAL; } + ASSERT(!type || type == entry->msi_attrib.type); + pos = entry->msi_attrib.pos; if ( entry->msi_attrib.type == PCI_CAP_ID_MSI ) { msi_set_enable(pdev, 0); nr = entry->msi.nvec; } - else if ( entry->msi_attrib.type == PCI_CAP_ID_MSIX ) + else if ( !type && entry->msi_attrib.type == PCI_CAP_ID_MSIX ) { control = pci_conf_read16(pdev->seg, pdev->bus, slot, func, - msix_control_reg(entry->msi_attrib.pos)); + msix_control_reg(pos)); pci_conf_write16(pdev->seg, pdev->bus, slot, func, - msix_control_reg(entry->msi_attrib.pos), + msix_control_reg(pos), control | (PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL)); if ( unlikely(!memory_decoded(pdev)) ) { spin_unlock_irqrestore(&desc->lock, flags); pci_conf_write16(pdev->seg, pdev->bus, slot, func, - msix_control_reg(entry->msi_attrib.pos), + msix_control_reg(pos), control & ~PCI_MSIX_FLAGS_ENABLE); return -ENXIO; } } + type = entry->msi_attrib.type; msg = entry->msg; write_msi_msg(entry, &msg); @@ -1324,9 +1332,9 @@ int pci_restore_msi_state(struct pci_dev spin_unlock_irqrestore(&desc->lock, flags); - if ( entry->msi_attrib.type == PCI_CAP_ID_MSI ) + if ( type == PCI_CAP_ID_MSI ) { - unsigned int cpos = msi_control_reg(entry->msi_attrib.pos); + unsigned int cpos = msi_control_reg(pos); control = pci_conf_read16(pdev->seg, pdev->bus, slot, func, cpos) & ~PCI_MSI_FLAGS_QSIZE; @@ -1336,12 +1344,13 @@ int pci_restore_msi_state(struct pci_dev msi_set_enable(pdev, 1); } - else if ( entry->msi_attrib.type == PCI_CAP_ID_MSIX ) - pci_conf_write16(pdev->seg, pdev->bus, slot, func, - msix_control_reg(entry->msi_attrib.pos), - control | PCI_MSIX_FLAGS_ENABLE); } + if ( type == PCI_CAP_ID_MSIX ) + pci_conf_write16(pdev->seg, pdev->bus, slot, func, + msix_control_reg(pos), + control | PCI_MSIX_FLAGS_ENABLE); + return 0; }