From patchwork Tue Jul 16 10:16:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paul Durrant X-Patchwork-Id: 11045849 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 67B3A138D for ; Tue, 16 Jul 2019 10:19:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5731E28451 for ; Tue, 16 Jul 2019 10:19:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4B99F285A8; Tue, 16 Jul 2019 10:19:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A443128451 for ; Tue, 16 Jul 2019 10:19:12 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hnKWA-0006HU-6g; Tue, 16 Jul 2019 10:17:06 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hnKW8-0006HP-CB for xen-devel@lists.xenproject.org; Tue, 16 Jul 2019 10:17:04 +0000 X-Inumbo-ID: da54892c-a7b2-11e9-8980-bc764e045a96 Received: from esa5.hc3370-68.iphmx.com (unknown [216.71.155.168]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id da54892c-a7b2-11e9-8980-bc764e045a96; Tue, 16 Jul 2019 10:17:02 +0000 (UTC) Authentication-Results: esa5.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=paul.durrant@citrix.com; spf=Pass smtp.mailfrom=Paul.Durrant@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of paul.durrant@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Paul.Durrant@citrix.com"; x-sender="paul.durrant@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa5.hc3370-68.iphmx.com: domain of Paul.Durrant@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Paul.Durrant@citrix.com"; x-sender="Paul.Durrant@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ~all" Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Paul.Durrant@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: EM0GV+ecy1n5forbrenh4tHGmCp6dTs7nrOjO6/yuV0SxmJ3wViFOkygw18sOrlKD300j38BRf v/TjpPfMhPDPsBqkZUXb+IPmysM/X3rRXpr4YuGY5Tm8IVeF5qdUN7fINpbZtJMalCyUSDmYPO Qa/adRIwEa6Xu96nUJeBKN/1z3O3VYVE/EmYOBmGTUsAwYdGCW4CKFIw0IHmvGoaqxuaOtT7iC vkNWAVBdEIGrotg4Qjrn9aneM7aio5ngbsXNkVTFAOoGUnxDiihxjzk1qkHTNTTUkuDwaG/AZy PV0= X-SBRS: 2.7 X-MesageID: 3068124 X-Ironport-Server: esa5.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.63,498,1557201600"; d="scan'208";a="3068124" From: Paul Durrant To: Date: Tue, 16 Jul 2019 11:16:55 +0100 Message-ID: <20190716101657.23327-3-paul.durrant@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190716101657.23327-1-paul.durrant@citrix.com> References: <20190716101657.23327-1-paul.durrant@citrix.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH v3 2/4] pci: add all-device iterator function... X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Stefano Stabellini , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Ian Jackson , Tim Deegan , Julien Grall , Paul Durrant , Jan Beulich Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP ...and use it for setup_hwdom_pci_devices() and dump_pci_devices(). The unlock/process-pending-softirqs/lock sequence that was in _setup_hwdom_pci_devices() is now done in the generic iterator function, which does mean it is also done (unnecessarily) in the case of dump_pci_devices(), since run_all_nonirq_keyhandlers() will call process_pending_softirqs() before invoking each key handler anyway, but this is not performance critical code. The "==== segment XXXX ====" headline that was in _dump_pci_devices() has been dropped because it is non-trivial to deal with it when using a generic all-device iterator and, since the segment number is included in every log line anyway, it didn't add much value anyway. Signed-off-by: Paul Durrant Reviewed-by: "Roger Pau Monné" --- Cc: Jan Beulich Cc: Andrew Cooper Cc: George Dunlap Cc: Ian Jackson Cc: Julien Grall Cc: Konrad Rzeszutek Wilk Cc: Stefano Stabellini Cc: Tim Deegan Cc: Wei Liu v3: - Addressed review comments from Roger. v2: - New in v2. --- xen/drivers/passthrough/pci.c | 121 ++++++++++++++++++++++++------------------ xen/include/xen/pci.h | 1 + 2 files changed, 69 insertions(+), 53 deletions(-) diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c index e88689425d..4bb9996049 100644 --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -1134,64 +1134,87 @@ static void __hwdom_init setup_one_hwdom_device(const struct setup_hwdom *ctxt, ctxt->d->domain_id, err); } -static int __hwdom_init _setup_hwdom_pci_devices(struct pci_seg *pseg, void *arg) +static int __hwdom_init setup_hwdom_pci_device(struct pci_dev *pdev, void *arg) { struct setup_hwdom *ctxt = arg; - int bus, devfn; + struct domain *d = ctxt->d; - for ( bus = 0; bus < 256; bus++ ) + if ( !pdev->domain ) + { + pdev->domain = d; + list_add(&pdev->domain_list, &d->pdev_list); + setup_one_hwdom_device(ctxt, pdev); + } + else if ( pdev->domain == dom_xen ) { - for ( devfn = 0; devfn < 256; devfn++ ) + pdev->domain = d; + setup_one_hwdom_device(ctxt, pdev); + pdev->domain = dom_xen; + } + else if ( pdev->domain != d ) + printk(XENLOG_WARNING "Dom%pd owning %04x:%02x:%02x.%u?\n", + pdev->domain, pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn), + PCI_FUNC(pdev->devfn)); + + return 0; +} + +struct psdi_ctxt { + int (*cb)(struct pci_dev *, void *); + void *arg; +}; + +static int pci_segment_devices_iterate(struct pci_seg *pseg, void *arg) +{ + struct psdi_ctxt *ctxt = arg; + unsigned int bus, devfn; + int rc = 0; + + /* + * We don't iterate by walking pseg->alldevs_list here because that + * would make the pcidevs_unlock()/lock() sequence below unsafe. + */ + for ( bus = 0; !rc && bus < 256; bus++ ) + for ( devfn = 0; !rc && devfn < 256; devfn++ ) { struct pci_dev *pdev = pci_get_pdev(pseg->nr, bus, devfn); if ( !pdev ) continue; - if ( !pdev->domain ) - { - pdev->domain = ctxt->d; - list_add(&pdev->domain_list, &ctxt->d->pdev_list); - setup_one_hwdom_device(ctxt, pdev); - } - else if ( pdev->domain == dom_xen ) - { - pdev->domain = ctxt->d; - setup_one_hwdom_device(ctxt, pdev); - pdev->domain = dom_xen; - } - else if ( pdev->domain != ctxt->d ) - printk(XENLOG_WARNING "Dom%d owning %04x:%02x:%02x.%u?\n", - pdev->domain->domain_id, pseg->nr, bus, - PCI_SLOT(devfn), PCI_FUNC(devfn)); - - if ( iommu_verbose ) - { - pcidevs_unlock(); - process_pending_softirqs(); - pcidevs_lock(); - } - } + rc = ctxt->cb(pdev, ctxt->arg); - if ( !iommu_verbose ) - { + /* + * Err on the safe side and assume the callback has taken + * a significant amount of time. + */ pcidevs_unlock(); process_pending_softirqs(); pcidevs_lock(); } - } - return 0; + return rc; +} + +int pci_pdevs_iterate(int (*cb)(struct pci_dev *, void *), void *arg) +{ + struct psdi_ctxt ctxt = { .cb = cb, .arg = arg }; + int rc; + + pcidevs_lock(); + rc = pci_segments_iterate(pci_segment_devices_iterate, &ctxt); + pcidevs_unlock(); + + return rc; } void __hwdom_init setup_hwdom_pci_devices( struct domain *d, int (*handler)(u8 devfn, struct pci_dev *)) { struct setup_hwdom ctxt = { .d = d, .handler = handler }; + int rc = pci_pdevs_iterate(setup_hwdom_pci_device, &ctxt); - pcidevs_lock(); - pci_segments_iterate(_setup_hwdom_pci_devices, &ctxt); - pcidevs_unlock(); + ASSERT(!rc); } #ifdef CONFIG_ACPI @@ -1294,24 +1317,18 @@ bool_t pcie_aer_get_firmware_first(const struct pci_dev *pdev) } #endif -static int _dump_pci_devices(struct pci_seg *pseg, void *arg) +static int dump_pci_device(struct pci_dev *pdev, void *arg) { - struct pci_dev *pdev; struct msi_desc *msi; - printk("==== segment %04x ====\n", pseg->nr); - - list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list ) - { - printk("%04x:%02x:%02x.%u - dom %-3d - node %-3d - MSIs < ", - pseg->nr, pdev->bus, - PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), - pdev->domain ? pdev->domain->domain_id : -1, - (pdev->node != NUMA_NO_NODE) ? pdev->node : -1); - list_for_each_entry ( msi, &pdev->msi_list, list ) - printk("%d ", msi->irq); - printk(">\n"); - } + printk("%04x:%02x:%02x.%u - dom %-3d - node %-3d - MSIs < ", + pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn), + PCI_FUNC(pdev->devfn), + pdev->domain ? pdev->domain->domain_id : -1, + (pdev->node != NUMA_NO_NODE) ? pdev->node : -1); + list_for_each_entry ( msi, &pdev->msi_list, list ) + printk("%d ", msi->irq); + printk(">\n"); return 0; } @@ -1319,9 +1336,7 @@ static int _dump_pci_devices(struct pci_seg *pseg, void *arg) static void dump_pci_devices(unsigned char ch) { printk("==== PCI devices ====\n"); - pcidevs_lock(); - pci_segments_iterate(_dump_pci_devices, NULL); - pcidevs_unlock(); + pci_pdevs_iterate(dump_pci_device, NULL); } static int __init setup_dump_pcidevs(void) diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h index 04a9f46cc3..79eb25417b 100644 --- a/xen/include/xen/pci.h +++ b/xen/include/xen/pci.h @@ -154,6 +154,7 @@ int find_upstream_bridge(u16 seg, u8 *bus, u8 *devfn, u8 *secbus); struct pci_dev *pci_lock_pdev(int seg, int bus, int devfn); struct pci_dev *pci_lock_domain_pdev( struct domain *, int seg, int bus, int devfn); +int pci_pdevs_iterate(int (*cb)(struct pci_dev *, void *), void *arg); void setup_hwdom_pci_devices(struct domain *, int (*)(u8 devfn, struct pci_dev *));