linux/drivers/gpu/drm/i915/selftests/i915_selftest.c
<<
>>
Prefs
   1/*
   2 * Copyright © 2016 Intel Corporation
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice (including the next
  12 * paragraph) shall be included in all copies or substantial portions of the
  13 * Software.
  14 *
  15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21 * IN THE SOFTWARE.
  22 */
  23
  24#include <linux/random.h>
  25
  26#include "gt/intel_gt_pm.h"
  27#include "i915_driver.h"
  28#include "i915_drv.h"
  29#include "i915_selftest.h"
  30
  31#include "igt_flush_test.h"
  32
  33struct i915_selftest i915_selftest __read_mostly = {
  34        .timeout_ms = 500,
  35};
  36
  37int i915_mock_sanitycheck(void)
  38{
  39        pr_info(DRIVER_NAME ": %s() - ok!\n", __func__);
  40        return 0;
  41}
  42
  43int i915_live_sanitycheck(struct drm_i915_private *i915)
  44{
  45        pr_info("%s: %s() - ok!\n", i915->drm.driver->name, __func__);
  46        return 0;
  47}
  48
  49enum {
  50#define selftest(name, func) mock_##name,
  51#include "i915_mock_selftests.h"
  52#undef selftest
  53};
  54
  55enum {
  56#define selftest(name, func) live_##name,
  57#include "i915_live_selftests.h"
  58#undef selftest
  59};
  60
  61enum {
  62#define selftest(name, func) perf_##name,
  63#include "i915_perf_selftests.h"
  64#undef selftest
  65};
  66
  67struct selftest {
  68        bool enabled;
  69        const char *name;
  70        union {
  71                int (*mock)(void);
  72                int (*live)(struct drm_i915_private *);
  73        };
  74};
  75
  76#define selftest(n, f) [mock_##n] = { .name = #n, { .mock = f } },
  77static struct selftest mock_selftests[] = {
  78#include "i915_mock_selftests.h"
  79};
  80#undef selftest
  81
  82#define selftest(n, f) [live_##n] = { .name = #n, { .live = f } },
  83static struct selftest live_selftests[] = {
  84#include "i915_live_selftests.h"
  85};
  86#undef selftest
  87
  88#define selftest(n, f) [perf_##n] = { .name = #n, { .live = f } },
  89static struct selftest perf_selftests[] = {
  90#include "i915_perf_selftests.h"
  91};
  92#undef selftest
  93
  94/* Embed the line number into the parameter name so that we can order tests */
  95#define selftest(n, func) selftest_0(n, func, param(n))
  96#define param(n) __PASTE(igt__, __PASTE(__LINE__, __mock_##n))
  97#define selftest_0(n, func, id) \
  98module_param_named(id, mock_selftests[mock_##n].enabled, bool, 0400);
  99#include "i915_mock_selftests.h"
 100#undef selftest_0
 101#undef param
 102
 103#define param(n) __PASTE(igt__, __PASTE(__LINE__, __live_##n))
 104#define selftest_0(n, func, id) \
 105module_param_named(id, live_selftests[live_##n].enabled, bool, 0400);
 106#include "i915_live_selftests.h"
 107#undef selftest_0
 108#undef param
 109
 110#define param(n) __PASTE(igt__, __PASTE(__LINE__, __perf_##n))
 111#define selftest_0(n, func, id) \
 112module_param_named(id, perf_selftests[perf_##n].enabled, bool, 0400);
 113#include "i915_perf_selftests.h"
 114#undef selftest_0
 115#undef param
 116#undef selftest
 117
 118static void set_default_test_all(struct selftest *st, unsigned int count)
 119{
 120        unsigned int i;
 121
 122        for (i = 0; i < count; i++)
 123                if (st[i].enabled)
 124                        return;
 125
 126        for (i = 0; i < count; i++)
 127                st[i].enabled = true;
 128}
 129
 130static int __run_selftests(const char *name,
 131                           struct selftest *st,
 132                           unsigned int count,
 133                           void *data)
 134{
 135        int err = 0;
 136
 137        while (!i915_selftest.random_seed)
 138                i915_selftest.random_seed = get_random_int();
 139
 140        i915_selftest.timeout_jiffies =
 141                i915_selftest.timeout_ms ?
 142                msecs_to_jiffies_timeout(i915_selftest.timeout_ms) :
 143                MAX_SCHEDULE_TIMEOUT;
 144
 145        set_default_test_all(st, count);
 146
 147        pr_info(DRIVER_NAME ": Performing %s selftests with st_random_seed=0x%x st_timeout=%u\n",
 148                name, i915_selftest.random_seed, i915_selftest.timeout_ms);
 149
 150        /* Tests are listed in order in i915_*_selftests.h */
 151        for (; count--; st++) {
 152                if (!st->enabled)
 153                        continue;
 154
 155                cond_resched();
 156                if (signal_pending(current))
 157                        return -EINTR;
 158
 159                pr_info(DRIVER_NAME ": Running %s\n", st->name);
 160                if (data)
 161                        err = st->live(data);
 162                else
 163                        err = st->mock();
 164                if (err == -EINTR && !signal_pending(current))
 165                        err = 0;
 166                if (err)
 167                        break;
 168        }
 169
 170        if (WARN(err > 0 || err == -ENOTTY,
 171                 "%s returned %d, conflicting with selftest's magic values!\n",
 172                 st->name, err))
 173                err = -1;
 174
 175        return err;
 176}
 177
 178#define run_selftests(x, data) \
 179        __run_selftests(#x, x##_selftests, ARRAY_SIZE(x##_selftests), data)
 180
 181int i915_mock_selftests(void)
 182{
 183        int err;
 184
 185        if (!i915_selftest.mock)
 186                return 0;
 187
 188        err = run_selftests(mock, NULL);
 189        if (err) {
 190                i915_selftest.mock = err;
 191                return 1;
 192        }
 193
 194        if (i915_selftest.mock < 0) {
 195                i915_selftest.mock = -ENOTTY;
 196                return 1;
 197        }
 198
 199        return 0;
 200}
 201
 202int i915_live_selftests(struct pci_dev *pdev)
 203{
 204        int err;
 205
 206        if (!i915_selftest.live)
 207                return 0;
 208
 209        err = run_selftests(live, pdev_to_i915(pdev));
 210        if (err) {
 211                i915_selftest.live = err;
 212                return err;
 213        }
 214
 215        if (i915_selftest.live < 0) {
 216                i915_selftest.live = -ENOTTY;
 217                return 1;
 218        }
 219
 220        return 0;
 221}
 222
 223int i915_perf_selftests(struct pci_dev *pdev)
 224{
 225        int err;
 226
 227        if (!i915_selftest.perf)
 228                return 0;
 229
 230        err = run_selftests(perf, pdev_to_i915(pdev));
 231        if (err) {
 232                i915_selftest.perf = err;
 233                return err;
 234        }
 235
 236        if (i915_selftest.perf < 0) {
 237                i915_selftest.perf = -ENOTTY;
 238                return 1;
 239        }
 240
 241        return 0;
 242}
 243
 244static bool apply_subtest_filter(const char *caller, const char *name)
 245{
 246        char *filter, *sep, *tok;
 247        bool result = true;
 248
 249        filter = kstrdup(i915_selftest.filter, GFP_KERNEL);
 250        for (sep = filter; (tok = strsep(&sep, ","));) {
 251                bool allow = true;
 252                char *sl;
 253
 254                if (*tok == '!') {
 255                        allow = false;
 256                        tok++;
 257                }
 258
 259                if (*tok == '\0')
 260                        continue;
 261
 262                sl = strchr(tok, '/');
 263                if (sl) {
 264                        *sl++ = '\0';
 265                        if (strcmp(tok, caller)) {
 266                                if (allow)
 267                                        result = false;
 268                                continue;
 269                        }
 270                        tok = sl;
 271                }
 272
 273                if (strcmp(tok, name)) {
 274                        if (allow)
 275                                result = false;
 276                        continue;
 277                }
 278
 279                result = allow;
 280                break;
 281        }
 282        kfree(filter);
 283
 284        return result;
 285}
 286
 287int __i915_nop_setup(void *data)
 288{
 289        return 0;
 290}
 291
 292int __i915_nop_teardown(int err, void *data)
 293{
 294        return err;
 295}
 296
 297int __i915_live_setup(void *data)
 298{
 299        struct drm_i915_private *i915 = data;
 300
 301        /* The selftests expect an idle system */
 302        if (intel_gt_pm_wait_for_idle(to_gt(i915)))
 303                return -EIO;
 304
 305        return intel_gt_terminally_wedged(to_gt(i915));
 306}
 307
 308int __i915_live_teardown(int err, void *data)
 309{
 310        struct drm_i915_private *i915 = data;
 311
 312        if (igt_flush_test(i915))
 313                err = -EIO;
 314
 315        i915_gem_drain_freed_objects(i915);
 316
 317        return err;
 318}
 319
 320int __intel_gt_live_setup(void *data)
 321{
 322        struct intel_gt *gt = data;
 323
 324        /* The selftests expect an idle system */
 325        if (intel_gt_pm_wait_for_idle(gt))
 326                return -EIO;
 327
 328        return intel_gt_terminally_wedged(gt);
 329}
 330
 331int __intel_gt_live_teardown(int err, void *data)
 332{
 333        struct intel_gt *gt = data;
 334
 335        if (igt_flush_test(gt->i915))
 336                err = -EIO;
 337
 338        i915_gem_drain_freed_objects(gt->i915);
 339
 340        return err;
 341}
 342
 343int __i915_subtests(const char *caller,
 344                    int (*setup)(void *data),
 345                    int (*teardown)(int err, void *data),
 346                    const struct i915_subtest *st,
 347                    unsigned int count,
 348                    void *data)
 349{
 350        int err;
 351
 352        for (; count--; st++) {
 353                cond_resched();
 354                if (signal_pending(current))
 355                        return -EINTR;
 356
 357                if (!apply_subtest_filter(caller, st->name))
 358                        continue;
 359
 360                err = setup(data);
 361                if (err) {
 362                        pr_err(DRIVER_NAME "/%s: setup failed for %s\n",
 363                               caller, st->name);
 364                        return err;
 365                }
 366
 367                pr_info(DRIVER_NAME ": Running %s/%s\n", caller, st->name);
 368                GEM_TRACE("Running %s/%s\n", caller, st->name);
 369
 370                err = teardown(st->func(data), data);
 371                if (err && err != -EINTR) {
 372                        pr_err(DRIVER_NAME "/%s: %s failed with error %d\n",
 373                               caller, st->name, err);
 374                        return err;
 375                }
 376        }
 377
 378        return 0;
 379}
 380
 381bool __igt_timeout(unsigned long timeout, const char *fmt, ...)
 382{
 383        va_list va;
 384
 385        if (!signal_pending(current)) {
 386                cond_resched();
 387                if (time_before(jiffies, timeout))
 388                        return false;
 389        }
 390
 391        if (fmt) {
 392                va_start(va, fmt);
 393                vprintk(fmt, va);
 394                va_end(va);
 395        }
 396
 397        return true;
 398}
 399
 400void igt_hexdump(const void *buf, size_t len)
 401{
 402        const size_t rowsize = 8 * sizeof(u32);
 403        const void *prev = NULL;
 404        bool skip = false;
 405        size_t pos;
 406
 407        for (pos = 0; pos < len; pos += rowsize) {
 408                char line[128];
 409
 410                if (prev && !memcmp(prev, buf + pos, rowsize)) {
 411                        if (!skip) {
 412                                pr_info("*\n");
 413                                skip = true;
 414                        }
 415                        continue;
 416                }
 417
 418                WARN_ON_ONCE(hex_dump_to_buffer(buf + pos, len - pos,
 419                                                rowsize, sizeof(u32),
 420                                                line, sizeof(line),
 421                                                false) >= sizeof(line));
 422                pr_info("[%04zx] %s\n", pos, line);
 423
 424                prev = buf + pos;
 425                skip = false;
 426        }
 427}
 428
 429module_param_named(st_random_seed, i915_selftest.random_seed, uint, 0400);
 430module_param_named(st_timeout, i915_selftest.timeout_ms, uint, 0400);
 431module_param_named(st_filter, i915_selftest.filter, charp, 0400);
 432
 433module_param_named_unsafe(mock_selftests, i915_selftest.mock, int, 0400);
 434MODULE_PARM_DESC(mock_selftests, "Run selftests before loading, using mock hardware (0:disabled [default], 1:run tests then load driver, -1:run tests then leave dummy module)");
 435
 436module_param_named_unsafe(live_selftests, i915_selftest.live, int, 0400);
 437MODULE_PARM_DESC(live_selftests, "Run selftests after driver initialisation on the live system (0:disabled [default], 1:run tests then continue, -1:run tests then exit module)");
 438
 439module_param_named_unsafe(perf_selftests, i915_selftest.perf, int, 0400);
 440MODULE_PARM_DESC(perf_selftests, "Run performance orientated selftests after driver initialisation on the live system (0:disabled [default], 1:run tests then continue, -1:run tests then exit module)");
 441