| .. | .. |
|---|
| 23 | 23 | |
|---|
| 24 | 24 | #include <linux/random.h> |
|---|
| 25 | 25 | |
|---|
| 26 | | -#include "../i915_drv.h" |
|---|
| 27 | | -#include "../i915_selftest.h" |
|---|
| 26 | +#include "gt/intel_gt_pm.h" |
|---|
| 27 | +#include "i915_drv.h" |
|---|
| 28 | +#include "i915_selftest.h" |
|---|
| 29 | + |
|---|
| 30 | +#include "igt_flush_test.h" |
|---|
| 28 | 31 | |
|---|
| 29 | 32 | struct i915_selftest i915_selftest __read_mostly = { |
|---|
| 30 | | - .timeout_ms = 1000, |
|---|
| 33 | + .timeout_ms = 500, |
|---|
| 31 | 34 | }; |
|---|
| 32 | 35 | |
|---|
| 33 | 36 | int i915_mock_sanitycheck(void) |
|---|
| .. | .. |
|---|
| 54 | 57 | #undef selftest |
|---|
| 55 | 58 | }; |
|---|
| 56 | 59 | |
|---|
| 60 | +enum { |
|---|
| 61 | +#define selftest(name, func) perf_##name, |
|---|
| 62 | +#include "i915_perf_selftests.h" |
|---|
| 63 | +#undef selftest |
|---|
| 64 | +}; |
|---|
| 65 | + |
|---|
| 57 | 66 | struct selftest { |
|---|
| 58 | 67 | bool enabled; |
|---|
| 59 | 68 | const char *name; |
|---|
| .. | .. |
|---|
| 75 | 84 | }; |
|---|
| 76 | 85 | #undef selftest |
|---|
| 77 | 86 | |
|---|
| 87 | +#define selftest(n, f) [perf_##n] = { .name = #n, { .live = f } }, |
|---|
| 88 | +static struct selftest perf_selftests[] = { |
|---|
| 89 | +#include "i915_perf_selftests.h" |
|---|
| 90 | +}; |
|---|
| 91 | +#undef selftest |
|---|
| 92 | + |
|---|
| 78 | 93 | /* Embed the line number into the parameter name so that we can order tests */ |
|---|
| 79 | 94 | #define selftest(n, func) selftest_0(n, func, param(n)) |
|---|
| 80 | 95 | #define param(n) __PASTE(igt__, __PASTE(__LINE__, __mock_##n)) |
|---|
| .. | .. |
|---|
| 88 | 103 | #define selftest_0(n, func, id) \ |
|---|
| 89 | 104 | module_param_named(id, live_selftests[live_##n].enabled, bool, 0400); |
|---|
| 90 | 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) \ |
|---|
| 111 | +module_param_named(id, perf_selftests[perf_##n].enabled, bool, 0400); |
|---|
| 112 | +#include "i915_perf_selftests.h" |
|---|
| 91 | 113 | #undef selftest_0 |
|---|
| 92 | 114 | #undef param |
|---|
| 93 | 115 | #undef selftest |
|---|
| .. | .. |
|---|
| 133 | 155 | if (signal_pending(current)) |
|---|
| 134 | 156 | return -EINTR; |
|---|
| 135 | 157 | |
|---|
| 136 | | - pr_debug(DRIVER_NAME ": Running %s\n", st->name); |
|---|
| 158 | + pr_info(DRIVER_NAME ": Running %s\n", st->name); |
|---|
| 137 | 159 | if (data) |
|---|
| 138 | 160 | err = st->live(data); |
|---|
| 139 | 161 | else |
|---|
| .. | .. |
|---|
| 183 | 205 | if (!i915_selftest.live) |
|---|
| 184 | 206 | return 0; |
|---|
| 185 | 207 | |
|---|
| 186 | | - err = run_selftests(live, to_i915(pci_get_drvdata(pdev))); |
|---|
| 208 | + err = run_selftests(live, pdev_to_i915(pdev)); |
|---|
| 187 | 209 | if (err) { |
|---|
| 188 | 210 | i915_selftest.live = err; |
|---|
| 189 | 211 | return err; |
|---|
| .. | .. |
|---|
| 197 | 219 | return 0; |
|---|
| 198 | 220 | } |
|---|
| 199 | 221 | |
|---|
| 222 | +int 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 | + |
|---|
| 243 | +static 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 | + |
|---|
| 286 | +int __i915_nop_setup(void *data) |
|---|
| 287 | +{ |
|---|
| 288 | + return 0; |
|---|
| 289 | +} |
|---|
| 290 | + |
|---|
| 291 | +int __i915_nop_teardown(int err, void *data) |
|---|
| 292 | +{ |
|---|
| 293 | + return err; |
|---|
| 294 | +} |
|---|
| 295 | + |
|---|
| 296 | +int __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 | + |
|---|
| 307 | +int __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 | + |
|---|
| 319 | +int __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 | + |
|---|
| 330 | +int __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 | + |
|---|
| 200 | 342 | int __i915_subtests(const char *caller, |
|---|
| 343 | + int (*setup)(void *data), |
|---|
| 344 | + int (*teardown)(int err, void *data), |
|---|
| 201 | 345 | const struct i915_subtest *st, |
|---|
| 202 | 346 | unsigned int count, |
|---|
| 203 | 347 | void *data) |
|---|
| .. | .. |
|---|
| 209 | 353 | if (signal_pending(current)) |
|---|
| 210 | 354 | return -EINTR; |
|---|
| 211 | 355 | |
|---|
| 212 | | - pr_debug(DRIVER_NAME ": Running %s/%s\n", caller, st->name); |
|---|
| 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); |
|---|
| 213 | 367 | GEM_TRACE("Running %s/%s\n", caller, st->name); |
|---|
| 214 | 368 | |
|---|
| 215 | | - err = st->func(data); |
|---|
| 369 | + err = teardown(st->func(data), data); |
|---|
| 216 | 370 | if (err && err != -EINTR) { |
|---|
| 217 | 371 | pr_err(DRIVER_NAME "/%s: %s failed with error %d\n", |
|---|
| 218 | 372 | caller, st->name, err); |
|---|
| .. | .. |
|---|
| 242 | 396 | return true; |
|---|
| 243 | 397 | } |
|---|
| 244 | 398 | |
|---|
| 399 | +void 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 | + |
|---|
| 245 | 428 | module_param_named(st_random_seed, i915_selftest.random_seed, uint, 0400); |
|---|
| 246 | 429 | module_param_named(st_timeout, i915_selftest.timeout_ms, uint, 0400); |
|---|
| 430 | +module_param_named(st_filter, i915_selftest.filter, charp, 0400); |
|---|
| 247 | 431 | |
|---|
| 248 | 432 | module_param_named_unsafe(mock_selftests, i915_selftest.mock, int, 0400); |
|---|
| 249 | 433 | MODULE_PARM_DESC(mock_selftests, "Run selftests before loading, using mock hardware (0:disabled [default], 1:run tests then load driver, -1:run tests then exit module)"); |
|---|
| 250 | 434 | |
|---|
| 251 | 435 | module_param_named_unsafe(live_selftests, i915_selftest.live, int, 0400); |
|---|
| 252 | 436 | MODULE_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 | + |
|---|
| 438 | +module_param_named_unsafe(perf_selftests, i915_selftest.perf, int, 0400); |
|---|
| 439 | +MODULE_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)"); |
|---|