From: "Xu, Quan" <quan.xu@intel.com>
To: xen-devel@lists.xen.org
Cc: Kevin Tian <kevin.tian@intel.com>, Feng Wu <feng.wu@intel.com>,
Quan Xu <quan.xu@intel.com>,
dario.faggioli@citrix.com, Julien Grall <julien.grall@arm.com>,
Jan Beulich <jbeulich@suse.com>,
Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Subject: [PATCH v12 1/6] IOMMU: add a timeout parameter for device IOTLB invalidation
Date: Fri, 24 Jun 2016 13:51:53 +0800 [thread overview]
Message-ID: <1466747518-54402-2-git-send-email-quan.xu@intel.com> (raw)
In-Reply-To: <1466747518-54402-1-git-send-email-quan.xu@intel.com>
From: Quan Xu <quan.xu@intel.com>
The parameter 'iommu_dev_iotlb_timeout' specifies the timeout
of device IOTLB invalidation in milliseconds. By default, the
timeout is 1000 milliseconds, which can be boot-time changed.
We also confirmed with VT-d hardware team that 1 milliseconds
is large enough for VT-d IOMMU internal invalidation.
the existing panic() is eliminated and we bubble up the timeout
of device IOTLB invalidation for further processing, as the
PCI-e Address Translation Services (ATS) mandates a timeout of
60 seconds for device IOTLB invalidation. Obviously we can't
spin for 60 seconds or otherwise Xen hypervisor hangs.
Add a __must_check annotation. The followup patch titled
'VT-d IOTLB/Context/IEC flush issue' addresses the __mustcheck.
That is the other callers of this routine (two or three levels up)
ignore the return code. This patch does not address this but the
other does.
Signed-off-by: Quan Xu <quan.xu@intel.com>
CC: Julien Grall <julien.grall@arm.com>
CC: Jan Beulich <jbeulich@suse.com>
CC: Kevin Tian <kevin.tian@intel.com>
CC: Feng Wu <feng.wu@intel.com>
CC: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
v12:
1. enhance commit message.
2. change timeout from 1ms to 1000ms.
3. change IOMMU_QI_TIMEOUT to VTD_QI_TIMEOUT, with VTD_QI_TIMEOUT
having its MILLISECS() dropped.
4. enhance the whole expression of 'timeout = ...'
5. drop a blank line that doesn't belong here.
---
docs/misc/xen-command-line.markdown | 9 +++++++++
xen/drivers/passthrough/iommu.c | 3 +++
xen/drivers/passthrough/vtd/qinval.c | 32 +++++++++++++++++++++-----------
xen/include/xen/iommu.h | 2 ++
4 files changed, 35 insertions(+), 11 deletions(-)
diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown
index 7a271c0..0046f0d 100644
--- a/docs/misc/xen-command-line.markdown
+++ b/docs/misc/xen-command-line.markdown
@@ -1015,6 +1015,15 @@ debug hypervisor only).
>> Enable IOMMU debugging code (implies `verbose`).
+### iommu\_dev\_iotlb\_timeout
+> `= <integer>`
+
+> Default: `1000`
+
+Specify the timeout of the device IOTLB invalidation in milliseconds.
+By default, the timeout is 1000 ms. When you see error 'Queue invalidate
+wait descriptor timed out', try increasing this value.
+
### iommu\_inclusive\_mapping (VT-d)
> `= <boolean>`
diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c
index ef80b3c..7656aeb 100644
--- a/xen/drivers/passthrough/iommu.c
+++ b/xen/drivers/passthrough/iommu.c
@@ -24,6 +24,9 @@
static void parse_iommu_param(char *s);
static void iommu_dump_p2m_table(unsigned char key);
+unsigned int __read_mostly iommu_dev_iotlb_timeout = 1000;
+integer_param("iommu_dev_iotlb_timeout", iommu_dev_iotlb_timeout);
+
/*
* The 'iommu' parameter enables the IOMMU. Optional comma separated
* value may contain:
diff --git a/xen/drivers/passthrough/vtd/qinval.c b/xen/drivers/passthrough/vtd/qinval.c
index aa7841a..4788d5f 100644
--- a/xen/drivers/passthrough/vtd/qinval.c
+++ b/xen/drivers/passthrough/vtd/qinval.c
@@ -28,6 +28,8 @@
#include "vtd.h"
#include "extern.h"
+#define VTD_QI_TIMEOUT 1
+
static void print_qi_regs(struct iommu *iommu)
{
u64 val;
@@ -130,10 +132,10 @@ static void queue_invalidate_iotlb(struct iommu *iommu,
spin_unlock_irqrestore(&iommu->register_lock, flags);
}
-static int queue_invalidate_wait(struct iommu *iommu,
- u8 iflag, u8 sw, u8 fn)
+static int __must_check queue_invalidate_wait(struct iommu *iommu,
+ u8 iflag, u8 sw, u8 fn,
+ bool_t flush_dev_iotlb)
{
- s_time_t start_time;
volatile u32 poll_slot = QINVAL_STAT_INIT;
unsigned int index;
unsigned long flags;
@@ -163,14 +165,20 @@ static int queue_invalidate_wait(struct iommu *iommu,
/* Now we don't support interrupt method */
if ( sw )
{
+ s_time_t timeout;
+
/* In case all wait descriptor writes to same addr with same data */
- start_time = NOW();
+ timeout = NOW() + MILLISECS(flush_dev_iotlb ?
+ iommu_dev_iotlb_timeout : VTD_QI_TIMEOUT);
+
while ( poll_slot != QINVAL_STAT_DONE )
{
- if ( NOW() > (start_time + DMAR_OPERATION_TIMEOUT) )
+ if ( NOW() > timeout )
{
print_qi_regs(iommu);
- panic("queue invalidate wait descriptor was not executed");
+ printk(XENLOG_WARNING VTDPREFIX
+ " Queue invalidate wait descriptor timed out\n");
+ return -ETIMEDOUT;
}
cpu_relax();
}
@@ -180,12 +188,14 @@ static int queue_invalidate_wait(struct iommu *iommu,
return -EOPNOTSUPP;
}
-static int invalidate_sync(struct iommu *iommu)
+static int __must_check invalidate_sync(struct iommu *iommu,
+ bool_t flush_dev_iotlb)
{
struct qi_ctrl *qi_ctrl = iommu_qi_ctrl(iommu);
if ( qi_ctrl->qinval_maddr )
- return queue_invalidate_wait(iommu, 0, 1, 1);
+ return queue_invalidate_wait(iommu, 0, 1, 1, flush_dev_iotlb);
+
return 0;
}
@@ -254,7 +264,7 @@ static int __iommu_flush_iec(struct iommu *iommu, u8 granu, u8 im, u16 iidx)
int ret;
queue_invalidate_iec(iommu, granu, im, iidx);
- ret = invalidate_sync(iommu);
+ ret = invalidate_sync(iommu, 0);
/*
* reading vt-d architecture register will ensure
* draining happens in implementation independent way.
@@ -300,7 +310,7 @@ static int __must_check flush_context_qi(void *_iommu, u16 did,
{
queue_invalidate_context(iommu, did, sid, fm,
type >> DMA_CCMD_INVL_GRANU_OFFSET);
- ret = invalidate_sync(iommu);
+ ret = invalidate_sync(iommu, 0);
}
return ret;
}
@@ -344,7 +354,7 @@ static int __must_check flush_iotlb_qi(void *_iommu, u16 did, u64 addr,
dw, did, size_order, 0, addr);
if ( flush_dev_iotlb )
ret = dev_invalidate_iotlb(iommu, did, addr, size_order, type);
- rc = invalidate_sync(iommu);
+ rc = invalidate_sync(iommu, flush_dev_iotlb);
if ( !ret )
ret = rc;
}
diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h
index 8b23cc9..a759f2b 100644
--- a/xen/include/xen/iommu.h
+++ b/xen/include/xen/iommu.h
@@ -35,6 +35,8 @@ extern bool_t iommu_hap_pt_share;
extern bool_t iommu_debug;
extern bool_t amd_iommu_perdev_intremap;
+extern unsigned int iommu_dev_iotlb_timeout;
+
#define IOMMU_PAGE_SIZE(sz) (1UL << PAGE_SHIFT_##sz)
#define IOMMU_PAGE_MASK(sz) (~(u64)0 << PAGE_SHIFT_##sz)
#define IOMMU_PAGE_ALIGN(sz, addr) (((addr) + ~PAGE_MASK_##sz) & PAGE_MASK_##sz)
--
1.9.1
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
next prev parent reply other threads:[~2016-06-24 5:51 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-06-24 5:51 [PATCH v12 0/6] VT-d Device-TLB flush issue Xu, Quan
2016-06-24 5:51 ` Xu, Quan [this message]
2016-06-24 11:30 ` [PATCH v12 1/6] IOMMU: add a timeout parameter for device IOTLB invalidation Tian, Kevin
2016-06-27 8:03 ` Jan Beulich
2016-06-27 8:19 ` Xu, Quan
2016-06-27 8:28 ` Jan Beulich
2016-06-27 8:34 ` Xu, Quan
2016-06-24 5:51 ` [PATCH v12 2/6] vt-d: synchronize for Device-TLB flush one by one Xu, Quan
2016-06-24 11:33 ` Tian, Kevin
2016-06-24 5:51 ` [PATCH v12 3/6] vt-d: convert conditionals of qi_ctrl->qinval_maddr into ASSERT()s Xu, Quan
2016-06-24 11:35 ` Tian, Kevin
2016-06-24 5:51 ` [PATCH v12 4/6] IOMMU/x86: using a struct pci_dev* instead of SBDF Xu, Quan
2016-06-24 11:46 ` Tian, Kevin
2016-06-26 8:57 ` Xu, Quan
2016-06-26 10:32 ` Xu, Quan
2016-06-29 1:59 ` Tian, Kevin
2016-06-27 8:17 ` Jan Beulich
2016-06-27 8:25 ` Jan Beulich
2016-06-27 11:11 ` Xu, Quan
2016-06-27 15:19 ` Jan Beulich
2016-06-28 1:31 ` Xu, Quan
2016-06-24 5:51 ` [PATCH v12 5/6] IOMMU: move the domain crash logic up to the generic IOMMU layer Xu, Quan
2016-06-24 11:48 ` Tian, Kevin
2016-06-26 8:58 ` Xu, Quan
2016-06-27 8:18 ` Jan Beulich
2016-06-24 5:51 ` [PATCH v12 6/6] vt-d: fix vt-d Device-TLB flush timeout issue Xu, Quan
2016-06-24 11:55 ` Tian, Kevin
2016-06-24 12:54 ` Jan Beulich
2016-06-26 9:18 ` Xu, Quan
2016-06-27 7:56 ` Jan Beulich
2016-06-27 8:24 ` Jan Beulich
2016-06-27 12:56 ` Xu, Quan
2016-06-27 15:21 ` Jan Beulich
2016-06-28 7:06 ` Xu, Quan
2016-06-28 7:24 ` Jan Beulich
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=1466747518-54402-2-git-send-email-quan.xu@intel.com \
--to=quan.xu@intel.com \
--cc=dario.faggioli@citrix.com \
--cc=feng.wu@intel.com \
--cc=jbeulich@suse.com \
--cc=julien.grall@arm.com \
--cc=kevin.tian@intel.com \
--cc=suravee.suthikulpanit@amd.com \
--cc=xen-devel@lists.xen.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).