[Intel-gfx] [PATCH igt] lib/igt_aux: Framework for measuring latency in raising signals

Chris Wilson chris at chris-wilson.co.uk
Fri Mar 18 19:16:37 UTC 2016


Not sure how best to put this to use yet, we need a set of benchmarks to
track changes as well as a few hard fail criteria. But at least this is a
start towards measuring how long we block signals whilst in the driver.

Any ideas on how to stop the -lrt prolifieration?
-Chris

---
 benchmarks/Makefile.am   |   2 +-
 debugger/Makefile.am     |   2 +-
 demos/Makefile.am        |   2 +-
 lib/Makefile.am          |   2 +-
 lib/igt_aux.c            | 102 +++++++++++++++++++++++++++++++++++++++++++++++
 lib/igt_aux.h            |   3 ++
 lib/tests/Makefile.am    |   2 +-
 tests/Makefile.am        |   2 +-
 tests/gem_exec_whisper.c |   6 +++
 tools/Makefile.am        |   2 +-
 10 files changed, 118 insertions(+), 7 deletions(-)

diff --git a/benchmarks/Makefile.am b/benchmarks/Makefile.am
index a555ab6..dd00e5a 100644
--- a/benchmarks/Makefile.am
+++ b/benchmarks/Makefile.am
@@ -3,7 +3,7 @@ include Makefile.sources
 
 AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib
 AM_CFLAGS = $(DRM_CFLAGS) $(CWARNFLAGS) $(CAIRO_CFLAGS) $(LIBUNWIND_CFLAGS)
-LDADD = $(top_builddir)/lib/libintel_tools.la $(DRM_LIBS) $(PCIACCESS_LIBS) $(CAIRO_LIBS) $(LIBUNWIND_LIBS) -lm
+LDADD = $(top_builddir)/lib/libintel_tools.la $(DRM_LIBS) $(PCIACCESS_LIBS) $(CAIRO_LIBS) $(LIBUNWIND_LIBS) -lrt -lm
 
 benchmarks_LTLIBRARIES = gem_exec_tracer.la
 gem_exec_tracer_la_LDFLAGS = -module -avoid-version -no-undefined
diff --git a/debugger/Makefile.am b/debugger/Makefile.am
index 0b6028b..1c4fadc 100644
--- a/debugger/Makefile.am
+++ b/debugger/Makefile.am
@@ -15,4 +15,4 @@ AM_CFLAGS = 			\
 	$(LIBUNWIND_CFLAGS)	\
 	$(CWARNFLAGS)
 
-LDADD = $(top_builddir)/lib/libintel_tools.la $(DRM_LIBS) $(PCIACCESS_LIBS) $(CAIRO_LIBS) $(LIBUNWIND_LIBS)
+LDADD = $(top_builddir)/lib/libintel_tools.la $(DRM_LIBS) $(PCIACCESS_LIBS) $(CAIRO_LIBS) $(LIBUNWIND_LIBS) -lrt
diff --git a/demos/Makefile.am b/demos/Makefile.am
index 029581a..4da1e2a 100644
--- a/demos/Makefile.am
+++ b/demos/Makefile.am
@@ -4,4 +4,4 @@ bin_PROGRAMS = 				\
 
 AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib
 AM_CFLAGS = $(DRM_CFLAGS) $(PCIACCESS_CFLAGS) $(CWARNFLAGS) $(CAIRO_CFLAGS) $(LIBUNWIND_CFLAGS)
-LDADD = $(top_builddir)/lib/libintel_tools.la $(DRM_LIBS) $(PCIACCESS_LIBS) $(CAIRO_LIBS) $(LIBUNWIND_LIBS)
+LDADD = $(top_builddir)/lib/libintel_tools.la $(DRM_LIBS) $(PCIACCESS_LIBS) $(CAIRO_LIBS) $(LIBUNWIND_LIBS) -lrt
diff --git a/lib/Makefile.am b/lib/Makefile.am
index e3a456b..88b2507 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -21,6 +21,6 @@ AM_CFLAGS = $(DRM_CFLAGS) $(CWARNFLAGS) $(LIBUNWIND_CFLAGS) $(DEBUG_CFLAGS) \
 	    -DIGT_LOG_DOMAIN=\""$(subst _,-,$*)"\" \
 	    -pthread
 
-LDADD = $(CAIRO_LIBS) $(LIBUNWIND_LIBS) -lm
+LDADD = $(CAIRO_LIBS) $(LIBUNWIND_LIBS) -lrt -lm
 AM_CFLAGS += $(CAIRO_CFLAGS)
 
diff --git a/lib/igt_aux.c b/lib/igt_aux.c
index f38ecd8..0e794df 100644
--- a/lib/igt_aux.c
+++ b/lib/igt_aux.c
@@ -41,6 +41,7 @@
 #include <pciaccess.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <time.h>
 #include <sys/wait.h>
 #include <sys/time.h>
 #include <sys/types.h>
@@ -60,6 +61,7 @@
 #include "ioctl_wrappers.h"
 #include "igt_kms.h"
 #include "igt_pm.h"
+#include "igt_stats.h"
 
 /**
  * SECTION:igt_aux
@@ -882,3 +884,103 @@ void igt_set_module_param_int(const char *name, int val)
 
 	igt_set_module_param(name, str);
 }
+
+static struct igt_siglatency {
+	timer_t timer;
+	struct timespec target;
+	struct sigaction oldact;
+	struct igt_mean mean;
+
+	int sig;
+} igt_siglatency;
+
+static uint32_t
+__hars_petruska_f54_1_random (void)
+{
+	static uint32_t state = 0x12345678;
+
+#define rol(x,k) ((x << k) | (x >> (32-k)))
+	return state = (state ^ rol (state, 5) ^ rol (state, 24)) + 0x37798849;
+#undef rol
+}
+
+#define MSEC_PER_SEC (1000)
+#define USEC_PER_SEC (1000*MSEC_PER_SEC)
+#define NSEC_PER_SEC (1000*USEC_PER_SEC)
+static long delay(void)
+{
+	return __hars_petruska_f54_1_random() % (NSEC_PER_SEC / 1000);
+}
+
+static double elapsed(const struct timespec *now, const struct timespec *last)
+{
+	double nsecs;
+
+	nsecs = now->tv_nsec - last ->tv_nsec;
+	nsecs += 1e9*(now->tv_sec - last->tv_sec);
+
+	return nsecs;
+}
+
+static void siglatency(int sig, siginfo_t *info, void *arg)
+{
+	struct itimerspec its;
+
+	clock_gettime(CLOCK_MONOTONIC, &its.it_value);
+	if (info)
+		igt_mean_add(&igt_siglatency.mean,
+			     elapsed(&its.it_value, &igt_siglatency.target));
+	igt_siglatency.target = its.it_value;
+
+	its.it_value.tv_nsec += 100 * 1000;
+	its.it_value.tv_nsec += delay();
+	if (its.it_value.tv_nsec >= NSEC_PER_SEC) {
+		its.it_value.tv_nsec -= NSEC_PER_SEC;
+		its.it_value.tv_sec += 1;
+	}
+	its.it_interval.tv_sec = its.it_interval.tv_nsec = 0;
+	timer_settime(igt_siglatency.timer, TIMER_ABSTIME, &its, NULL);
+}
+
+#define gettid() syscall(__NR_gettid)
+#define sigev_notify_thread_id _sigev_un._tid
+
+void igt_start_siglatency(int sig)
+{
+	struct sigevent sev;
+	struct sigaction act;
+
+	if (sig <= 0)
+		sig = SIGRTMIN;
+
+	if (igt_siglatency.sig)
+		(void)igt_stop_siglatency(NULL);
+	igt_assert(igt_siglatency.sig == 0);
+	igt_siglatency.sig = sig;
+
+	memset(&sev, 0, sizeof(sev));
+	sev.sigev_notify = SIGEV_SIGNAL | SIGEV_THREAD_ID;
+	sev.sigev_notify_thread_id = gettid();
+	sev.sigev_signo = sig;
+	timer_create(CLOCK_MONOTONIC, &sev, &igt_siglatency.timer);
+
+	memset(&act, 0, sizeof(act));
+	act.sa_sigaction = siglatency;
+	sigaction(sig, &act, &igt_siglatency.oldact);
+
+	siglatency(sig, NULL, NULL);
+}
+
+double igt_stop_siglatency(struct igt_mean *result)
+{
+	double mean = igt_mean_get(&igt_siglatency.mean);
+
+	if (result)
+		*result = igt_siglatency.mean;
+
+	sigaction(igt_siglatency.sig, &igt_siglatency.oldact, NULL);
+	timer_delete(igt_siglatency.timer);
+	memset(&igt_siglatency, 0, sizeof(igt_siglatency));
+
+	return mean;
+}
diff --git a/lib/igt_aux.h b/lib/igt_aux.h
index 427719e..083018c 100644
--- a/lib/igt_aux.h
+++ b/lib/igt_aux.h
@@ -154,6 +154,9 @@ void igt_unlock_mem(void);
 	ret_;								\
 })
 
+struct igt_mean;
+void igt_start_siglatency(int sig); /* 0 => SIGRTMIN (default) */
+double igt_stop_siglatency(struct igt_mean *result);
 
 void igt_set_module_param(const char *name, const char *val);
 void igt_set_module_param_int(const char *name, int val);
diff --git a/lib/tests/Makefile.am b/lib/tests/Makefile.am
index f09d2fe..d7eaf69 100644
--- a/lib/tests/Makefile.am
+++ b/lib/tests/Makefile.am
@@ -15,5 +15,5 @@ AM_CFLAGS = $(DRM_CFLAGS) $(CWARNFLAGS) $(DEBUG_CFLAGS) \
 
 LDADD = ../libintel_tools.la $(PCIACCESS_LIBS) $(DRM_LIBS) $(LIBUNWIND_LIBS)
 
-LDADD += $(CAIRO_LIBS) $(LIBUDEV_LIBS) $(GLIB_LIBS) -lm
+LDADD += $(CAIRO_LIBS) $(LIBUDEV_LIBS) $(GLIB_LIBS) -lrt -lm
 AM_CFLAGS += $(CAIRO_CFLAGS) $(LIBUDEV_CFLAGS) $(GLIB_CFLAGS)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index aabee2b..b973d98 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -58,7 +58,7 @@ AM_CFLAGS = $(DRM_CFLAGS) $(CWARNFLAGS) $(DEBUG_CFLAGS)\
 
 LDADD = ../lib/libintel_tools.la $(PCIACCESS_LIBS) $(DRM_LIBS) $(LIBUNWIND_LIBS)
 
-LDADD += $(CAIRO_LIBS) $(LIBUDEV_LIBS) $(GLIB_LIBS) -lm
+LDADD += $(CAIRO_LIBS) $(LIBUDEV_LIBS) $(GLIB_LIBS) -lrt -lm
 AM_CFLAGS += $(CAIRO_CFLAGS) $(LIBUDEV_CFLAGS) $(GLIB_CFLAGS)
 AM_LDFLAGS = -Wl,--as-needed
 
diff --git a/tests/gem_exec_whisper.c b/tests/gem_exec_whisper.c
index 30f2608..b63603d 100644
--- a/tests/gem_exec_whisper.c
+++ b/tests/gem_exec_whisper.c
@@ -125,6 +125,7 @@ static void whisper(int fd, unsigned engine, unsigned flags)
 	int i, n, pass, loc;
 	unsigned int reloc_migrations = 0;
 	unsigned int eb_migrations = 0;
+	double latency;
 
 	nengine = 0;
 	if (engine == -1) {
@@ -214,6 +215,8 @@ static void whisper(int fd, unsigned engine, unsigned flags)
 		gem_write(fd, batches[n].handle, 0, batch, sizeof(batch));
 	}
 
+	igt_start_siglatency(0);
+
 	for (pass = 0; pass < 1024; pass++) {
 		uint64_t offset;
 
@@ -323,6 +326,9 @@ static void whisper(int fd, unsigned engine, unsigned flags)
 	gem_close(fd, scratch.handle);
 	gem_close(fd, store.handle);
 
+	latency = igt_stop_siglatency(NULL);
+	igt_info("Average signal latency: %.3fus\n", latency / 1000);
+
 	if (flags & FDS) {
 		for (n = 0; n < 64; n++)
 			close(fds[n]);
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 90a8ec1..20cb1ae 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -4,7 +4,7 @@ SUBDIRS = null_state_gen registers
 
 AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib
 AM_CFLAGS = $(DEBUG_CFLAGS) $(DRM_CFLAGS) $(PCIACCESS_CFLAGS) $(CWARNFLAGS) $(CAIRO_CFLAGS) $(LIBUNWIND_CFLAGS) -DPKGDATADIR=\"$(pkgdatadir)\"
-LDADD = $(top_builddir)/lib/libintel_tools.la $(DRM_LIBS) $(PCIACCESS_LIBS) $(CAIRO_LIBS) $(LIBUDEV_LIBS) $(LIBUNWIND_LIBS) -lm
+LDADD = $(top_builddir)/lib/libintel_tools.la $(DRM_LIBS) $(PCIACCESS_LIBS) $(CAIRO_LIBS) $(LIBUDEV_LIBS) $(LIBUNWIND_LIBS) -lrt -lm
 AM_LDFLAGS = -Wl,--as-needed
 
 
-- 
2.8.0.rc3



More information about the Intel-gfx mailing list