From patchwork Fri Jul 11 12:30:02 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ethan zhao X-Patchwork-Id: 4533341 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 3F0C29F1C4 for ; Fri, 11 Jul 2014 12:31:32 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 4DE3F20260 for ; Fri, 11 Jul 2014 12:31:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4EE6820251 for ; Fri, 11 Jul 2014 12:31:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753487AbaGKMbB (ORCPT ); Fri, 11 Jul 2014 08:31:01 -0400 Received: from userp1040.oracle.com ([156.151.31.81]:26934 "EHLO userp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752450AbaGKMa5 (ORCPT ); Fri, 11 Jul 2014 08:30:57 -0400 Received: from acsinet22.oracle.com (acsinet22.oracle.com [141.146.126.238]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id s6BCUehI012430 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 11 Jul 2014 12:30:41 GMT Received: from aserz7021.oracle.com (aserz7021.oracle.com [141.146.126.230]) by acsinet22.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id s6BCUdoW024469 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 11 Jul 2014 12:30:40 GMT Received: from abhmp0010.oracle.com (abhmp0010.oracle.com [141.146.116.16]) by aserz7021.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id s6BCUdKr011279; Fri, 11 Jul 2014 12:30:39 GMT Received: from etnux.cn.oracle.com (/10.182.70.25) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 11 Jul 2014 05:30:39 -0700 From: Ethan Zhao To: bhelgaas@google.com, konrad.wilk@oracle.com, boris.ostrovsky@oracle.com, david.vrabel@citrix.com, gleb@kernel.org, pbonzini@redhat.com, jeffrey.t.kirsher@intel.com, jesse.brandeburg@intel.com, bruce.w.allan@intel.com, carolyn.wyborny@intel.com, donald.c.skidmore@intel.com, gregory.v.rose@intel.com, alexander.h.duyck@intel.com, john.ronciak@intel.com, mitch.a.williams@intel.com, alex.williamson@redhat.com Cc: linux-pci@vger.kernel.org, kvm@vger.kernel.org, linux.nics@intel.com, e1000-devel@lists.sourceforge.net, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, ethan.kernel@gmail.com, vaughan.cao@oracle.com, Ethan Zhao Subject: [PATCH 2/2 V3] PCI: implement VFs assignment reference counter Date: Fri, 11 Jul 2014 20:30:02 +0800 Message-Id: <1405081802-419-2-git-send-email-ethan.zhao@oracle.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1405081802-419-1-git-send-email-ethan.zhao@oracle.com> References: <1405081802-419-1-git-send-email-ethan.zhao@oracle.com> X-Source-IP: acsinet22.oracle.com [141.146.126.238] Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Current implementation of helper function pci_vfs_assigned() is a little complex, to get sum of VFs that assigned to VM, access low level configuration space register and then loop in traversing device tree. This patch introduces an atomic reference counter for VFs those were assigned to VM in struct pci_sriov. and simplify the code in pci_vfs_assigned(). v3: change the naming of device assignment helpers, because they work for all kind of PCI device, not only SR-IOV (david.vrabel@citrix.com) v2: reorder the patchset according to the suggestion from alex.williamson@redhat.com Signed-off-by: Ethan Zhao --- drivers/pci/iov.c | 42 ++++++++++++++++-------------------------- drivers/pci/pci.h | 1 + 2 files changed, 17 insertions(+), 26 deletions(-) diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 090f827..10efe43 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -382,6 +382,7 @@ found: iov->nres = nres; iov->ctrl = ctrl; iov->total_VFs = total; + atomic_set(&iov->VFs_assigned_cnt, 0); iov->offset = offset; iov->stride = stride; iov->pgsz = pgsz; @@ -603,43 +604,22 @@ int pci_num_vf(struct pci_dev *dev) EXPORT_SYMBOL_GPL(pci_num_vf); /** - * pci_vfs_assigned - returns number of VFs are assigned to a guest - * @dev: the PCI device + * pci_vfs_assigned - returns number of VFs are assigned to VM + * @dev: the physical PCI device that contains the VFs. * * Returns number of VFs belonging to this device that are assigned to a guest. * If device is not a physical function returns 0. */ int pci_vfs_assigned(struct pci_dev *dev) { - struct pci_dev *vfdev; - unsigned int vfs_assigned = 0; - unsigned short dev_id; /* only search if we are a PF */ if (!dev->is_physfn) return 0; - /* - * determine the device ID for the VFs, the vendor ID will be the - * same as the PF so there is no need to check for that one - */ - pci_read_config_word(dev, dev->sriov->pos + PCI_SRIOV_VF_DID, &dev_id); - - /* loop through all the VFs to see if we own any that are assigned */ - vfdev = pci_get_device(dev->vendor, dev_id, NULL); - while (vfdev) { - /* - * It is considered assigned if it is a virtual function with - * our dev as the physical function and the assigned bit is set - */ - if (vfdev->is_virtfn && (vfdev->physfn == dev) && - (vfdev->dev_flags & PCI_DEV_FLAGS_ASSIGNED)) - vfs_assigned++; - - vfdev = pci_get_device(dev->vendor, dev_id, vfdev); - } - - return vfs_assigned; + if (dev->sriov) + return atomic_read(&dev->sriov->VFs_assigned_cnt); + return 0; } EXPORT_SYMBOL_GPL(pci_vfs_assigned); @@ -650,6 +630,11 @@ EXPORT_SYMBOL_GPL(pci_vfs_assigned); void pci_iov_assign_device(struct pci_dev *pdev) { pdev->dev_flags |= PCI_DEV_FLAGS_ASSIGNED; + if (pdev->is_virtfn && !pdev->is_physfn) + if (pdev->physfn) + if (pdev->physfn->sriov) + atomic_inc(&pdev->physfn->sriov-> + VFs_assigned_cnt); } EXPORT_SYMBOL_GPL(pci_iov_assign_device); @@ -660,6 +645,11 @@ EXPORT_SYMBOL_GPL(pci_iov_assign_device); void pci_iov_deassign_device(struct pci_dev *pdev) { pdev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED; + if (pdev->is_virtfn && !pdev->is_physfn) + if (pdev->physfn) + if (pdev->physfn->sriov) + atomic_dec(&pdev->physfn->sriov-> + VFs_assigned_cnt); } EXPORT_SYMBOL_GPL(pci_iov_deassign_device); diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 6bd0822..d17bda2 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -235,6 +235,7 @@ struct pci_sriov { u32 pgsz; /* page size for BAR alignment */ u8 link; /* Function Dependency Link */ u16 driver_max_VFs; /* max num VFs driver supports */ + atomic_t VFs_assigned_cnt; /* counter of VFs assigned to VM */ struct pci_dev *dev; /* lowest numbered PF */ struct pci_dev *self; /* this PF */ struct mutex lock; /* lock for VF bus */