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@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx