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

The SR-IOV spec requires the Smallest Translation Unit and the
Invalidate Queue Depth fields in the Virtual Function ATS capability
to be 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>
---
 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 8a9817c..0bf23fc 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;
 }
@@ -722,19 +722,40 @@ int pci_enable_ats(struct pci_dev *dev, int pgshift)
 	int rc;
 	u16 ctrl;
 
-	BUG_ON(dev->ats);
+	BUG_ON(dev->ats && dev->ats->is_enabled);
 
 	if (pgshift < PCI_ATS_MIN_STU)
 		return -EINVAL;
 
-	rc = ats_alloc_one(dev, pgshift);
-	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 == pgshift ? 0 : -EINVAL;
+		else
+			rc = ats_alloc_one(pdev, pgshift);
+
+		if (!rc)
+			pdev->ats->ref_cnt++;
+		mutex_unlock(&pdev->sriov->lock);
+		if (rc)
+			return rc;
+	}
+
+	if (!dev->is_physfn) {
+		rc = ats_alloc_one(dev, pgshift);
+		if (rc)
+			return rc;
+	}
 
 	ctrl = PCI_ATS_CTRL_ENABLE;
-	ctrl |= PCI_ATS_CTRL_STU(pgshift - PCI_ATS_MIN_STU);
+	if (!dev->is_virtfn)
+		ctrl |= PCI_ATS_CTRL_STU(pgshift - PCI_ATS_MIN_STU);
 	pci_write_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, ctrl);
 
+	dev->ats->is_enabled = 1;
+
 	return 0;
 }
 
@@ -746,13 +767,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);
 }
 
 /**
@@ -764,13 +798,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 9f0db6a..8ecd185 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -223,6 +223,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
@@ -244,7 +246,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-03-23  8:00 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-23  7:58 [PATCH v4 0/6] PCI: support the ATS capability Yu Zhao
2009-03-23  7:58 ` [PATCH v4 1/6] " Yu Zhao
2009-03-23  7:58 ` Yu Zhao [this message]
2009-03-23  7:58 ` [PATCH v4 3/6] VT-d: parse ATSR in DMA Remapping Reporting Structure Yu Zhao
2009-03-23  7:59 ` [PATCH v4 4/6] VT-d: add device IOTLB invalidation support Yu Zhao
2009-03-29  5:19   ` Grant Grundler
2009-03-23  7:59 ` [PATCH v4 5/6] VT-d: cleanup iommu_flush_iotlb_psi and flush_unmaps Yu Zhao
2009-03-23  7:59 ` [PATCH v4 6/6] VT-d: support the device IOTLB Yu Zhao
2009-03-26 23:15 ` [PATCH v4 0/6] PCI: support the ATS capability Jesse Barnes
2009-03-29  5:21   ` Grant Grundler
2009-03-29 13:51   ` Matthew Wilcox
2009-03-30  1:56     ` Yu Zhao

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=1237795142-6606-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-kernel@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.