[PATCH 02/45] drm/i915: Provide a hook for selftests
Tvrtko Ursulin
tvrtko.ursulin at linux.intel.com
Tue Dec 6 12:33:04 UTC 2016
On 06/12/2016 00:12, Chris Wilson wrote:
> Some pieces of code are independent of hardware but are very tricky to
> exercise through the normal userspace ABI or via debugfs hooks. Being
> able to create mock unit tests and execute them through CI is vital.
> Start by adding a central point where we can execute unit tests from and
> a parameter to enable them. This is disabled by default as the
> expectation is that these tests will occasionally explode.
>
> To facilitate integration with igt, any parameter beginning with
> i915.igt__ is interpreted as a subtest executable independently via
> igt/drv_selftest.
>
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> ---
> drivers/gpu/drm/i915/Kconfig.debug | 15 +++++
> drivers/gpu/drm/i915/Makefile | 1 +
> drivers/gpu/drm/i915/i915_params.c | 5 ++
> drivers/gpu/drm/i915/i915_params.h | 3 +
> drivers/gpu/drm/i915/i915_pci.c | 6 ++
> drivers/gpu/drm/i915/i915_selftest.c | 115 ++++++++++++++++++++++++++++++++++
> drivers/gpu/drm/i915/i915_selftest.h | 54 ++++++++++++++++
> drivers/gpu/drm/i915/i915_selftests.h | 11 ++++
> 8 files changed, 210 insertions(+)
> create mode 100644 drivers/gpu/drm/i915/i915_selftest.c
> create mode 100644 drivers/gpu/drm/i915/i915_selftest.h
> create mode 100644 drivers/gpu/drm/i915/i915_selftests.h
>
> diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug
> index 597648c7a645..76af8774cf70 100644
> --- a/drivers/gpu/drm/i915/Kconfig.debug
> +++ b/drivers/gpu/drm/i915/Kconfig.debug
> @@ -25,6 +25,7 @@ config DRM_I915_DEBUG
> select DRM_VGEM # used by igt/prime_vgem (dmabuf interop checks)
> select DRM_DEBUG_MM if DRM=y
> select DRM_I915_SW_FENCE_DEBUG_OBJECTS
> + select DRM_I915_SELFTEST
> default n
> help
> Choose this option to turn on extra driver debugging that may affect
> @@ -58,3 +59,17 @@ config DRM_I915_SW_FENCE_DEBUG_OBJECTS
> Recommended for driver developers only.
>
> If in doubt, say "N".
> +
> +config DRM_I915_SELFTEST
> + bool "Enable selftests upon driver load"
> + depends on DRM_I915
> + default n
> + help
> + Choose this option to allow the driver to perform selftests upon
> + loading; also requires the i915.selftest=1 module parameter. To
> + exit the module after running the selftests (i.e. to prevent normal
> + module initialisation afterwards) use i915.selftest=-1.
> +
> + Recommended for driver developers only.
> +
> + If in doubt, say "N".
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 3c30916727fb..7c3b4f0c836c 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -114,6 +114,7 @@ i915-y += dvo_ch7017.o \
>
> # Post-mortem debug and GPU hang state capture
> i915-$(CONFIG_DRM_I915_CAPTURE_ERROR) += i915_gpu_error.o
> +i915-$(CONFIG_DRM_I915_SELFTEST) += i915_selftest.o
>
> # virtual gpu code
> i915-y += i915_vgpu.o
> diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
> index 0e280fbd52f1..b66e38e66833 100644
> --- a/drivers/gpu/drm/i915/i915_params.c
> +++ b/drivers/gpu/drm/i915/i915_params.c
> @@ -243,3 +243,8 @@ MODULE_PARM_DESC(enable_dpcd_backlight,
> module_param_named(enable_gvt, i915.enable_gvt, bool, 0400);
> MODULE_PARM_DESC(enable_gvt,
> "Enable support for Intel GVT-g graphics virtualization host support(default:false)");
> +
> +#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
> +module_param_named_unsafe(selftest, i915.selftest, int, 0400);
> +MODULE_PARM_DESC(selftest, "Run selftests when loading (0:disabled [default], 1 run tests then load module, -1 run tests then exit module)");
Colon after 1 and -1 perhaps?
> +#endif
> diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h
> index 8e433de04679..49ca8a6f9407 100644
> --- a/drivers/gpu/drm/i915/i915_params.h
> +++ b/drivers/gpu/drm/i915/i915_params.h
> @@ -28,6 +28,9 @@
> #include <linux/cache.h> /* for __read_mostly */
>
> struct i915_params {
> +#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
> + int selftest;
> +#endif
> int modeset;
> int panel_ignore_lid;
> int semaphores;
> diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
> index 389a33090707..1683adb845ee 100644
> --- a/drivers/gpu/drm/i915/i915_pci.c
> +++ b/drivers/gpu/drm/i915/i915_pci.c
> @@ -27,6 +27,7 @@
> #include <linux/vga_switcheroo.h>
>
> #include "i915_drv.h"
> +#include "i915_selftest.h"
>
> #define GEN_DEFAULT_PIPEOFFSETS \
> .pipe_offsets = { PIPE_A_OFFSET, PIPE_B_OFFSET, \
> @@ -496,6 +497,11 @@ static struct pci_driver i915_pci_driver = {
> static int __init i915_init(void)
> {
> bool use_kms = true;
> + int ret;
> +
> + ret = i915_selftest();
> + if (ret)
> + return ret;
>
> /*
> * Enable KMS by default, unless explicitly overriden by
> diff --git a/drivers/gpu/drm/i915/i915_selftest.c b/drivers/gpu/drm/i915/i915_selftest.c
> new file mode 100644
> index 000000000000..cbb0800b919e
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/i915_selftest.c
> @@ -0,0 +1,115 @@
> +/*
> + * 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 "i915_drv.h"
> +#include "i915_selftest.h"
> +
> +int i915_selftest_sanitycheck(void)
> +{
> + pr_info("i915: %s() - ok!\n", __func__);
> + return 0;
> +}
> +
> +#define selftest(name, func) name,
> +enum {
> +#include "i915_selftests.h"
> +};
> +#undef selftest
> +
> +#define selftest(name, func) [name] = { #name, func },
> +static struct i915_selftest_subtest {
> + const char *name;
> + int (*func)(void);
> + bool enabled;
> +} i915_selftests[] = {
> +#include "i915_selftests.h"
> +};
> +#undef selftest
> +
> +#define selftest(name, func) \
> +module_param_named(igt__##name, i915_selftests[name].enabled, bool, 0400);
> +#include "i915_selftests.h"
> +#undef selftest
> +
> +static void set_default_test_all(void)
> +{
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(i915_selftests); i++)
> + if (i915_selftests[i].enabled)
> + return;
> +
> + for (i = 0; i < ARRAY_SIZE(i915_selftests); i++)
> + i915_selftests[i].enabled = true;
> +}
> +
> +int i915_selftest(void)
> +{
> + int i;
> +
> + if (!i915.selftest)
> + return 0;
> +
> + pr_info("i915: Performing selftests\n");
> + set_default_test_all();
> +
> + for (i = 0; i < ARRAY_SIZE(i915_selftests); i++) {
> + int err;
> +
> + if (!i915_selftests[i].enabled)
> + continue;
> +
> + pr_debug("i915: Running %s\n", i915_selftests[i].name);
> + err = i915_selftests[i].func();
> + if (err)
> + return err;
> + }
> +
> + if (i915.selftest < 0)
> + return -ENOTTY;
> +
> + return 0;
> +}
> +
> +int __i915_subtests(const char *caller,
> + const struct i915_subtest *st,
> + int count,
> + void *data)
> +{
> + int err;
> +
> + while (count--) {
> + pr_debug("i915: Running %s/%s\n", caller, st->name);
> +
> + err = st->func(data);
> + if (err) {
> + pr_err("i915/%s: %s failed with error %d\n",
> + caller, st->name, err);
> + return err;
> + }
> +
> + st++;
> + }
> +
> + return 0;
> +}
> diff --git a/drivers/gpu/drm/i915/i915_selftest.h b/drivers/gpu/drm/i915/i915_selftest.h
> new file mode 100644
> index 000000000000..f1dc157a9461
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/i915_selftest.h
> @@ -0,0 +1,54 @@
> +/*
> + * 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.
> + */
> +
> +#ifndef __I915_SELFTEST_H__
> +#define __I915_SELFTEST_H__
> +
> +#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
> +int i915_selftest(void);
> +#else
> +static inline int i915_selftest(void) { return 0; }
> +#endif
> +
> +/* We extract the function declarations from i915_selftests.h.
> + * Add your unit tests there!
s/Add/Declare/ ?
> + */
> +#define selftest(name, func) int func(void);
> +#include "i915_selftests.h"
> +#undef selftest
> +
> +struct i915_subtest {
> + int (*func)(void *data);
> + const char *name;
> +};
> +
> +int __i915_subtests(const char *caller,
> + const struct i915_subtest *st,
> + int count,
> + void *data);
> +#define i915_subtests(T, data) \
> + __i915_subtests(__func__, T, ARRAY_SIZE(T), data)
> +
> +#define SUBTEST(x) { x, #x }
> +
> +#endif /* __I915_SELFTEST_H__ */
> diff --git a/drivers/gpu/drm/i915/i915_selftests.h b/drivers/gpu/drm/i915/i915_selftests.h
> new file mode 100644
> index 000000000000..3f8015c8a520
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/i915_selftests.h
> @@ -0,0 +1,11 @@
> +/* List each unit test as selftest(name, function)
> + *
> + * The name is used as both an enum and expanded as subtest__name to create
> + * a module parameter. It must be unique and legal for a C identifier.
> + *
> + * The function should be of type int function(void). It may be conditionally
> + * compiled using #if IS_ENABLED(DRM_I915_SELFTEST).
> + *
> + * Tests are executed in reverse order by igt/drv_selftest
> + */
> +selftest(sanitycheck, i915_selftest_sanitycheck) /* keep last */
>
Some preprocessor trickery to navigate but looks ok. :)
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
Regards,
Tvrtko
More information about the Intel-gfx-trybot
mailing list