ntel-gpu-tools/tests/drv_hangman.c
Chris Wilson 405b3478d1 igt/drv_hangman: Tidy up assertion failure message
Because

(drv_hangman:6035) CRITICAL: Failed assertion: !((__extension__
(__builtin_constant_p (l) && ((__builtin_constant_p (tmp) && strlen
(tmp) < ((size_t) (l))) || (__builtin_constant_p (s) && strlen (s) <
((size_t) (l)))) ? __extension__ ({ size_t __s1_len, __s2_len;
(__builtin_constant_p (tmp) && __builtin_constant_p (s) && (__s1_len =
strlen (tmp), __s2_len = strlen (s), (!((size_t)(const void *)((tmp) +
1) - (size_t)(const void *)(tmp) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)((s) + 1) - (size_t)(const void *)(s) == 1) ||
__s2_len >= 4)) ? __builtin_strcmp (tmp, s) : (__builtin_constant_p
(tmp) && ((size_t)(const void *)((tmp) + 1) - (size_t)(const void
*)(tmp) == 1) && (__s1_len = strlen (tmp), __s1_len < 4) ?
(__builtin_constant_p (s) && ((size_t)(const void *)((s) + 1) -
(size_t)(const void *)(s) == 1) ? __builtin_strcmp (tmp, s) :
(__extension__ ({ const unsigned char *__s2 = (const unsigned char *)
(const char *) (s); int __result = (((const unsigned char *) (const char
*) (tmp))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result =
(((const unsigned char *) (const char *) (tmp))[1] - __s2[1]); if
(__s1_len > 1 && __result == 0) { __result = (((const unsigned char *)
(const char *) (tmp))[2] - __s2[2]); if (__s1_len > 2 && __result == 0)
__result = (((const unsigned char *) (const char *) (tmp))[3] -
__s2[3]); } } __result; }))) : (__builtin_constant_p (s) &&
((size_t)(const void *)((s) + 1) - (size_t)(const void *)(s) == 1) &&
(__s2_len = strlen (s), __s2_len < 4) ? (__builtin_constant_p (tmp) &&
((size_t)(const void *)((tmp) + 1) - (size_t)(const void *)(tmp) == 1) ?
__builtin_strcmp (tmp, s) : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (tmp); int __result =
(((const unsigned char *) (const char *) (s))[0] - __s2[0]); if
(__s2_len > 0 && __result == 0) { __result = (((const unsigned char *)
(const char *) (s))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) {
__result = (((const unsigned char *) (const char *) (s))[2] - __s2[2]);
if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *)
(const char *) (s))[3] - __s2[3]); } } __result; })))) :
__builtin_strcmp (tmp, s)))); }) : strncmp (tmp, s, l))) == 0)

is a little hard to understand at a glance.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
2016-02-26 12:59:37 +00:00

314 lines
7.0 KiB
C

/*
* Copyright © 2014 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 <mika.kuoppala@intel.com>
* Oscar Mateo <oscar.mateo@intel.com>
*
*/
#include "igt.h"
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifndef I915_PARAM_CMD_PARSER_VERSION
#define I915_PARAM_CMD_PARSER_VERSION 28
#endif
static char read_buffer[1024];
static int _read_sysfs(void *dst, int maxlen,
const char* path,
const char *fname)
{
int fd;
char full[PATH_MAX];
int r, e;
igt_assert(snprintf(full, PATH_MAX, "%s/%s", path, fname) < PATH_MAX);
fd = open(full, O_RDONLY);
if (fd == -1)
return -errno;
r = read(fd, dst, maxlen);
e = errno;
close(fd);
if (r < 0)
return -e;
return r;
}
static int read_sysfs(void *dst, int maxlen, const char *fname)
{
char path[PATH_MAX];
igt_assert(snprintf(path, PATH_MAX, "/sys/class/drm/card%d",
drm_get_card()) < PATH_MAX);
return _read_sysfs(dst, maxlen, path, fname);
}
static void test_sysfs_error_exists(void)
{
igt_assert_lt(0, read_sysfs(read_buffer, sizeof(read_buffer), "error"));
}
static void test_debugfs_error_state_exists(void)
{
int fd;
igt_assert_lte(0,
(fd = igt_debugfs_open("i915_error_state", O_RDONLY)));
close (fd);
}
static void test_debugfs_ring_stop_exists(void)
{
int fd;
igt_assert_lte(0, (fd = igt_debugfs_open("i915_ring_stop", O_RDONLY)));
close(fd);
}
static void read_dfs(const char *fname, char *d, int maxlen)
{
int fd;
int l;
igt_assert_lte(0, (fd = igt_debugfs_open(fname, O_RDONLY)));
igt_assert_lt(0, (l = read(fd, d, maxlen - 1)));
igt_assert_lt(l, maxlen);
d[l] = 0;
close(fd);
igt_debug("dfs entry %s read '%s'\n", fname, d);
}
static int compare_dfs_entry(const char *fname, const char *s)
{
const int l = min(strlen(s), sizeof(read_buffer));
read_dfs(fname, read_buffer, l + 1);
return strncmp(read_buffer, s, l);
}
static void assert_dfs_entry(const char *fname, const char *s)
{
igt_fail_on_f(compare_dfs_entry(fname, s) != 0,
"contents of %s: '%s' (expected '%s')\n",
fname, read_buffer, s);
}
static void assert_dfs_entry_not(const char *fname, const char *s)
{
igt_fail_on_f(compare_dfs_entry(fname, s) == 0,
"contents of %s: '%s' (expected not '%s'\n",
fname, read_buffer, s);
}
static void assert_error_state_clear(void)
{
assert_dfs_entry("i915_error_state", "no error state collected");
}
static void assert_error_state_collected(void)
{
assert_dfs_entry_not("i915_error_state", "no error state collected");
}
const uint32_t *batch;
static uint64_t submit_hang(int fd, unsigned ring_id)
{
uint64_t offset;
igt_hang_ring_t hang;
hang = igt_hang_ctx(fd, 0, ring_id, HANG_ALLOW_CAPTURE, &offset);
batch = gem_mmap__cpu(fd, hang.handle, 0, 4096, PROT_READ);
gem_set_domain(fd, hang.handle, I915_GEM_DOMAIN_CPU, 0);
igt_post_hang_ring(fd, hang);
return offset;
}
static void clear_error_state(void)
{
int fd;
const char *b = "1";
igt_assert_lte(0,
(fd = igt_debugfs_open("i915_error_state", O_WRONLY)));
igt_assert(write(fd, b, 1) == 1);
close(fd);
}
static void test_error_state_basic(void)
{
int fd;
fd = drm_open_driver(DRIVER_INTEL);
clear_error_state();
assert_error_state_clear();
submit_hang(fd, I915_EXEC_RENDER);
close(fd);
assert_error_state_collected();
clear_error_state();
assert_error_state_clear();
}
static void check_error_state(const int gen,
const bool uses_cmd_parser,
const char *expected_ring_name,
uint64_t expected_offset)
{
FILE *file;
char *line = NULL;
size_t line_size = 0;
file = igt_debugfs_fopen("i915_error_state", "r");
igt_require(file);
while (getline(&line, &line_size, file) > 0) {
char *dashes;
uint32_t gtt_offset_upper, gtt_offset_lower;
int matched;
dashes = strstr(line, "---");
if (!dashes)
continue;
matched = sscanf(dashes, "--- gtt_offset = 0x%08x %08x\n",
&gtt_offset_upper, &gtt_offset_lower);
if (matched) {
char expected_line[64];
uint64_t gtt_offset;
int i;
strncpy(expected_line, line, dashes - line);
expected_line[dashes - line - 1] = '\0';
igt_assert(strstr(expected_line, expected_ring_name));
gtt_offset = gtt_offset_upper;
if (matched == 2) {
gtt_offset <<= 32;
gtt_offset |= gtt_offset_lower;
}
if (!uses_cmd_parser)
igt_assert_eq_u64(gtt_offset, expected_offset);
for (i = 0; i < 1024; i++) {
igt_assert(getline(&line, &line_size, file) > 0);
snprintf(expected_line, sizeof(expected_line),
"%08x : %08x",
4*i, batch[i]);
igt_assert(strstr(line, expected_line));
}
break;
}
}
free(line);
fclose(file);
}
static bool uses_cmd_parser(int fd, int gen)
{
int parser_version = 0;
drm_i915_getparam_t gp;
int rc;
gp.param = I915_PARAM_CMD_PARSER_VERSION;
gp.value = &parser_version;
rc = drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
if (rc || parser_version == 0)
return false;
if (!gem_uses_ppgtt(fd))
return false;
if (gen != 7)
return false;
return true;
}
static void test_error_state_capture(unsigned ring_id,
const char *ring_name)
{
int fd, gen;
uint64_t offset;
bool cmd_parser;
fd = drm_open_driver(DRIVER_INTEL);
clear_error_state();
gen = intel_gen(intel_get_drm_devid(fd));
cmd_parser = uses_cmd_parser(fd, gen);
offset = submit_hang(fd, ring_id);
close(fd);
check_error_state(gen, cmd_parser, ring_name, offset);
}
igt_main
{
const struct intel_execution_engine *e;
igt_skip_on_simulation();
igt_subtest("error-state-debugfs-entry")
test_debugfs_error_state_exists();
igt_subtest("error-state-sysfs-entry")
test_sysfs_error_exists();
igt_subtest("ring-stop-sysfs-entry")
test_debugfs_ring_stop_exists();
igt_subtest("error-state-basic")
test_error_state_basic();
for (e = intel_execution_engines; e->name; e++) {
if (e->exec_id == 0)
continue;
igt_subtest_f("error-state-capture-%s", e->name)
test_error_state_capture(e->exec_id | e->flags,
e->full_name);
}
}