On Mon, Nov 16, 2015 at 03:22:23PM +0200, Joonas Lahtinen wrote: > Cc: Thomas Wood <thomas.wood@xxxxxxxxx> > Cc: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> > Cc: Damien Lespiau <damien.lespiau@xxxxxxxxx> > Signed-off-by: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx> Given that we have all that in piglit already the commit message is a bit thin on justification. Why do we need this in igt too? How does this interact with the piglit dmesg capture? > --- > lib/igt_core.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++--- > tests/Makefile.sources | 1 + > tests/igt_capture.c | 93 ++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 200 insertions(+), 7 deletions(-) > create mode 100644 tests/igt_capture.c > > diff --git a/lib/igt_core.c b/lib/igt_core.c > index 04a0ab2..e73175a 100644 > --- a/lib/igt_core.c > +++ b/lib/igt_core.c > @@ -211,6 +211,8 @@ > * "--help" command line option. > */ > > +#define IGT_KMSG_CAPTURE_DUMP_BUF_SIZE 4096 > + > static unsigned int exit_handler_count; > const char *igt_interactive_debug; > > @@ -247,6 +249,10 @@ enum { > static int igt_exitcode = IGT_EXIT_SUCCESS; > static const char *command_str; > > +static int igt_kmsg_capture_fd; > +static char* igt_kmsg_capture_dump_buf; > +static pthread_mutex_t kmsg_mutex = PTHREAD_MUTEX_INITIALIZER; > + > static char* igt_log_domain_filter; > static struct { > char *entries[256]; > @@ -312,6 +318,71 @@ static void _igt_log_buffer_dump(void) > pthread_mutex_unlock(&log_buffer_mutex); > } > > +static void _igt_kmsg_capture_reset(void) > +{ > + if (igt_kmsg_capture_fd == -1) > + return; > + > + pthread_mutex_lock(&kmsg_mutex); > + > + lseek(igt_kmsg_capture_fd, 0, SEEK_END); > + > + pthread_mutex_unlock(&kmsg_mutex); > +} > + > +static void _igt_kmsg_capture_dump(void) > +{ > + size_t nbytes; > + int nlines; > + char *p; > + char *p0; > + int c; > + > + if (igt_kmsg_capture_fd == -1 || > + igt_kmsg_capture_dump_buf == NULL) > + return; > + > + pthread_mutex_lock(&kmsg_mutex); > + > + > + nlines = 0; > + do { > + errno = 0; > + nbytes = read(igt_kmsg_capture_fd, > + igt_kmsg_capture_dump_buf, > + IGT_KMSG_CAPTURE_DUMP_BUF_SIZE); > + > + if (nbytes == -1) > + continue; > + > + if (!nlines) > + fprintf(stderr, "**** KMSG ****\n"); > + > + p = p0 = strchr(igt_kmsg_capture_dump_buf, ';') + 1; > + while (p - p0 < nbytes) { > + if (*p != '\\') { > + fputc(*p++, stderr); > + continue; > + } > + sscanf(p, "\\x%x", &c); > + fputc(c, stderr); > + p += 4; > + } > + //fputs(strchr(igt_kmsg_capture_dump_buf, ';') + 1, stderr); > + nlines++; > + } while(errno == 0); > + > + if (nlines) > + fprintf(stderr, "**** END ****\n"); > + else > + fprintf(stderr, "No kmsg.\n"); > + > + if (errno != EAGAIN) > + fprintf(stderr, "Incomplete kmsg.\n"); > + > + pthread_mutex_unlock(&kmsg_mutex); > +} > + > __attribute__((format(printf, 1, 2))) > static void kmsg(const char *format, ...) > #define KERN_EMER "<0>" > @@ -330,11 +401,15 @@ static void kmsg(const char *format, ...) > if (file == NULL) > return; > > + pthread_mutex_lock(&kmsg_mutex); > + > va_start(ap, format); > vfprintf(file, format, ap); > va_end(ap); > > fclose(file); > + > + pthread_mutex_unlock(&kmsg_mutex); > } > > static void gettime(struct timespec *ts) > @@ -527,6 +602,15 @@ static int common_init(int *argc, char **argv, > int ret = 0; > const char *env; > > + igt_kmsg_capture_fd = open("/dev/kmsg", O_RDWR | O_NONBLOCK); > + if (igt_kmsg_capture_fd != -1) { > + igt_kmsg_capture_dump_buf = > + malloc(IGT_KMSG_CAPTURE_DUMP_BUF_SIZE); > + if(igt_kmsg_capture_dump_buf == NULL) > + igt_warn("Unable to allocate memory, " > + "will not dump kmsg.\n"); > + } > + > if (!isatty(STDOUT_FILENO) || getenv("IGT_PLAIN_OUTPUT")) > __igt_plain_output = true; > > @@ -796,6 +880,7 @@ bool __igt_run_subtest(const char *subtest_name) > igt_debug("Starting subtest: %s\n", subtest_name); > > _igt_log_buffer_reset(); > + _igt_kmsg_capture_reset(); > > gettime(&subtest_time); > return (in_subtest = subtest_name); > @@ -972,6 +1057,7 @@ void igt_fail(int exitcode) > exit(exitcode); > > _igt_log_buffer_dump(); > + _igt_kmsg_capture_dump(); > > if (in_subtest) { > if (exitcode == IGT_EXIT_TIMEOUT) > @@ -1072,16 +1158,21 @@ void __igt_fail_assert(const char *domain, const char *file, const int line, > */ > void igt_exit(void) > { > + int status = IGT_EXIT_SUCCESS; > + > igt_exit_called = true; > > if (run_single_subtest && !run_single_subtest_found) { > igt_warn("Unknown subtest: %s\n", run_single_subtest); > - exit(IGT_EXIT_INVALID); > + status = IGT_EXIT_INVALID; > + goto do_exit; > } > > > - if (igt_only_list_subtests()) > - exit(IGT_EXIT_SUCCESS); > + if (igt_only_list_subtests()) { > + status = IGT_EXIT_SUCCESS; > + goto do_exit; > + } > > kmsg(KERN_INFO "%s: exiting, ret=%d\n", command_str, igt_exitcode); > igt_debug("Exiting with status code %d\n", igt_exitcode); > @@ -1111,18 +1202,26 @@ void igt_exit(void) > > > printf("%s (%.3fs)\n", result, elapsed); > - exit(igt_exitcode); > + status = igt_exitcode; > + goto do_exit; > } > > /* Calling this without calling one of the above is a failure */ > assert(skipped_one || succeeded_one || failed_one); > > if (failed_one) > - exit(igt_exitcode); > + status = igt_exitcode; > else if (succeeded_one) > - exit(IGT_EXIT_SUCCESS); > + status = IGT_EXIT_SUCCESS; > else > - exit(IGT_EXIT_SKIP); > + status = IGT_EXIT_SKIP; > +do_exit: > + if (igt_kmsg_capture_fd != -1) > + close(igt_kmsg_capture_fd); > + if (igt_kmsg_capture_dump_buf != NULL) > + free(igt_kmsg_capture_dump_buf); > + > + exit(status); > } > > /* fork support code */ > diff --git a/tests/Makefile.sources b/tests/Makefile.sources > index 8fb2de8..25f0c4a 100644 > --- a/tests/Makefile.sources > +++ b/tests/Makefile.sources > @@ -62,6 +62,7 @@ TESTS_progs_M = \ > gem_tiled_partial_pwrite_pread \ > gem_userptr_blits \ > gem_write_read_ring_switch \ > + igt_capture \ > kms_addfb_basic \ > kms_atomic \ > kms_cursor_crc \ > diff --git a/tests/igt_capture.c b/tests/igt_capture.c > new file mode 100644 > index 0000000..fd008d0 > --- /dev/null > +++ b/tests/igt_capture.c > @@ -0,0 +1,93 @@ > +/* > + * Copyright © 2015 Intel Corporation > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice (including the next > + * paragraph) shall be included in all copies or substantial portions of the > + * Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS > + * IN THE SOFTWARE. > + * > + * Authors: > + * Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx> > + * > + */ > + > +#include "igt.h" > +#include <unistd.h> > +#include <stdlib.h> > +#include <stdio.h> > +#include <string.h> > +#include <fcntl.h> > +#include <inttypes.h> > +#include <errno.h> > +#include <sys/stat.h> > +#include <sys/ioctl.h> > + > +static FILE* kmsg; > + > +static void > +test_kmsg(void) > +{ > + fputs("TEST (KMSG)\n", kmsg); > + fflush(kmsg); > + igt_fail(IGT_EXIT_FAILURE); > +} > + > +static void > +test_warn(void) > +{ > + igt_warn("TEST (WARN)\n"); > + igt_fail(IGT_EXIT_FAILURE); > +} > + > +static void > +test_debug(void) > +{ > + igt_debug("TEST (DEBUG)\n"); > + igt_fail(IGT_EXIT_FAILURE); > +} > + > +static void > +test_combined(void) > +{ > + igt_warn("TEST #1 (WARN)\n"); > + fputs("TEST #1\n", kmsg); > + igt_warn("TEST #2 (WARN)\n"); > + fputs("TEST #2\n", kmsg); > + fflush(kmsg); > + igt_fail(IGT_EXIT_FAILURE); > +} > + > +igt_main > +{ > + igt_fixture { > + kmsg = fopen("/dev/kmsg", "w"); > + igt_require(kmsg != NULL); > + } > + > + igt_subtest("kmsg") > + test_kmsg(); > + igt_subtest("warn") > + test_warn(); > + igt_subtest("debug") > + test_debug(); > + igt_subtest("combined") > + test_combined(); > + > + igt_fixture { > + fclose(kmsg); > + } > +} > -- > 2.4.3 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx