summaryrefslogtreecommitdiff
path: root/drivers/iommu/iommu-debug.c
diff options
context:
space:
mode:
authorMitchel Humpherys <mitchelh@codeaurora.org>2015-10-02 16:17:57 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-22 11:14:23 -0700
commitef702c85fa87c1410355a1689d93aeef7ef452d0 (patch)
treee15037c5ad738471a964ca8d32e6b607d0e813ea /drivers/iommu/iommu-debug.c
parent88a510ad7c00bfcb7265ec1cae94138655937d5c (diff)
iommu/iommu-debug: Use more iterations while profiling
Currently we only take one sample per buffer size per API when doing profiling. This results in high run-to-run variance in the results. Use more iterations to help smooth this out. Change-Id: I3779007a2f69ef79b573285b2422554f42dda99f Signed-off-by: Mitchel Humpherys <mitchelh@codeaurora.org>
Diffstat (limited to 'drivers/iommu/iommu-debug.c')
-rw-r--r--drivers/iommu/iommu-debug.c101
1 files changed, 60 insertions, 41 deletions
diff --git a/drivers/iommu/iommu-debug.c b/drivers/iommu/iommu-debug.c
index 48e903ab8373..c8081e41a5bd 100644
--- a/drivers/iommu/iommu-debug.c
+++ b/drivers/iommu/iommu-debug.c
@@ -424,6 +424,8 @@ static const char * const _size_to_string(unsigned long size)
return "unknown size, please add to _size_to_string";
}
+#define ITERS_PER_OP 100
+
static void iommu_debug_device_profiling(struct seq_file *s, struct device *dev,
bool secure)
{
@@ -476,33 +478,42 @@ static void iommu_debug_device_profiling(struct seq_file *s, struct device *dev,
goto out_domain_free;
}
+ seq_printf(s, "(average over %d iterations)\n", ITERS_PER_OP);
seq_printf(s, "%8s %15s %12s\n", "size", "iommu_map", "iommu_unmap");
for (sz = sizes; *sz; ++sz) {
unsigned long size = *sz;
size_t unmapped;
- s64 map_elapsed_us, unmap_elapsed_us;
+ u64 map_elapsed_us = 0, unmap_elapsed_us = 0;
struct timespec tbefore, tafter, diff;
-
- getnstimeofday(&tbefore);
- if (iommu_map(domain, iova, paddr, size,
- IOMMU_READ | IOMMU_WRITE)) {
- seq_puts(s, "Failed to map\n");
- continue;
- }
- getnstimeofday(&tafter);
- diff = timespec_sub(tafter, tbefore);
- map_elapsed_us = div_s64(timespec_to_ns(&diff), 1000);
-
- getnstimeofday(&tbefore);
- unmapped = iommu_unmap(domain, iova, size);
- if (unmapped != size) {
- seq_printf(s, "Only unmapped %zx instead of %zx\n",
- unmapped, size);
- continue;
+ int i;
+
+ for (i = 0; i < ITERS_PER_OP; ++i) {
+ getnstimeofday(&tbefore);
+ if (iommu_map(domain, iova, paddr, size,
+ IOMMU_READ | IOMMU_WRITE)) {
+ seq_puts(s, "Failed to map\n");
+ continue;
+ }
+ getnstimeofday(&tafter);
+ diff = timespec_sub(tafter, tbefore);
+ map_elapsed_us += div_s64(timespec_to_ns(&diff), 1000);
+
+ getnstimeofday(&tbefore);
+ unmapped = iommu_unmap(domain, iova, size);
+ if (unmapped != size) {
+ seq_printf(s,
+ "Only unmapped %zx instead of %zx\n",
+ unmapped, size);
+ continue;
+ }
+ getnstimeofday(&tafter);
+ diff = timespec_sub(tafter, tbefore);
+ unmap_elapsed_us += div_s64(timespec_to_ns(&diff),
+ 1000);
}
- getnstimeofday(&tafter);
- diff = timespec_sub(tafter, tbefore);
- unmap_elapsed_us = div_s64(timespec_to_ns(&diff), 1000);
+
+ map_elapsed_us /= ITERS_PER_OP;
+ unmap_elapsed_us /= ITERS_PER_OP;
seq_printf(s, "%8s %12lld us %9lld us\n", _size_to_string(size),
map_elapsed_us, unmap_elapsed_us);
@@ -513,10 +524,11 @@ static void iommu_debug_device_profiling(struct seq_file *s, struct device *dev,
for (sz = sizes; *sz; ++sz) {
unsigned long size = *sz;
size_t unmapped;
- s64 map_elapsed_us, unmap_elapsed_us;
+ u64 map_elapsed_us = 0, unmap_elapsed_us = 0;
struct timespec tbefore, tafter, diff;
struct sg_table table;
unsigned long chunk_size = SZ_4K;
+ int i;
if (iommu_debug_build_phoney_sg_table(dev, &table, size,
chunk_size)) {
@@ -525,26 +537,33 @@ static void iommu_debug_device_profiling(struct seq_file *s, struct device *dev,
goto out_detach;
}
- getnstimeofday(&tbefore);
- if (iommu_map_sg(domain, iova, table.sgl, table.nents,
- IOMMU_READ | IOMMU_WRITE) != size) {
- seq_puts(s, "Failed to map_sg\n");
- goto next;
- }
- getnstimeofday(&tafter);
- diff = timespec_sub(tafter, tbefore);
- map_elapsed_us = div_s64(timespec_to_ns(&diff), 1000);
-
- getnstimeofday(&tbefore);
- unmapped = iommu_unmap(domain, iova, size);
- if (unmapped != size) {
- seq_printf(s, "Only unmapped %zx instead of %zx\n",
- unmapped, size);
- goto next;
+ for (i = 0; i < ITERS_PER_OP; ++i) {
+ getnstimeofday(&tbefore);
+ if (iommu_map_sg(domain, iova, table.sgl, table.nents,
+ IOMMU_READ | IOMMU_WRITE) != size) {
+ seq_puts(s, "Failed to map_sg\n");
+ goto next;
+ }
+ getnstimeofday(&tafter);
+ diff = timespec_sub(tafter, tbefore);
+ map_elapsed_us += div_s64(timespec_to_ns(&diff), 1000);
+
+ getnstimeofday(&tbefore);
+ unmapped = iommu_unmap(domain, iova, size);
+ if (unmapped != size) {
+ seq_printf(s,
+ "Only unmapped %zx instead of %zx\n",
+ unmapped, size);
+ goto next;
+ }
+ getnstimeofday(&tafter);
+ diff = timespec_sub(tafter, tbefore);
+ unmap_elapsed_us += div_s64(timespec_to_ns(&diff),
+ 1000);
}
- getnstimeofday(&tafter);
- diff = timespec_sub(tafter, tbefore);
- unmap_elapsed_us = div_s64(timespec_to_ns(&diff), 1000);
+
+ map_elapsed_us /= ITERS_PER_OP;
+ unmap_elapsed_us /= ITERS_PER_OP;
seq_printf(s, "%8s %12lld us %9lld us\n", _size_to_string(size),
map_elapsed_us, unmap_elapsed_us);