alistair23-linux/drivers/gpu/drm/selftests/drm_selftest.c
Chris Wilson 50f0033d1a drm: Add some kselftests for the DRM range manager (struct drm_mm)
First we introduce a smattering of infrastructure for writing selftests.
The idea is that we have a test module that exercises a particular
portion of the exported API, and that module provides a set of tests
that can either be run as an ensemble via kselftest or individually via
an igt harness (in this case igt/drm_mm). To accommodate selecting
individual tests, we export a boolean parameter to control selection of
each test - that is hidden inside a bunch of reusable boilerplate macros
to keep writing the tests simple.

v2: Choose a random random_seed unless one is specified by the user.
v3: More parameters to control max_iterations and max_prime of the
tests.

Testcase: igt/drm_mm
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/20161222083641.2691-7-chris@chris-wilson.co.uk
2016-12-27 12:34:39 +01:00

110 lines
2.9 KiB
C

/*
* Copyright © 2016 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.
*/
#include <linux/compiler.h>
#define selftest(name, func) __idx_##name,
enum {
#include TESTS
};
#undef selftest
#define selftest(n, f) [__idx_##n] = { .name = #n, .func = f },
static struct drm_selftest {
bool enabled;
const char *name;
int (*func)(void *);
} selftests[] = {
#include TESTS
};
#undef selftest
/* Embed the line number into the parameter name so that we can order tests */
#define param(n) __PASTE(igt__, __PASTE(__PASTE(__LINE__, __), n))
#define selftest_0(n, func, id) \
module_param_named(id, selftests[__idx_##n].enabled, bool, 0400);
#define selftest(n, func) selftest_0(n, func, param(n))
#include TESTS
#undef selftest
static void set_default_test_all(struct drm_selftest *st, unsigned long count)
{
unsigned long i;
for (i = 0; i < count; i++)
if (st[i].enabled)
return;
for (i = 0; i < count; i++)
st[i].enabled = true;
}
static int run_selftests(struct drm_selftest *st,
unsigned long count,
void *data)
{
int err = 0;
set_default_test_all(st, count);
/* Tests are listed in natural order in drm_*_selftests.h */
for (; count--; st++) {
if (!st->enabled)
continue;
pr_debug("drm: Running %s\n", st->name);
err = st->func(data);
if (err)
break;
}
if (WARN(err > 0 || err == -ENOTTY,
"%s returned %d, conflicting with selftest's magic values!\n",
st->name, err))
err = -1;
rcu_barrier();
return err;
}
static int __maybe_unused
__drm_subtests(const char *caller,
const struct drm_subtest *st,
int count,
void *data)
{
int err;
for (; count--; st++) {
pr_debug("Running %s/%s\n", caller, st->name);
err = st->func(data);
if (err) {
pr_err("%s: %s failed with error %d\n",
caller, st->name, err);
return err;
}
}
return 0;
}