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>
Signed-off-by: Patrick Daly <pdaly@codeaurora.org>
diff --git a/drivers/iommu/iommu-debug.c b/drivers/iommu/iommu-debug.c
index 2e2ea1a..75c0c92 100644
--- a/drivers/iommu/iommu-debug.c
+++ b/drivers/iommu/iommu-debug.c
@@ -455,6 +455,8 @@
 	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)
 {
@@ -496,33 +498,42 @@
 		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;
+		int 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);
+		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(&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);
@@ -533,10 +544,11 @@
 	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)) {
@@ -545,26 +557,33 @@
 			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);
+		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(&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);