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_drv.h"
  28#include "i915_selftest.h"
  29
  30#include "igt_flush_test.h"
  31
  32struct i915_selftest i915_selftest __read_mostly = {
  33        .timeout_ms = 500,
  34};
  35
  36int i915_mock_sanitycheck(void)
  37{
  38        pr_info(DRIVER_NAME ": %s() - ok!\n", __func__);
  39        return 0;
  40}
  41
  42int i915_live_sanitycheck(struct drm_i915_private *i915)
  43{
  44        pr_info("%s: %s() - ok!\n", i915->drm.driver->name, __func__);
  45        return 0;
  46}
  47
  48enum {
  49#define selftest(name, func) mock_##name,
  50#include "i915_mock_selftests.h"
  51#undef selftest
  52};
  53
  54enum {
  55#define selftest(name, func) live_##name,
  56#include "i915_live_selftests.h"
  57#undef selftest
  58};
  59
  60enum {
  61#define selftest(name, func) perf_##name,
  62#include "i915_perf_selftests.h"
  63#undef selftest
  64};
  65
  66struct selftest {
  67        bool enabled;
  68        const char *name;
  69        union {
  70                int (*mock)(void);
  71                int (*live)(struct drm_i915_private *);
  72        };
  73};
  74
  75#define selftest(n, f) [mock_##n] = { .name = #n, { .mock = f } },
  76static struct selftest mock_selftests[] = {
  77#include "i915_mock_selftests.h"
  78};
  79#undef selftest
  80
  81#define selftest(n, f) [live_##n] = { .name = #n, { .live = f } },
  82static struct selftest live_selftests[] = {
  83#include "i915_live_selftests.h"
  84};
  85#undef selftest
  86
  87#define selftest(n, f) [perf_##n] = { .name = #n, { .live = f } },
  88static struct selftest perf_selftests[] = {
  89#include "i915_perf_selftests.h"
  90};
  91#undef selftest
  92
  93/* Embed the line number into the parameter name so that we can order tests */
  94#define selftest(n, func) selftest_0(n, func, param(n))
  95#define param(n) __PASTE(igt__, __PASTE(__LINE__, __mock_##n))
  96#define selftest_0(n, func, id) \
  97module_param_named(id, mock_selftests[mock_##n].enabled, bool, 0400);
  98#include "i915_mock_selftests.h"
  99#undef selftest_0
 100#undef param
 101
 102#define param(n) __PASTE(igt__, __PASTE(__LINE__, __live_##n))
 103#define selftest_0(n, func, id) \
 104module_param_named(id, live_selftests[live_##n].enabled, bool, 0400);
 105#include "i915_live_selftests.h"
 106#undef selftest_0
 107#undef param
 108
 109#define param(n) __PASTE(igt__, __PASTE(__LINE__, __perf_##n))
 110#define selftest_0(n, func, id) \
 111module_param_named(id, perf_selftests[perf_##n].enabled, bool, 0400);
 112#include "i915_perf_selftests.h"
 113#undef selftest_0
 114#undef param
 115#undef selftest
 116
 117static void set_default_test_all(struct selftest *st, unsigned int count)
 118{
 119        unsigned int i;
 120
 121        for (i = 0; i < count; i++)
 122                if (st[i].enabled)
 123                        return;
 124
 125        for (i = 0; i < count; i++)
 126                st[i].enabled = true;
 127}
 128
 129static int __run_selftests(const char *name,
 130                           struct selftest *st,
 131                           unsigned int count,
 132                           void *data)
 133{
 134        int err = 0;
 135
 136        while (!i915_selftest.random_seed)
 137                i915_selftest.random_seed = get_random_int();
 138
 139        i915_selftest.timeout_jiffies =
 140                i915_selftest.timeout_ms ?
 141                msecs_to_jiffies_timeout(i915_selftest.timeout_ms) :
 142                MAX_SCHEDULE_TIMEOUT;
 143
 144        set_default_test_all(st, count);
 145
 146        pr_info(DRIVER_NAME ": Performing %s selftests with st_random_seed=0x%x st_timeout=%u\n",
 147                name, i915_selftest.random_seed, i915_selftest.timeout_ms);
 148
 149        /* Tests are listed in order in i915_*_selftests.h */
 150        for (; count--; st++) {
 151                if (!st->enabled)
 152                        continue;
 153
 154                cond_resched();
 155                if (signal_pending(current))
 156                        return -EINTR;
 157
 158                pr_info(DRIVER_NAME ": Running %s\n", st->name);
 159                if (data)
 160                        err = st->live(data);
 161                else
 162                        err = st->mock();
 163                if (err == -EINTR && !signal_pending(current))
 164                        err = 0;
 165                if (err)
 166                        break;
 167        }
 168
 169        if (WARN(err > 0 || err == -ENOTTY,
 170                 "%s returned %d, conflicting with selftest's magic values!\n",
 171                 st->name, err))
 172                err = -1;
 173
 174        return err;
 175}
 176
 177#define run_selftests(x, data) \
 178        __run_selftests(#x, x##_selftests, ARRAY_SIZE(x##_selftests), data)
 179
 180int i915_mock_selftests(void)
 181{
 182        int err;
 183
 184        if (!i915_selftest.mock)
 185                return 0;
 186
 187        err = run_selftests(mock, NULL);
 188        if (err) {
 189                i915_selftest.mock = err;
 190                return 1;
 191        }
 192
 193        if (i915_selftest.mock < 0) {
 194                i915_selftest.mock = -ENOTTY;
 195                return 1;
 196        }
 197
 198        return 0;
 199}
 200
 201int i915_live_selftests(struct pci_dev *pdev)
 202{
 203        int err;
 204
 205        if (!i915_selftest.live)
 206                return 0;
 207
 208        err = run_selftests(live, pdev_to_i915(pdev));
 209        if (err) {
 210                i915_selftest.live = err;
 211                return err;
 212        }
 213
 214        if (i915_selftest.live < 0) {
 215                i915_selftest.live = -ENOTTY;
 216                return 1;
 217        }
 218
 219        return 0;
 220}
 221
 222int i915_perf_selftests(struct pci_dev *pdev)
 223{
 224        int err;
 225
 226        if (!i915_selftest.perf)
 227                return 0;
 228
 229        err = run_selftests(perf, pdev_to_i915(pdev));
 230        if (err) {
 231                i915_selftest.perf = err;
 232                return err;
 233        }
 234
 235        if (i915_selftest.perf < 0) {
 236                i915_selftest.perf = -ENOTTY;
 237                return 1;
 238        }
 239
 240        return 0;
 241}
 242
 243static bool apply_subtest_filter(const char *caller, const char *name)
 244{
 245        char *filter, *sep, *tok;
 246        bool result = true;
 247
 248        filter = kstrdup(i915_selftest.filter, GFP_KERNEL);
 249        for (sep = filter; (tok = strsep(&sep, ","));) {
 250                bool allow = true;
 251                char *sl;
 252
 253                if (*tok == '!') {
 254                        allow = false;
 255                        tok++;
 256                }
 257
 258                if (*tok == '\0')
 259                        continue;
 260
 261                sl = strchr(tok, '/');
 262                if (sl) {
 263                        *sl++ = '\0';
 264                        if (strcmp(tok, caller)) {
 265                                if (allow)
 266                                        result = false;
 267                                continue;
 268                        }
 269                        tok = sl;
 270                }
 271
 272                if (strcmp(tok, name)) {
 273                        if (allow)
 274                                result = false;
 275                        continue;
 276                }
 277
 278                result = allow;
 279                break;
 280        }
 281        kfree(filter);
 282
 283        return result;
 284}
 285
 286int __i915_nop_setup(void *data)
 287{
 288        return 0;
 289}
 290
 291int __i915_nop_teardown(int err, void *data)
 292{
 293        return err;
 294}
 295
 296int __i915_live_setup(void *data)
 297{
 298        struct drm_i915_private *i915 = data;
 299
 300        /* The selftests expect an idle system */
 301        if (intel_gt_pm_wait_for_idle(&i915->gt))
 302                return -EIO;
 303
 304        return intel_gt_terminally_wedged(&i915->gt);
 305}
 306
 307int __i915_live_teardown(int err, void *data)
 308{
 309        struct drm_i915_private *i915 = data;
 310
 311        if (igt_flush_test(i915))
 312                err = -EIO;
 313
 314        i915_gem_drain_freed_objects(i915);
 315
 316        return err;
 317}
 318
 319int __intel_gt_live_setup(void *data)
 320{
 321        struct intel_gt *gt = data;
 322
 323        /* The selftests expect an idle system */
 324        if (intel_gt_pm_wait_for_idle(gt))
 325                return -EIO;
 326
 327        return intel_gt_terminally_wedged(gt);
 328}
 329
 330int __intel_gt_live_teardown(int err, void *data)
 331{
 332        struct intel_gt *gt = data;
 333
 334        if (igt_flush_test(gt->i915))
 335                err = -EIO;
 336
 337        i915_gem_drain_freed_objects(gt->i915);
 338
 339        return err;
 340}
 341
 342int __i915_subtests(const char *caller,
 343                    int (*setup)(void *data),
 344                    int (*teardown)(int err, void *data),
 345                    const struct i915_subtest *st,
 346                    unsigned int count,
 347                    void *data)
 348{
 349        int err;
 350
 351        for (; count--; st++) {
 352                cond_resched();
 353                if (signal_pending(current))
 354                        return -EINTR;
 355
 356                if (!apply_subtest_filter(caller, st->name))
 357                        continue;
 358
 359                err = setup(data);
 360                if (err) {
 361                        pr_err(DRIVER_NAME "/%s: setup failed for %s\n",
 362                               caller, st->name);
 363                        return err;
 364                }
 365
 366                pr_info(DRIVER_NAME ": Running %s/%s\n", caller, st->name);
 367                GEM_TRACE("Running %s/%s\n", caller, st->name);
 368
 369                err = teardown(st->func(data), data);
 370                if (err && err != -EINTR) {
 371                        pr_err(DRIVER_NAME "/%s: %s failed with error %d\n",
 372                               caller, st->name, err);
 373                        return err;
 374                }
 375        }
 376
 377        return 0;
 378}
 379
 380bool __igt_timeout(unsigned long timeout, const char *fmt, ...)
 381{
 382        va_list va;
 383
 384        if (!signal_pending(current)) {
 385                cond_resched();
 386                if (time_before(jiffies, timeout))
 387                        return false;
 388        }
 389
 390        if (fmt) {
 391                va_start(va, fmt);
 392                vprintk(fmt, va);
 393                va_end(va);
 394        }
 395
 396        return true;
 397}
 398
 399void igt_hexdump(const void *buf, size_t len)
 400{
 401        const size_t rowsize = 8 * sizeof(u32);
 402        const void *prev = NULL;
 403        bool skip = false;
 404        size_t pos;
 405
 406        for (pos = 0; pos < len; pos += rowsize) {
 407                char line[128];
 408
 409                if (prev && !memcmp(prev, buf + pos, rowsize)) {
 410                        if (!skip) {
 411                                pr_info("*\n");
 412                                skip = true;
 413                        }
 414                        continue;
 415                }
 416
 417                WARN_ON_ONCE(hex_dump_to_buffer(buf + pos, len - pos,
 418                                                rowsize, sizeof(u32),
 419                                                line, sizeof(line),
 420                                                false) >= sizeof(line));
 421                pr_info("[%04zx] %s\n", pos, line);
 422
 423                prev = buf + pos;
 424                skip = false;
 425        }
 426}
 427
 428module_param_named(st_random_seed, i915_selftest.random_seed, uint, 0400);
 429module_param_named(st_timeout, i915_selftest.timeout_ms, uint, 0400);
 430module_param_named(st_filter, i915_selftest.filter, charp, 0400);
 431
 432module_param_named_unsafe(mock_selftests, i915_selftest.mock, int, 0400);
 433MODULE_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)");
 434
 435module_param_named_unsafe(live_selftests, i915_selftest.live, int, 0400);
 436MODULE_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)");
 437
 438module_param_named_unsafe(perf_selftests, i915_selftest.perf, int, 0400);
 439MODULE_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)");
 440