All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yu Zhao <yu.zhao@intel.com>
To: dwmw2@infradead.org
Cc: jbarnes@virtuousgeek.org, linux-pci@vger.kernel.org,
	iommu@lists.linux-foundation.org, kvm@vger.kernel.org,
	Yu Zhao <yu.zhao@intel.com>
Subject: [PATCH v5 2/6] PCI: handle Virtual Function ATS enabling
Date: Mon, 18 May 2009 13:51:33 +0800	[thread overview]
Message-ID: <1242625897-1678-3-git-send-email-yu.zhao@intel.com> (raw)
In-Reply-To: <1242625897-1678-1-git-send-email-yu.zhao@intel.com>

The SR-IOV spec requires that the Smallest Translation Unit and
the Invalidate Queue Depth fields in the Virtual Function ATS
capability are hardwired to 0. If a function is a Virtual Function,
then and set its Physical Function's STU before enabling the ATS.

Signed-off-by: Yu Zhao <yu.zhao@intel.com>
Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/pci/iov.c |   66 +++++++++++++++++++++++++++++++++++++++++-----------
 drivers/pci/pci.h |    4 ++-
 2 files changed, 55 insertions(+), 15 deletions(-)

diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index 0a7a1b4..4151404 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -491,10 +491,10 @@ found:
 
 	if (pdev)
 		iov->dev = pci_dev_get(pdev);
-	else {
+	else
 		iov->dev = dev;
-		mutex_init(&iov->lock);
-	}
+
+	mutex_init(&iov->lock);
 
 	dev->sriov = iov;
 	dev->is_physfn = 1;
@@ -514,11 +514,11 @@ static void sriov_release(struct pci_dev *dev)
 {
 	BUG_ON(dev->sriov->nr_virtfn);
 
-	if (dev == dev->sriov->dev)
-		mutex_destroy(&dev->sriov->lock);
-	else
+	if (dev != dev->sriov->dev)
 		pci_dev_put(dev->sriov->dev);
 
+	mutex_destroy(&dev->sriov->lock);
+
 	kfree(dev->sriov);
 	dev->sriov = NULL;
 }
@@ -723,19 +723,40 @@ int pci_enable_ats(struct pci_dev *dev, int ps)
 	int rc;
 	u16 ctrl;
 
-	BUG_ON(dev->ats);
+	BUG_ON(dev->ats && dev->ats->is_enabled);
 
 	if (ps < PCI_ATS_MIN_STU)
 		return -EINVAL;
 
-	rc = ats_alloc_one(dev, ps);
-	if (rc)
-		return rc;
+	if (dev->is_physfn || dev->is_virtfn) {
+		struct pci_dev *pdev = dev->is_physfn ? dev : dev->physfn;
+
+		mutex_lock(&pdev->sriov->lock);
+		if (pdev->ats)
+			rc = pdev->ats->stu == ps ? 0 : -EINVAL;
+		else
+			rc = ats_alloc_one(pdev, ps);
+
+		if (!rc)
+			pdev->ats->ref_cnt++;
+		mutex_unlock(&pdev->sriov->lock);
+		if (rc)
+			return rc;
+	}
+
+	if (!dev->is_physfn) {
+		rc = ats_alloc_one(dev, ps);
+		if (rc)
+			return rc;
+	}
 
 	ctrl = PCI_ATS_CTRL_ENABLE;
-	ctrl |= PCI_ATS_CTRL_STU(ps - PCI_ATS_MIN_STU);
+	if (!dev->is_virtfn)
+		ctrl |= PCI_ATS_CTRL_STU(ps - PCI_ATS_MIN_STU);
 	pci_write_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, ctrl);
 
+	dev->ats->is_enabled = 1;
+
 	return 0;
 }
 
@@ -747,13 +768,26 @@ void pci_disable_ats(struct pci_dev *dev)
 {
 	u16 ctrl;
 
-	BUG_ON(!dev->ats);
+	BUG_ON(!dev->ats || !dev->ats->is_enabled);
 
 	pci_read_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, &ctrl);
 	ctrl &= ~PCI_ATS_CTRL_ENABLE;
 	pci_write_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, ctrl);
 
-	ats_free_one(dev);
+	dev->ats->is_enabled = 0;
+
+	if (dev->is_physfn || dev->is_virtfn) {
+		struct pci_dev *pdev = dev->is_physfn ? dev : dev->physfn;
+
+		mutex_lock(&pdev->sriov->lock);
+		pdev->ats->ref_cnt--;
+		if (!pdev->ats->ref_cnt)
+			ats_free_one(pdev);
+		mutex_unlock(&pdev->sriov->lock);
+	}
+
+	if (!dev->is_physfn)
+		ats_free_one(dev);
 }
 
 /**
@@ -765,13 +799,17 @@ void pci_disable_ats(struct pci_dev *dev)
  * The ATS spec uses 0 in the Invalidate Queue Depth field to
  * indicate that the function can accept 32 Invalidate Request.
  * But here we use the `real' values (i.e. 1~32) for the Queue
- * Depth.
+ * Depth; and 0 indicates the function shares the Queue with
+ * other functions (doesn't exclusively own a Queue).
  */
 int pci_ats_queue_depth(struct pci_dev *dev)
 {
 	int pos;
 	u16 cap;
 
+	if (dev->is_virtfn)
+		return 0;
+
 	if (dev->ats)
 		return dev->ats->qdep;
 
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 3c2ec64..f73bcbe 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -234,6 +234,8 @@ struct pci_ats {
 	int pos;	/* capability position */
 	int stu;	/* Smallest Translation Unit */
 	int qdep;	/* Invalidate Queue Depth */
+	int ref_cnt;	/* Physical Function reference count */
+	int is_enabled:1;	/* Enable bit is set */
 };
 
 #ifdef CONFIG_PCI_IOV
@@ -255,7 +257,7 @@ extern int pci_ats_queue_depth(struct pci_dev *dev);
  */
 static inline int pci_ats_enabled(struct pci_dev *dev)
 {
-	return !!dev->ats;
+	return dev->ats && dev->ats->is_enabled;
 }
 #else
 static inline int pci_iov_init(struct pci_dev *dev)
-- 
1.5.6.4


  parent reply	other threads:[~2009-05-18  5:50 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-05-18  5:51 [PATCH v5 0/6] ATS capability support for Intel IOMMU Yu Zhao
2009-05-18  5:51 ` [PATCH v5 1/6] PCI: support the ATS capability Yu Zhao
2009-05-18  5:51 ` Yu Zhao [this message]
2009-05-18  5:51 ` [PATCH v5 3/6] VT-d: parse ATSR in DMA Remapping Reporting Structure Yu Zhao
2009-05-18  5:51 ` [PATCH v5 4/6] VT-d: add device IOTLB invalidation support Yu Zhao
2009-05-18  5:51 ` [PATCH v5 5/6] VT-d: cleanup iommu_flush_iotlb_psi and flush_unmaps Yu Zhao
2009-05-18  5:51 ` [PATCH v5 6/6] VT-d: support the device IOTLB Yu Zhao
2009-06-28 14:28   ` David Woodhouse
2009-06-29  3:07     ` Yu Zhao
2009-08-09  9:33   ` David Woodhouse
2009-08-09 10:28   ` David Woodhouse

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1242625897-1678-3-git-send-email-yu.zhao@intel.com \
    --to=yu.zhao@intel.com \
    --cc=dwmw2@infradead.org \
    --cc=iommu@lists.linux-foundation.org \
    --cc=jbarnes@virtuousgeek.org \
    --cc=kvm@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.