All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Wilson <chris@chris-wilson.co.uk>
To: intel-gfx@lists.freedesktop.org
Subject: [i-g-t RFC 2/3] lib: Capture kcov around ioctls
Date: Wed,  8 Jun 2016 09:52:04 +0100	[thread overview]
Message-ID: <1465375925-8244-2-git-send-email-chris@chris-wilson.co.uk> (raw)
In-Reply-To: <1465375925-8244-1-git-send-email-chris@chris-wilson.co.uk>

Use our ioctl overload to enable kcov capture around every ioctl.
---
 lib/igt_aux.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 lib/igt_aux.h |  5 ++++
 2 files changed, 84 insertions(+), 5 deletions(-)

diff --git a/lib/igt_aux.c b/lib/igt_aux.c
index fb1dac2..71067b3 100644
--- a/lib/igt_aux.c
+++ b/lib/igt_aux.c
@@ -60,6 +60,7 @@
 #include "config.h"
 #include "intel_reg.h"
 #include "ioctl_wrappers.h"
+#include "igt_kcov.h"
 #include "igt_kms.h"
 #include "igt_pm.h"
 #include "igt_stats.h"
@@ -74,6 +75,77 @@
  * fit into any other topic.
  */
 
+static struct __igt_kcov_ioctl_global {
+	struct igt_kcov kcov;
+	void (*trace)(struct igt_kcov *, void *data);
+	void *data;
+	bool enable;
+} __igt_kcov_ioctl;
+
+static int
+__kcov_ioctl(int fd, unsigned long request, void *arg)
+{
+	int ret;
+
+	if (__igt_kcov_ioctl.enable)
+		igt_kcov_enable(&__igt_kcov_ioctl.kcov);
+
+	ret = ioctl(fd, request, arg);
+
+	if (__igt_kcov_ioctl.enable) {
+		int err = errno;
+
+		igt_kcov_disable(&__igt_kcov_ioctl.kcov);
+		__igt_kcov_ioctl.trace(&__igt_kcov_ioctl.kcov,
+				       __igt_kcov_ioctl.data);
+		igt_kcov_reset(&__igt_kcov_ioctl.kcov);
+		errno = err;
+	}
+
+	return ret;
+}
+
+static int
+kcov_ioctl(int fd, unsigned long request, void *arg)
+{
+	int ret;
+	do {
+		ret = __kcov_ioctl(fd, request, arg);
+	} while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+	return ret;
+}
+
+void igt_kcov_setup(void (*trace)(struct igt_kcov *, void *),
+		    void *data)
+{
+	if (!trace) {
+		igt_kcov_fini(&__igt_kcov_ioctl.kcov);
+		memset(&__igt_kcov_ioctl, 0, sizeof(__igt_kcov_ioctl));
+		return;
+	}
+
+	if (igt_kcov_init(&__igt_kcov_ioctl.kcov))
+		return;
+
+	__igt_kcov_ioctl.trace = trace;
+	__igt_kcov_ioctl.data = data;
+}
+
+void igt_kcov_start(void)
+{
+	if (__igt_kcov_ioctl.trace) {
+		__igt_kcov_ioctl.enable = true;
+		igt_ioctl = kcov_ioctl;
+	} else
+		igt_ioctl = drmIoctl;
+}
+
+void igt_kcov_stop(void)
+{
+	__igt_kcov_ioctl.enable = false;
+	igt_ioctl = drmIoctl;
+}
+
 
 /* signal interrupt helpers */
 
@@ -86,6 +158,7 @@
 #define sigev_notify_thread_id _sigev_un._tid
 
 static struct __igt_sigiter_global {
+	int (*old_ioctl)(int fd, unsigned long request, void *arg);
 	pid_t tid;
 	timer_t timer;
 	struct timespec offset;
@@ -118,8 +191,8 @@ sig_ioctl(int fd, unsigned long request, void *arg)
 	memset(&its, 0, sizeof(its));
 	if (timer_settime(__igt_sigiter.timer, 0, &its, NULL)) {
 		/* oops, we didn't undo the interrupter (i.e. !unwound abort) */
-		igt_ioctl = drmIoctl;
-		return drmIoctl(fd, request, arg);
+		igt_ioctl = __igt_sigiter.old_ioctl;
+		return igt_ioctl(fd, request, arg);
 	}
 
 	its.it_value = __igt_sigiter.offset;
@@ -131,7 +204,7 @@ sig_ioctl(int fd, unsigned long request, void *arg)
 		ret = 0;
 		serial = __igt_sigiter.stat.signals;
 		igt_assert(timer_settime(__igt_sigiter.timer, 0, &its, NULL) == 0);
-		if (ioctl(fd, request, arg))
+		if (__kcov_ioctl(fd, request, arg))
 			ret = errno;
 		if (__igt_sigiter.stat.signals == serial)
 			__igt_sigiter.stat.miss++;
@@ -166,7 +239,7 @@ static bool igt_sigiter_start(struct __igt_sigiter *iter, bool enable)
 	 * tests, we cannot assume the state of the igt_ioctl indirection.
 	 */
 	SIG_ASSERT(igt_ioctl == drmIoctl);
-	igt_ioctl = drmIoctl;
+	igt_ioctl = __igt_sigiter.old_ioctl;
 
 	if (enable) {
 		struct timespec start, end;
@@ -174,6 +247,7 @@ static bool igt_sigiter_start(struct __igt_sigiter *iter, bool enable)
 		struct sigaction act;
 		struct itimerspec its;
 
+		__igt_sigiter.old_ioctl = igt_ioctl;
 		igt_ioctl = sig_ioctl;
 		__igt_sigiter.tid = gettid();
 
@@ -226,7 +300,7 @@ static bool igt_sigiter_stop(struct __igt_sigiter *iter, bool enable)
 
 		SIG_ASSERT(igt_ioctl == sig_ioctl);
 		SIG_ASSERT(__igt_sigiter.tid == gettid());
-		igt_ioctl = drmIoctl;
+		igt_ioctl = __igt_sigiter.old_ioctl;
 
 		timer_delete(__igt_sigiter.timer);
 
diff --git a/lib/igt_aux.h b/lib/igt_aux.h
index be0d2d6..3bfe3af 100644
--- a/lib/igt_aux.h
+++ b/lib/igt_aux.h
@@ -43,6 +43,11 @@ void igt_stop_signal_helper(void);
 void igt_fork_hang_detector(int fd);
 void igt_stop_hang_detector(void);
 
+struct igt_kcov;
+void igt_kcov_setup(void (*trace)(struct igt_kcov *, void *), void *data);
+void igt_kcov_start(void);
+void igt_kcov_stop(void);
+
 struct __igt_sigiter {
 	unsigned pass;
 };
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2016-06-08  8:52 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-08  8:52 [i-g-t RFC 1/3] lib: Wrap kcov Chris Wilson
2016-06-08  8:52 ` Chris Wilson [this message]
2016-06-08  8:52 ` [i-g-t RFC 3/3] Preliminary fuzzing/test minimisation Chris Wilson

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=1465375925-8244-2-git-send-email-chris@chris-wilson.co.uk \
    --to=chris@chris-wilson.co.uk \
    --cc=intel-gfx@lists.freedesktop.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.