[PATCH 2/3] igt/gem_pread: Support to verify pread/pwrite for non-shmem backed obj

ankitprasad.r.sharma
2015-07-22T14:02:42Z

This patch adds support to verify pread/pwrite for non-shmem backed
objects. It also shows the pread/pwrite speed.
It also tests speeds for pread with and without user side page faults

v2: Fixed Rebase conflicts (Ankit)

v3: Precalculating values to avoid redundant function calls (Dave)
Replaced igt_subtest by igt_subtest_f, added asserts for mmap, corrected
indentation (Tvrtko)

Signed-off-by: Ankitprasad Sharma <ankitprasad.r.sharma at intel.com>
---
tests/gem_pread.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++---
tests/gem_pwrite.c | 54 ++++++++++++++++++++++++---
2 files changed, 149 insertions(+), 11 deletions(-)

diff --git a/tests/gem_pread.c b/tests/gem_pread.c
index cc83948..21fccd0 100644
--- a/tests/gem_pread.c
+++ b/tests/gem_pread.c
@@ -41,6 +41,10 @@
#include "drmtest.h"

#define OBJECT_SIZE 16384
+#define LARGE_OBJECT_SIZE 1024 * 1024
+#define KGRN "\x1B[32m"
+#define KRED "\x1B[31m"
+#define KNRM "\x1B[0m"

static void do_gem_read(int fd, uint32_t handle, void *buf, int len, int loops)
{
@@ -76,12 +80,16 @@ static const char *bytes_per_sec(char *buf, double v)

uint32_t *src, dst;
+uint32_t *dst_user, src_stolen, large_stolen;
+uint32_t *stolen_pf_user, *stolen_nopf_user;
int fd, count;

int main(int argc, char **argv)
{
int object_size = 0;
+ double usecs;
uint32_t buf[20];
+ char* bps;
const struct {
int level;
const char *name;
@@ -106,6 +114,8 @@ int main(int argc, char **argv)

dst = gem_create(fd, object_size);
src = malloc(object_size);
+ src_stolen = gem_create_stolen(fd, object_size);
+ dst_user = malloc(object_size);
}

igt_subtest("normal") {
@@ -115,10 +125,10 @@ int main(int argc, char **argv)
gettimeofday(&start, NULL);
do_gem_read(fd, dst, src, object_size, count);
gettimeofday(&end, NULL);
+ usecs = elapsed(&start, &end, count);
+ bps = bytes_per_sec((char *)buf, object_size/usecs*1e6);
igt_info("Time to pread %d bytes x %6d: %7.3fµs, %s\n",
- object_size, count,
- elapsed(&start, &end, count),
- bytes_per_sec((char *)buf, object_size/elapsed(&start, &end, count)*1e6));
+ object_size, count, usecs, bps);
fflush(stdout);
}
}
@@ -133,18 +143,102 @@ int main(int argc, char **argv)
gettimeofday(&start, NULL);
do_gem_read(fd, dst, src, object_size, count);
gettimeofday(&end, NULL);
+ usecs = elapsed(&start, &end, count);
+ bps = bytes_per_sec((char *)buf, object_size/usecs*1e6);
igt_info("Time to %s pread %d bytes x %6d: %7.3fµs, %s\n",
- c->name, object_size, count,
- elapsed(&start, &end, count),
- bytes_per_sec((char *)buf, object_size/elapsed(&start, &end, count)*1e6));
+ c->name, object_size, count, usecs, bps);
fflush(stdout);
}
}
}

+ igt_subtest("stolen-normal") {
+ for (count = 1; count <= 1<<17; count <<= 1) {
+ struct timeval start, end;
+
+ gettimeofday(&start, NULL);
+ do_gem_read(fd, src_stolen, dst_user, object_size, count);
+ gettimeofday(&end, NULL);
+ usecs = elapsed(&start, &end, count);
+ bps = bytes_per_sec((char *)buf, object_size/usecs*1e6);
+ igt_info("Time to pread %d bytes x %6d: %7.3fµs, %s\n",
+ object_size, count, usecs, bps);
+ fflush(stdout);
+ }
+ }
+ for (c = cache; c->level != -1; c++) {
+ igt_subtest_f("stolen-%s", c->name) {
+ gem_set_caching(fd, src_stolen, c->level);
+
+ for (count = 1; count <= 1<<17; count <<= 1) {
+ struct timeval start, end;
+
+ gettimeofday(&start, NULL);
+ do_gem_read(fd, src_stolen, dst_user,
+ object_size, count);
+ gettimeofday(&end, NULL);
+ usecs = elapsed(&start, &end, count);
+ bps = bytes_per_sec((char *)buf, object_size/usecs*1e6);
+ igt_info("Time to stolen-%s pread %d bytes x %6d: %7.3fµs, %s\n",
+ c->name, object_size, count, usecs, bps);
+ fflush(stdout);
+ }
+ }
+ }
+
+ /* List the time taken in pread operation for stolen objects, with
+ * and without the overhead of page fault handling on accessing the
+ * user space buffer
+ */
+ igt_subtest("pagefault-pread") {
+ large_stolen = gem_create_stolen(fd, LARGE_OBJECT_SIZE);
+ stolen_nopf_user = (uint32_t *) mmap(NULL, LARGE_OBJECT_SIZE,
+ PROT_WRITE,
+ MAP_ANONYMOUS|MAP_PRIVATE,
+ -1, 0);
+ igt_assert(stolen_nopf_user);
+
+ for (count = 1; count <= 10; count ++) {
+ struct timeval start, end;
+ double t_elapsed = 0;
+
+ gettimeofday(&start, NULL);
+ do_gem_read(fd, large_stolen, stolen_nopf_user,
+ LARGE_OBJECT_SIZE, 1);
+ gettimeofday(&end, NULL);
+ t_elapsed = elapsed(&start, &end, 1);
+ bps = bytes_per_sec((char *)buf, object_size/t_elapsed*1e6);
+ igt_info("Pagefault-N - Time to pread %d bytes: %7.3fµs, %s\n",
+ LARGE_OBJECT_SIZE, t_elapsed, bps);
+
+ stolen_pf_user = (uint32_t *) mmap(NULL, LARGE_OBJECT_SIZE,
+ PROT_WRITE,
+ MAP_ANONYMOUS|MAP_PRIVATE,
+ -1, 0);
+ igt_assert(stolen_pf_user);
+
+ gettimeofday(&start, NULL);
+ do_gem_read(fd, large_stolen, stolen_pf_user,
+ LARGE_OBJECT_SIZE, 1);
+ gettimeofday(&end, NULL);
+ usecs = elapsed(&start, &end, count);
+ bps = bytes_per_sec((char *)buf, object_size/usecs*1e6);
+ igt_info("Pagefault-Y - Time to pread %d bytes: %7.3fµs, %s%s%s\n",
+ LARGE_OBJECT_SIZE, usecs,
+ t_elapsed < usecs ? KGRN : KRED, bps, KNRM);
+ fflush(stdout);
+ munmap(stolen_pf_user, LARGE_OBJECT_SIZE);
+ }
+ munmap(stolen_nopf_user, LARGE_OBJECT_SIZE);
+ gem_close(fd, large_stolen);
+ }
+
+
igt_fixture {
free(src);
gem_close(fd, dst);
+ free(dst_user);
+ gem_close(fd, src_stolen);

close(fd);
}
diff --git a/tests/gem_pwrite.c b/tests/gem_pwrite.c
index 5b6a77f..892c531 100644
--- a/tests/gem_pwrite.c
+++ b/tests/gem_pwrite.c
@@ -135,11 +135,14 @@ static void test_big_gtt(int fd, int scale)
}

uint32_t *src, dst;
+uint32_t *src_user, dst_stolen;
int fd;

int main(int argc, char **argv)
{
int object_size = 0;
+ double usecs;
+ char* bps;
uint32_t buf[20];
int count;
const struct {
@@ -150,6 +153,9 @@ int main(int argc, char **argv)
{ 1, "snoop" },
{ 2, "display" },
{ -1 },
+ { -1, "stolen-uncached"},
+ { -1, "stolen-snoop"},
+ { -1, "stolen-display"},
}, *c;

igt_skip_on_simulation();
@@ -167,6 +173,8 @@ int main(int argc, char **argv)

dst = gem_create(fd, object_size);
src = malloc(object_size);
+ dst_stolen = gem_create_stolen(fd, object_size);
+ src_user = malloc(object_size);
}

igt_subtest("normal") {
@@ -176,10 +184,10 @@ int main(int argc, char **argv)
gettimeofday(&start, NULL);
do_gem_write(fd, dst, src, object_size, count);
gettimeofday(&end, NULL);
+ usecs = elapsed(&start, &end, count);
+ bps = bytes_per_sec((char *)buf, object_size/usecs*1e6);
igt_info("Time to pwrite %d bytes x %6d: %7.3fµs, %s\n",
- object_size, count,
- elapsed(&start, &end, count),
- bytes_per_sec((char *)buf, object_size/elapsed(&start, &end, count)*1e6));
+ object_size, count, usecs, bps);
fflush(stdout);
}
}
@@ -194,10 +202,44 @@ int main(int argc, char **argv)
gettimeofday(&start, NULL);
do_gem_write(fd, dst, src, object_size, count);
gettimeofday(&end, NULL);
+ usecs = elapsed(&start, &end, count);
+ bps = bytes_per_sec((char *)buf, object_size/usecs*1e6);
igt_info("Time to %s pwrite %d bytes x %6d: %7.3fµs, %s\n",
+ c->name, object_size, count, usecs, bps);
+ fflush(stdout);
+ }
+ }
+ }
+
+ igt_subtest("stolen-normal") {
+ for (count = 1; count <= 1<<17; count <<= 1) {
+ struct timeval start, end;
+
+ gettimeofday(&start, NULL);
+ do_gem_write(fd, dst_stolen, src_user,
+ object_size, count);
+ gettimeofday(&end, NULL);
+ usecs = elapsed(&start, &end, count);
+ bps = bytes_per_sec((char *)buf, object_size/usecs*1e6);
+ igt_info("Time to pwrite %d bytes x %6d: %7.3fµs, %s\n",
+ object_size, count, usecs, bps);
+ fflush(stdout);
+ }
+ }
+
+ for (c = cache; c->level != -1; c++) {
+ igt_subtest((c + 4)->name) {
+ gem_set_caching(fd, dst, c->level);
+ for (count = 1; count <= 1<<17; count <<= 1) {
+ struct timeval start, end;
+
+ gettimeofday(&start, NULL);
+ do_gem_write(fd, dst_stolen, src_user,
+ object_size, count);
+ gettimeofday(&end, NULL);
+ igt_info("Time to stolen-%s pwrite %d bytes x %6d: %7.3fµs, %s\n",
c->name, object_size, count,
- elapsed(&start, &end, count),
- bytes_per_sec((char *)buf, object_size/elapsed(&start, &end, count)*1e6));
+ usecs, bps);
fflush(stdout);
}
}
@@ -206,6 +248,8 @@ int main(int argc, char **argv)
igt_fixture {
free(src);
gem_close(fd, dst);
+ free(src_user);
+ gem_close(fd, dst_stolen);
}

igt_subtest("big-cpu")