From patchwork Tue Nov 13 13:51:14 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Kuoppala X-Patchwork-Id: 1734201 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork1.kernel.org (Postfix) with ESMTP id 633AE3FC64 for ; Tue, 13 Nov 2012 13:51:41 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 471B29F032 for ; Tue, 13 Nov 2012 05:51:41 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga14.intel.com (mga14.intel.com [143.182.124.37]) by gabe.freedesktop.org (Postfix) with ESMTP id 703379EA09 for ; Tue, 13 Nov 2012 05:51:30 -0800 (PST) Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga102.ch.intel.com with ESMTP; 13 Nov 2012 05:51:29 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.80,767,1344236400"; d="scan'208";a="217096100" Received: from gaia.fi.intel.com (HELO gaia) ([10.237.72.66]) by azsmga001.ch.intel.com with ESMTP; 13 Nov 2012 05:51:16 -0800 Received: by gaia (Postfix, from userid 1000) id B59664269B; Tue, 13 Nov 2012 15:51:15 +0200 (EET) From: Mika Kuoppala To: intel-gfx@lists.freedesktop.org Date: Tue, 13 Nov 2012 15:51:14 +0200 Message-Id: <1352814674-1794-1-git-send-email-mika.kuoppala@intel.com> X-Mailer: git-send-email 1.7.9.5 Subject: [Intel-gfx] [PATCH] tests: add gem_seqno_wrap test X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org This test uses debugfs entry to set next_seqno close to a wrapping point and then creates a load with gem_stress to induce the wrap. Signed-off-by: Mika Kuoppala --- tests/Makefile.am | 1 + tests/gem_seqno_wrap.c | 248 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 249 insertions(+) create mode 100644 tests/gem_seqno_wrap.c diff --git a/tests/Makefile.am b/tests/Makefile.am index 6e6bd7e..cfa0cee 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -44,6 +44,7 @@ TESTS_progs = \ gem_linear_blits \ gem_vmap_blits \ gem_threaded_access_tiled \ + gem_seqno_wrap \ gem_tiled_blits \ gem_tiled_fence_blits \ gem_largeobject \ diff --git a/tests/gem_seqno_wrap.c b/tests/gem_seqno_wrap.c new file mode 100644 index 0000000..b7135ad --- /dev/null +++ b/tests/gem_seqno_wrap.c @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2012 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: + * Mika Kuoppala + */ + +/* + * This test runs gem_stress test multiple times while setting the + * next_seqno close to wrapping point. Driver can only handle INT_MAX-1 + * increments to seqno. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "drmtest.h" +#include "i915_drm.h" +#include "intel_bufmgr.h" + +#define NUM_WRAPS 3 + +static int verbose = 0; + +static int run_gem_stress(int times) +{ + int pid; + int r = -1; + int status = 0; + + pid = fork(); + if (pid == 0) { + char *argv[3]; + char cmd[32]; + char opt1[32]; + char path[PATH_MAX]; + char full_path[PATH_MAX]; + + strncpy(cmd, "gem_stress", sizeof(cmd)); + argv[0] = cmd; + argv[1] = opt1; + argv[2] = NULL; + + assert(snprintf(opt1, sizeof(opt1), "-o%d", times) > 0); + + if (getcwd(path, PATH_MAX) == NULL) + perror("getcwd"); + + assert(snprintf(full_path, PATH_MAX, "%s/%s", path, argv[0]) > 0); + + if (!verbose) { + close(STDOUT_FILENO); + close(STDERR_FILENO); + } + + r = execv(full_path, argv); + if (r == -1) + perror("execv failed"); + } else { + int waitcount = 20; + + while(waitcount-- > 0) { + r = waitpid(pid, &status, WNOHANG); + if (r == pid) { + if(WIFEXITED(status)) { + if (WEXITSTATUS(status)) + fprintf(stderr, "child returned with %d\n", WEXITSTATUS(status)); + return WEXITSTATUS(status); + } + } else if (r != 0) { + perror("waitpid"); + return -errno; + } + + sleep(1); + } + + kill(pid, SIGKILL); + return -ETIMEDOUT; + } + + return r; +} + +static const char *debug_fs_entry = "/sys/kernel/debug/dri/0/i915_next_seqno"; + +static int read_seqno(uint32_t *seqno) +{ + int fh; + char buf[32]; + int r; + char *p; + unsigned long int tmp; + + fh = open(debug_fs_entry, O_RDWR); + if (fh == -1) { + perror("open"); + fprintf(stderr, "no %s found, too old kernel?\n", debug_fs_entry); + return -errno; + } + + r = read(fh, buf, sizeof(buf) - 1); + if (r < 0) { + perror("read"); + close(fh); + return -errno; + } + + close(fh); + buf[r] = 0; + + p = strstr(buf, "0x"); + if (!p) + p = buf; + + tmp = strtoul(p, NULL, 0); + if (tmp == ULONG_MAX) { + perror("strtoul"); + return -errno; + } + + *seqno = tmp; + + return 0; +} + +static int write_seqno(uint32_t seqno) +{ + int fh; + char buf[32]; + int r; + + fh = open(debug_fs_entry, O_RDWR); + if (fh == -1) { + perror("open"); + return -errno; + } + + assert(snprintf(buf, sizeof(buf), "0x%x", seqno) > 0); + + r = write(fh, buf, strnlen(buf, sizeof(buf))); + if (r < 0) + return r; + + assert(r == strnlen(buf, sizeof(buf))); + + close(fh); + + return 0; +} + +static int run_once(void) +{ + int r; + uint32_t seqno = 0; + uint32_t seqno_after = 0; + uint32_t incr; + + r = read_seqno(&seqno); + assert(r == 0); + + incr = (UINT32_MAX >> 1) - 0x1000; + if (seqno + incr < seqno) + seqno = UINT32_MAX - 0x1000; + else + seqno += incr; + + seqno++; + + r = write_seqno(seqno); + if (r < 0) { + fprintf(stderr, "write_seqno returned %d\n", r); + return r; + } + + // XXX we lose drm auth/master if we are too hasty to reopen /dev/dri wtf?! + // usleep(200*1000); + r = run_gem_stress(1); + if (r != 0) { + fprintf(stderr, "run_gem_stress returned %d\n", r); + return -1; + } + + r = read_seqno(&seqno_after); + assert(r == 0); + + if (seqno > seqno_after) + return 1; + + return 0; +} + +int main(int argc, char **argv) +{ + + int wraps = 0; + int wr; + int r; + + if (argc > 1) + wr = atoi(argv[1]); + else + wr = NUM_WRAPS; + + while(wraps < wr) { + r = run_once(); + if (r < 0) { + if (verbose) fprintf(stderr, "run once returned %d\n", r); + return r; + } + + wraps += r; + } + + if (wraps == wr) { + if (verbose) + printf("done %d wraps successfully\n", wraps); + + return 0; + } + + return -1; +}