selftest_timeline.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429
  1. // SPDX-License-Identifier: MIT
  2. /*
  3. * Copyright © 2017-2018 Intel Corporation
  4. */
  5. #include <linux/prime_numbers.h>
  6. #include <linux/string_helpers.h>
  7. #include "intel_context.h"
  8. #include "intel_engine_heartbeat.h"
  9. #include "intel_engine_pm.h"
  10. #include "intel_engine_regs.h"
  11. #include "intel_gpu_commands.h"
  12. #include "intel_gt.h"
  13. #include "intel_gt_requests.h"
  14. #include "intel_ring.h"
  15. #include "selftest_engine_heartbeat.h"
  16. #include "../selftests/i915_random.h"
  17. #include "../i915_selftest.h"
  18. #include "selftests/igt_flush_test.h"
  19. #include "selftests/lib_sw_fence.h"
  20. #include "selftests/mock_gem_device.h"
  21. #include "selftests/mock_timeline.h"
  22. static struct page *hwsp_page(struct intel_timeline *tl)
  23. {
  24. struct drm_i915_gem_object *obj = tl->hwsp_ggtt->obj;
  25. GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
  26. return sg_page(obj->mm.pages->sgl);
  27. }
  28. static unsigned long hwsp_cacheline(struct intel_timeline *tl)
  29. {
  30. unsigned long address = (unsigned long)page_address(hwsp_page(tl));
  31. return (address + offset_in_page(tl->hwsp_offset)) / TIMELINE_SEQNO_BYTES;
  32. }
  33. static int selftest_tl_pin(struct intel_timeline *tl)
  34. {
  35. struct i915_gem_ww_ctx ww;
  36. int err;
  37. i915_gem_ww_ctx_init(&ww, false);
  38. retry:
  39. err = i915_gem_object_lock(tl->hwsp_ggtt->obj, &ww);
  40. if (!err)
  41. err = intel_timeline_pin(tl, &ww);
  42. if (err == -EDEADLK) {
  43. err = i915_gem_ww_ctx_backoff(&ww);
  44. if (!err)
  45. goto retry;
  46. }
  47. i915_gem_ww_ctx_fini(&ww);
  48. return err;
  49. }
  50. /* Only half of seqno's are usable, see __intel_timeline_get_seqno() */
  51. #define CACHELINES_PER_PAGE (PAGE_SIZE / TIMELINE_SEQNO_BYTES / 2)
  52. struct mock_hwsp_freelist {
  53. struct intel_gt *gt;
  54. struct radix_tree_root cachelines;
  55. struct intel_timeline **history;
  56. unsigned long count, max;
  57. struct rnd_state prng;
  58. };
  59. enum {
  60. SHUFFLE = BIT(0),
  61. };
  62. static void __mock_hwsp_record(struct mock_hwsp_freelist *state,
  63. unsigned int idx,
  64. struct intel_timeline *tl)
  65. {
  66. tl = xchg(&state->history[idx], tl);
  67. if (tl) {
  68. radix_tree_delete(&state->cachelines, hwsp_cacheline(tl));
  69. intel_timeline_unpin(tl);
  70. intel_timeline_put(tl);
  71. }
  72. }
  73. static int __mock_hwsp_timeline(struct mock_hwsp_freelist *state,
  74. unsigned int count,
  75. unsigned int flags)
  76. {
  77. struct intel_timeline *tl;
  78. unsigned int idx;
  79. while (count--) {
  80. unsigned long cacheline;
  81. int err;
  82. tl = intel_timeline_create(state->gt);
  83. if (IS_ERR(tl))
  84. return PTR_ERR(tl);
  85. err = selftest_tl_pin(tl);
  86. if (err) {
  87. intel_timeline_put(tl);
  88. return err;
  89. }
  90. cacheline = hwsp_cacheline(tl);
  91. err = radix_tree_insert(&state->cachelines, cacheline, tl);
  92. if (err) {
  93. if (err == -EEXIST) {
  94. pr_err("HWSP cacheline %lu already used; duplicate allocation!\n",
  95. cacheline);
  96. }
  97. intel_timeline_unpin(tl);
  98. intel_timeline_put(tl);
  99. return err;
  100. }
  101. idx = state->count++ % state->max;
  102. __mock_hwsp_record(state, idx, tl);
  103. }
  104. if (flags & SHUFFLE)
  105. i915_prandom_shuffle(state->history,
  106. sizeof(*state->history),
  107. min(state->count, state->max),
  108. &state->prng);
  109. count = i915_prandom_u32_max_state(min(state->count, state->max),
  110. &state->prng);
  111. while (count--) {
  112. idx = --state->count % state->max;
  113. __mock_hwsp_record(state, idx, NULL);
  114. }
  115. return 0;
  116. }
  117. static int mock_hwsp_freelist(void *arg)
  118. {
  119. struct mock_hwsp_freelist state;
  120. struct drm_i915_private *i915;
  121. const struct {
  122. const char *name;
  123. unsigned int flags;
  124. } phases[] = {
  125. { "linear", 0 },
  126. { "shuffled", SHUFFLE },
  127. { },
  128. }, *p;
  129. unsigned int na;
  130. int err = 0;
  131. i915 = mock_gem_device();
  132. if (!i915)
  133. return -ENOMEM;
  134. INIT_RADIX_TREE(&state.cachelines, GFP_KERNEL);
  135. state.prng = I915_RND_STATE_INITIALIZER(i915_selftest.random_seed);
  136. state.gt = to_gt(i915);
  137. /*
  138. * Create a bunch of timelines and check that their HWSP do not overlap.
  139. * Free some, and try again.
  140. */
  141. state.max = PAGE_SIZE / sizeof(*state.history);
  142. state.count = 0;
  143. state.history = kzalloc_objs(*state.history, state.max);
  144. if (!state.history) {
  145. err = -ENOMEM;
  146. goto err_put;
  147. }
  148. for (p = phases; p->name; p++) {
  149. pr_debug("%s(%s)\n", __func__, p->name);
  150. for_each_prime_number_from(na, 1, 2 * CACHELINES_PER_PAGE) {
  151. err = __mock_hwsp_timeline(&state, na, p->flags);
  152. if (err)
  153. goto out;
  154. }
  155. }
  156. out:
  157. for (na = 0; na < state.max; na++)
  158. __mock_hwsp_record(&state, na, NULL);
  159. kfree(state.history);
  160. err_put:
  161. mock_destroy_device(i915);
  162. return err;
  163. }
  164. struct __igt_sync {
  165. const char *name;
  166. u32 seqno;
  167. bool expected;
  168. bool set;
  169. };
  170. static int __igt_sync(struct intel_timeline *tl,
  171. u64 ctx,
  172. const struct __igt_sync *p,
  173. const char *name)
  174. {
  175. int ret;
  176. if (__intel_timeline_sync_is_later(tl, ctx, p->seqno) != p->expected) {
  177. pr_err("%s: %s(ctx=%llu, seqno=%u) expected passed %s but failed\n",
  178. name, p->name, ctx, p->seqno, str_yes_no(p->expected));
  179. return -EINVAL;
  180. }
  181. if (p->set) {
  182. ret = __intel_timeline_sync_set(tl, ctx, p->seqno);
  183. if (ret)
  184. return ret;
  185. }
  186. return 0;
  187. }
  188. static int igt_sync(void *arg)
  189. {
  190. const struct __igt_sync pass[] = {
  191. { "unset", 0, false, false },
  192. { "new", 0, false, true },
  193. { "0a", 0, true, true },
  194. { "1a", 1, false, true },
  195. { "1b", 1, true, true },
  196. { "0b", 0, true, false },
  197. { "2a", 2, false, true },
  198. { "4", 4, false, true },
  199. { "INT_MAX", INT_MAX, false, true },
  200. { "INT_MAX-1", INT_MAX-1, true, false },
  201. { "INT_MAX+1", (u32)INT_MAX+1, false, true },
  202. { "INT_MAX", INT_MAX, true, false },
  203. { "UINT_MAX", UINT_MAX, false, true },
  204. { "wrap", 0, false, true },
  205. { "unwrap", UINT_MAX, true, false },
  206. {},
  207. }, *p;
  208. struct intel_timeline tl;
  209. int order, offset;
  210. int ret = -ENODEV;
  211. mock_timeline_init(&tl, 0);
  212. for (p = pass; p->name; p++) {
  213. for (order = 1; order < 64; order++) {
  214. for (offset = -1; offset <= (order > 1); offset++) {
  215. u64 ctx = BIT_ULL(order) + offset;
  216. ret = __igt_sync(&tl, ctx, p, "1");
  217. if (ret)
  218. goto out;
  219. }
  220. }
  221. }
  222. mock_timeline_fini(&tl);
  223. mock_timeline_init(&tl, 0);
  224. for (order = 1; order < 64; order++) {
  225. for (offset = -1; offset <= (order > 1); offset++) {
  226. u64 ctx = BIT_ULL(order) + offset;
  227. for (p = pass; p->name; p++) {
  228. ret = __igt_sync(&tl, ctx, p, "2");
  229. if (ret)
  230. goto out;
  231. }
  232. }
  233. }
  234. out:
  235. mock_timeline_fini(&tl);
  236. return ret;
  237. }
  238. static unsigned int random_engine(struct rnd_state *rnd)
  239. {
  240. return i915_prandom_u32_max_state(I915_NUM_ENGINES, rnd);
  241. }
  242. static int bench_sync(void *arg)
  243. {
  244. struct rnd_state prng;
  245. struct intel_timeline tl;
  246. unsigned long end_time, count;
  247. u64 prng32_1M;
  248. ktime_t kt;
  249. int order, last_order;
  250. mock_timeline_init(&tl, 0);
  251. /* Lookups from cache are very fast and so the random number generation
  252. * and the loop itself becomes a significant factor in the per-iteration
  253. * timings. We try to compensate the results by measuring the overhead
  254. * of the prng and subtract it from the reported results.
  255. */
  256. prandom_seed_state(&prng, i915_selftest.random_seed);
  257. count = 0;
  258. kt = ktime_get();
  259. end_time = jiffies + HZ/10;
  260. do {
  261. u32 x;
  262. /* Make sure the compiler doesn't optimise away the prng call */
  263. WRITE_ONCE(x, prandom_u32_state(&prng));
  264. count++;
  265. } while (!time_after(jiffies, end_time));
  266. kt = ktime_sub(ktime_get(), kt);
  267. pr_debug("%s: %lu random evaluations, %lluns/prng\n",
  268. __func__, count, (long long)div64_ul(ktime_to_ns(kt), count));
  269. prng32_1M = div64_ul(ktime_to_ns(kt) << 20, count);
  270. /* Benchmark (only) setting random context ids */
  271. prandom_seed_state(&prng, i915_selftest.random_seed);
  272. count = 0;
  273. kt = ktime_get();
  274. end_time = jiffies + HZ/10;
  275. do {
  276. u64 id = i915_prandom_u64_state(&prng);
  277. __intel_timeline_sync_set(&tl, id, 0);
  278. count++;
  279. } while (!time_after(jiffies, end_time));
  280. kt = ktime_sub(ktime_get(), kt);
  281. kt = ktime_sub_ns(kt, (count * prng32_1M * 2) >> 20);
  282. pr_info("%s: %lu random insertions, %lluns/insert\n",
  283. __func__, count, (long long)div64_ul(ktime_to_ns(kt), count));
  284. /* Benchmark looking up the exact same context ids as we just set */
  285. prandom_seed_state(&prng, i915_selftest.random_seed);
  286. end_time = count;
  287. kt = ktime_get();
  288. while (end_time--) {
  289. u64 id = i915_prandom_u64_state(&prng);
  290. if (!__intel_timeline_sync_is_later(&tl, id, 0)) {
  291. mock_timeline_fini(&tl);
  292. pr_err("Lookup of %llu failed\n", id);
  293. return -EINVAL;
  294. }
  295. }
  296. kt = ktime_sub(ktime_get(), kt);
  297. kt = ktime_sub_ns(kt, (count * prng32_1M * 2) >> 20);
  298. pr_info("%s: %lu random lookups, %lluns/lookup\n",
  299. __func__, count, (long long)div64_ul(ktime_to_ns(kt), count));
  300. mock_timeline_fini(&tl);
  301. cond_resched();
  302. mock_timeline_init(&tl, 0);
  303. /* Benchmark setting the first N (in order) contexts */
  304. count = 0;
  305. kt = ktime_get();
  306. end_time = jiffies + HZ/10;
  307. do {
  308. __intel_timeline_sync_set(&tl, count++, 0);
  309. } while (!time_after(jiffies, end_time));
  310. kt = ktime_sub(ktime_get(), kt);
  311. pr_info("%s: %lu in-order insertions, %lluns/insert\n",
  312. __func__, count, (long long)div64_ul(ktime_to_ns(kt), count));
  313. /* Benchmark looking up the exact same context ids as we just set */
  314. end_time = count;
  315. kt = ktime_get();
  316. while (end_time--) {
  317. if (!__intel_timeline_sync_is_later(&tl, end_time, 0)) {
  318. pr_err("Lookup of %lu failed\n", end_time);
  319. mock_timeline_fini(&tl);
  320. return -EINVAL;
  321. }
  322. }
  323. kt = ktime_sub(ktime_get(), kt);
  324. pr_info("%s: %lu in-order lookups, %lluns/lookup\n",
  325. __func__, count, (long long)div64_ul(ktime_to_ns(kt), count));
  326. mock_timeline_fini(&tl);
  327. cond_resched();
  328. mock_timeline_init(&tl, 0);
  329. /* Benchmark searching for a random context id and maybe changing it */
  330. prandom_seed_state(&prng, i915_selftest.random_seed);
  331. count = 0;
  332. kt = ktime_get();
  333. end_time = jiffies + HZ/10;
  334. do {
  335. u32 id = random_engine(&prng);
  336. u32 seqno = prandom_u32_state(&prng);
  337. if (!__intel_timeline_sync_is_later(&tl, id, seqno))
  338. __intel_timeline_sync_set(&tl, id, seqno);
  339. count++;
  340. } while (!time_after(jiffies, end_time));
  341. kt = ktime_sub(ktime_get(), kt);
  342. kt = ktime_sub_ns(kt, (count * prng32_1M * 2) >> 20);
  343. pr_info("%s: %lu repeated insert/lookups, %lluns/op\n",
  344. __func__, count, (long long)div64_ul(ktime_to_ns(kt), count));
  345. mock_timeline_fini(&tl);
  346. cond_resched();
  347. /* Benchmark searching for a known context id and changing the seqno */
  348. for (last_order = 1, order = 1; order < 32;
  349. ({ int tmp = last_order; last_order = order; order += tmp; })) {
  350. unsigned int mask = BIT(order) - 1;
  351. mock_timeline_init(&tl, 0);
  352. count = 0;
  353. kt = ktime_get();
  354. end_time = jiffies + HZ/10;
  355. do {
  356. /* Without assuming too many details of the underlying
  357. * implementation, try to identify its phase-changes
  358. * (if any)!
  359. */
  360. u64 id = (u64)(count & mask) << order;
  361. __intel_timeline_sync_is_later(&tl, id, 0);
  362. __intel_timeline_sync_set(&tl, id, 0);
  363. count++;
  364. } while (!time_after(jiffies, end_time));
  365. kt = ktime_sub(ktime_get(), kt);
  366. pr_info("%s: %lu cyclic/%d insert/lookups, %lluns/op\n",
  367. __func__, count, order,
  368. (long long)div64_ul(ktime_to_ns(kt), count));
  369. mock_timeline_fini(&tl);
  370. cond_resched();
  371. }
  372. return 0;
  373. }
  374. int intel_timeline_mock_selftests(void)
  375. {
  376. static const struct i915_subtest tests[] = {
  377. SUBTEST(mock_hwsp_freelist),
  378. SUBTEST(igt_sync),
  379. SUBTEST(bench_sync),
  380. };
  381. return i915_subtests(tests, NULL);
  382. }
  383. static int emit_ggtt_store_dw(struct i915_request *rq, u32 addr, u32 value)
  384. {
  385. u32 *cs;
  386. cs = intel_ring_begin(rq, 4);
  387. if (IS_ERR(cs))
  388. return PTR_ERR(cs);
  389. if (GRAPHICS_VER(rq->i915) >= 8) {
  390. *cs++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT;
  391. *cs++ = addr;
  392. *cs++ = 0;
  393. *cs++ = value;
  394. } else if (GRAPHICS_VER(rq->i915) >= 4) {
  395. *cs++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT;
  396. *cs++ = 0;
  397. *cs++ = addr;
  398. *cs++ = value;
  399. } else {
  400. *cs++ = MI_STORE_DWORD_IMM | MI_MEM_VIRTUAL;
  401. *cs++ = addr;
  402. *cs++ = value;
  403. *cs++ = MI_NOOP;
  404. }
  405. intel_ring_advance(rq, cs);
  406. return 0;
  407. }
  408. static struct i915_request *
  409. checked_tl_write(struct intel_timeline *tl, struct intel_engine_cs *engine, u32 value)
  410. {
  411. struct i915_request *rq;
  412. int err;
  413. err = selftest_tl_pin(tl);
  414. if (err) {
  415. rq = ERR_PTR(err);
  416. goto out;
  417. }
  418. if (READ_ONCE(*tl->hwsp_seqno) != tl->seqno) {
  419. pr_err("Timeline created with incorrect breadcrumb, found %x, expected %x\n",
  420. *tl->hwsp_seqno, tl->seqno);
  421. intel_timeline_unpin(tl);
  422. return ERR_PTR(-EINVAL);
  423. }
  424. rq = intel_engine_create_kernel_request(engine);
  425. if (IS_ERR(rq))
  426. goto out_unpin;
  427. i915_request_get(rq);
  428. err = emit_ggtt_store_dw(rq, tl->hwsp_offset, value);
  429. i915_request_add(rq);
  430. if (err) {
  431. i915_request_put(rq);
  432. rq = ERR_PTR(err);
  433. }
  434. out_unpin:
  435. intel_timeline_unpin(tl);
  436. out:
  437. if (IS_ERR(rq))
  438. pr_err("Failed to write to timeline!\n");
  439. return rq;
  440. }
  441. static int live_hwsp_engine(void *arg)
  442. {
  443. #define NUM_TIMELINES 4096
  444. struct intel_gt *gt = arg;
  445. struct intel_timeline **timelines;
  446. struct intel_engine_cs *engine;
  447. enum intel_engine_id id;
  448. unsigned long count, n;
  449. int err = 0;
  450. /*
  451. * Create a bunch of timelines and check we can write
  452. * independently to each of their breadcrumb slots.
  453. */
  454. timelines = kvmalloc_objs(*timelines, NUM_TIMELINES * I915_NUM_ENGINES);
  455. if (!timelines)
  456. return -ENOMEM;
  457. count = 0;
  458. for_each_engine(engine, gt, id) {
  459. if (!intel_engine_can_store_dword(engine))
  460. continue;
  461. intel_engine_pm_get(engine);
  462. for (n = 0; n < NUM_TIMELINES; n++) {
  463. struct intel_timeline *tl;
  464. struct i915_request *rq;
  465. tl = intel_timeline_create(gt);
  466. if (IS_ERR(tl)) {
  467. err = PTR_ERR(tl);
  468. break;
  469. }
  470. rq = checked_tl_write(tl, engine, count);
  471. if (IS_ERR(rq)) {
  472. intel_timeline_put(tl);
  473. err = PTR_ERR(rq);
  474. break;
  475. }
  476. timelines[count++] = tl;
  477. i915_request_put(rq);
  478. }
  479. intel_engine_pm_put(engine);
  480. if (err)
  481. break;
  482. }
  483. if (igt_flush_test(gt->i915))
  484. err = -EIO;
  485. for (n = 0; n < count; n++) {
  486. struct intel_timeline *tl = timelines[n];
  487. if (!err && READ_ONCE(*tl->hwsp_seqno) != n) {
  488. GEM_TRACE_ERR("Invalid seqno:%lu stored in timeline %llu @ %x, found 0x%x\n",
  489. n, tl->fence_context, tl->hwsp_offset, *tl->hwsp_seqno);
  490. GEM_TRACE_DUMP();
  491. err = -EINVAL;
  492. }
  493. intel_timeline_put(tl);
  494. }
  495. kvfree(timelines);
  496. return err;
  497. #undef NUM_TIMELINES
  498. }
  499. static int live_hwsp_alternate(void *arg)
  500. {
  501. #define NUM_TIMELINES 4096
  502. struct intel_gt *gt = arg;
  503. struct intel_timeline **timelines;
  504. struct intel_engine_cs *engine;
  505. enum intel_engine_id id;
  506. unsigned long count, n;
  507. int err = 0;
  508. /*
  509. * Create a bunch of timelines and check we can write
  510. * independently to each of their breadcrumb slots with adjacent
  511. * engines.
  512. */
  513. timelines = kvmalloc_objs(*timelines, NUM_TIMELINES * I915_NUM_ENGINES);
  514. if (!timelines)
  515. return -ENOMEM;
  516. count = 0;
  517. for (n = 0; n < NUM_TIMELINES; n++) {
  518. for_each_engine(engine, gt, id) {
  519. struct intel_timeline *tl;
  520. struct i915_request *rq;
  521. if (!intel_engine_can_store_dword(engine))
  522. continue;
  523. tl = intel_timeline_create(gt);
  524. if (IS_ERR(tl)) {
  525. err = PTR_ERR(tl);
  526. goto out;
  527. }
  528. intel_engine_pm_get(engine);
  529. rq = checked_tl_write(tl, engine, count);
  530. intel_engine_pm_put(engine);
  531. if (IS_ERR(rq)) {
  532. intel_timeline_put(tl);
  533. err = PTR_ERR(rq);
  534. goto out;
  535. }
  536. timelines[count++] = tl;
  537. i915_request_put(rq);
  538. }
  539. }
  540. out:
  541. if (igt_flush_test(gt->i915))
  542. err = -EIO;
  543. for (n = 0; n < count; n++) {
  544. struct intel_timeline *tl = timelines[n];
  545. if (!err && READ_ONCE(*tl->hwsp_seqno) != n) {
  546. GEM_TRACE_ERR("Invalid seqno:%lu stored in timeline %llu @ %x, found 0x%x\n",
  547. n, tl->fence_context, tl->hwsp_offset, *tl->hwsp_seqno);
  548. GEM_TRACE_DUMP();
  549. err = -EINVAL;
  550. }
  551. intel_timeline_put(tl);
  552. }
  553. kvfree(timelines);
  554. return err;
  555. #undef NUM_TIMELINES
  556. }
  557. static int live_hwsp_wrap(void *arg)
  558. {
  559. struct intel_gt *gt = arg;
  560. struct intel_engine_cs *engine;
  561. struct intel_timeline *tl;
  562. enum intel_engine_id id;
  563. int err = 0;
  564. /*
  565. * Across a seqno wrap, we need to keep the old cacheline alive for
  566. * foreign GPU references.
  567. */
  568. tl = intel_timeline_create(gt);
  569. if (IS_ERR(tl))
  570. return PTR_ERR(tl);
  571. if (!tl->has_initial_breadcrumb)
  572. goto out_free;
  573. err = selftest_tl_pin(tl);
  574. if (err)
  575. goto out_free;
  576. for_each_engine(engine, gt, id) {
  577. const u32 *hwsp_seqno[2];
  578. struct i915_request *rq;
  579. u32 seqno[2];
  580. if (!intel_engine_can_store_dword(engine))
  581. continue;
  582. rq = intel_engine_create_kernel_request(engine);
  583. if (IS_ERR(rq)) {
  584. err = PTR_ERR(rq);
  585. goto out;
  586. }
  587. tl->seqno = -4u;
  588. mutex_lock_nested(&tl->mutex, SINGLE_DEPTH_NESTING);
  589. err = intel_timeline_get_seqno(tl, rq, &seqno[0]);
  590. mutex_unlock(&tl->mutex);
  591. if (err) {
  592. i915_request_add(rq);
  593. goto out;
  594. }
  595. pr_debug("seqno[0]:%08x, hwsp_offset:%08x\n",
  596. seqno[0], tl->hwsp_offset);
  597. err = emit_ggtt_store_dw(rq, tl->hwsp_offset, seqno[0]);
  598. if (err) {
  599. i915_request_add(rq);
  600. goto out;
  601. }
  602. hwsp_seqno[0] = tl->hwsp_seqno;
  603. mutex_lock_nested(&tl->mutex, SINGLE_DEPTH_NESTING);
  604. err = intel_timeline_get_seqno(tl, rq, &seqno[1]);
  605. mutex_unlock(&tl->mutex);
  606. if (err) {
  607. i915_request_add(rq);
  608. goto out;
  609. }
  610. pr_debug("seqno[1]:%08x, hwsp_offset:%08x\n",
  611. seqno[1], tl->hwsp_offset);
  612. err = emit_ggtt_store_dw(rq, tl->hwsp_offset, seqno[1]);
  613. if (err) {
  614. i915_request_add(rq);
  615. goto out;
  616. }
  617. hwsp_seqno[1] = tl->hwsp_seqno;
  618. /* With wrap should come a new hwsp */
  619. GEM_BUG_ON(seqno[1] >= seqno[0]);
  620. GEM_BUG_ON(hwsp_seqno[0] == hwsp_seqno[1]);
  621. i915_request_add(rq);
  622. if (i915_request_wait(rq, 0, HZ / 5) < 0) {
  623. pr_err("Wait for timeline writes timed out!\n");
  624. err = -EIO;
  625. goto out;
  626. }
  627. if (READ_ONCE(*hwsp_seqno[0]) != seqno[0] ||
  628. READ_ONCE(*hwsp_seqno[1]) != seqno[1]) {
  629. pr_err("Bad timeline values: found (%x, %x), expected (%x, %x)\n",
  630. *hwsp_seqno[0], *hwsp_seqno[1],
  631. seqno[0], seqno[1]);
  632. err = -EINVAL;
  633. goto out;
  634. }
  635. intel_gt_retire_requests(gt); /* recycle HWSP */
  636. }
  637. out:
  638. if (igt_flush_test(gt->i915))
  639. err = -EIO;
  640. intel_timeline_unpin(tl);
  641. out_free:
  642. intel_timeline_put(tl);
  643. return err;
  644. }
  645. static int emit_read_hwsp(struct i915_request *rq,
  646. u32 seqno, u32 hwsp,
  647. u32 *addr)
  648. {
  649. const u32 gpr = i915_mmio_reg_offset(GEN8_RING_CS_GPR(rq->engine->mmio_base, 0));
  650. u32 *cs;
  651. cs = intel_ring_begin(rq, 12);
  652. if (IS_ERR(cs))
  653. return PTR_ERR(cs);
  654. *cs++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT;
  655. *cs++ = *addr;
  656. *cs++ = 0;
  657. *cs++ = seqno;
  658. *addr += 4;
  659. *cs++ = MI_LOAD_REGISTER_MEM_GEN8 | MI_USE_GGTT;
  660. *cs++ = gpr;
  661. *cs++ = hwsp;
  662. *cs++ = 0;
  663. *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
  664. *cs++ = gpr;
  665. *cs++ = *addr;
  666. *cs++ = 0;
  667. *addr += 4;
  668. intel_ring_advance(rq, cs);
  669. return 0;
  670. }
  671. struct hwsp_watcher {
  672. struct i915_vma *vma;
  673. struct i915_request *rq;
  674. u32 addr;
  675. u32 *map;
  676. };
  677. static bool cmp_lt(u32 a, u32 b)
  678. {
  679. return a < b;
  680. }
  681. static bool cmp_gte(u32 a, u32 b)
  682. {
  683. return a >= b;
  684. }
  685. static int setup_watcher(struct hwsp_watcher *w, struct intel_gt *gt,
  686. struct intel_timeline *tl)
  687. {
  688. struct drm_i915_gem_object *obj;
  689. struct i915_vma *vma;
  690. obj = i915_gem_object_create_internal(gt->i915, SZ_2M);
  691. if (IS_ERR(obj))
  692. return PTR_ERR(obj);
  693. /* keep the same cache settings as timeline */
  694. i915_gem_object_set_pat_index(obj, tl->hwsp_ggtt->obj->pat_index);
  695. w->map = i915_gem_object_pin_map_unlocked(obj,
  696. page_unmask_bits(tl->hwsp_ggtt->obj->mm.mapping));
  697. if (IS_ERR(w->map)) {
  698. i915_gem_object_put(obj);
  699. return PTR_ERR(w->map);
  700. }
  701. vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, 0);
  702. if (IS_ERR(vma)) {
  703. i915_gem_object_put(obj);
  704. return PTR_ERR(vma);
  705. }
  706. w->vma = vma;
  707. w->addr = i915_ggtt_offset(vma);
  708. return 0;
  709. }
  710. static void switch_tl_lock(struct i915_request *from, struct i915_request *to)
  711. {
  712. /* some light mutex juggling required; think co-routines */
  713. if (from) {
  714. lockdep_unpin_lock(&from->context->timeline->mutex, from->cookie);
  715. mutex_unlock(&from->context->timeline->mutex);
  716. }
  717. if (to) {
  718. mutex_lock(&to->context->timeline->mutex);
  719. to->cookie = lockdep_pin_lock(&to->context->timeline->mutex);
  720. }
  721. }
  722. static int create_watcher(struct hwsp_watcher *w,
  723. struct intel_engine_cs *engine,
  724. int ringsz)
  725. {
  726. struct intel_context *ce;
  727. ce = intel_context_create(engine);
  728. if (IS_ERR(ce))
  729. return PTR_ERR(ce);
  730. ce->ring_size = ringsz;
  731. w->rq = intel_context_create_request(ce);
  732. intel_context_put(ce);
  733. if (IS_ERR(w->rq))
  734. return PTR_ERR(w->rq);
  735. w->addr = i915_ggtt_offset(w->vma);
  736. switch_tl_lock(w->rq, NULL);
  737. return 0;
  738. }
  739. static int check_watcher(struct hwsp_watcher *w, const char *name,
  740. bool (*op)(u32 hwsp, u32 seqno))
  741. {
  742. struct i915_request *rq = fetch_and_zero(&w->rq);
  743. u32 offset, end;
  744. int err;
  745. GEM_BUG_ON(w->addr - i915_ggtt_offset(w->vma) > w->vma->size);
  746. i915_request_get(rq);
  747. switch_tl_lock(NULL, rq);
  748. i915_request_add(rq);
  749. if (i915_request_wait(rq, 0, HZ) < 0) {
  750. err = -ETIME;
  751. goto out;
  752. }
  753. err = 0;
  754. offset = 0;
  755. end = (w->addr - i915_ggtt_offset(w->vma)) / sizeof(*w->map);
  756. while (offset < end) {
  757. if (!op(w->map[offset + 1], w->map[offset])) {
  758. pr_err("Watcher '%s' found HWSP value %x for seqno %x\n",
  759. name, w->map[offset + 1], w->map[offset]);
  760. err = -EINVAL;
  761. }
  762. offset += 2;
  763. }
  764. out:
  765. i915_request_put(rq);
  766. return err;
  767. }
  768. static void cleanup_watcher(struct hwsp_watcher *w)
  769. {
  770. if (w->rq) {
  771. switch_tl_lock(NULL, w->rq);
  772. i915_request_add(w->rq);
  773. }
  774. i915_vma_unpin_and_release(&w->vma, I915_VMA_RELEASE_MAP);
  775. }
  776. static bool retire_requests(struct intel_timeline *tl)
  777. {
  778. struct i915_request *rq, *rn;
  779. mutex_lock(&tl->mutex);
  780. list_for_each_entry_safe(rq, rn, &tl->requests, link)
  781. if (!i915_request_retire(rq))
  782. break;
  783. mutex_unlock(&tl->mutex);
  784. return !i915_active_fence_isset(&tl->last_request);
  785. }
  786. static struct i915_request *wrap_timeline(struct i915_request *rq)
  787. {
  788. struct intel_context *ce = rq->context;
  789. struct intel_timeline *tl = ce->timeline;
  790. u32 seqno = rq->fence.seqno;
  791. while (tl->seqno >= seqno) { /* Cause a wrap */
  792. i915_request_put(rq);
  793. rq = intel_context_create_request(ce);
  794. if (IS_ERR(rq))
  795. return rq;
  796. i915_request_get(rq);
  797. i915_request_add(rq);
  798. }
  799. i915_request_put(rq);
  800. rq = i915_request_create(ce);
  801. if (IS_ERR(rq))
  802. return rq;
  803. i915_request_get(rq);
  804. i915_request_add(rq);
  805. return rq;
  806. }
  807. static int live_hwsp_read(void *arg)
  808. {
  809. struct intel_gt *gt = arg;
  810. struct hwsp_watcher watcher[2] = {};
  811. struct intel_engine_cs *engine;
  812. struct intel_timeline *tl;
  813. enum intel_engine_id id;
  814. int err = 0;
  815. int i;
  816. /*
  817. * If we take a reference to the HWSP for reading on the GPU, that
  818. * read may be arbitrarily delayed (either by foreign fence or
  819. * priority saturation) and a wrap can happen within 30 minutes.
  820. * When the GPU read is finally submitted it should be correct,
  821. * even across multiple wraps.
  822. */
  823. if (GRAPHICS_VER(gt->i915) < 8) /* CS convenience [SRM/LRM] */
  824. return 0;
  825. tl = intel_timeline_create(gt);
  826. if (IS_ERR(tl))
  827. return PTR_ERR(tl);
  828. if (!tl->has_initial_breadcrumb)
  829. goto out_free;
  830. selftest_tl_pin(tl);
  831. for (i = 0; i < ARRAY_SIZE(watcher); i++) {
  832. err = setup_watcher(&watcher[i], gt, tl);
  833. if (err)
  834. goto out;
  835. }
  836. for_each_engine(engine, gt, id) {
  837. struct intel_context *ce;
  838. unsigned long count = 0;
  839. IGT_TIMEOUT(end_time);
  840. /* Create a request we can use for remote reading of the HWSP */
  841. err = create_watcher(&watcher[1], engine, SZ_512K);
  842. if (err)
  843. goto out;
  844. do {
  845. struct i915_sw_fence *submit;
  846. struct i915_request *rq;
  847. u32 hwsp, dummy;
  848. submit = heap_fence_create(GFP_KERNEL);
  849. if (!submit) {
  850. err = -ENOMEM;
  851. goto out;
  852. }
  853. err = create_watcher(&watcher[0], engine, SZ_4K);
  854. if (err)
  855. goto out;
  856. ce = intel_context_create(engine);
  857. if (IS_ERR(ce)) {
  858. err = PTR_ERR(ce);
  859. goto out;
  860. }
  861. ce->timeline = intel_timeline_get(tl);
  862. /* Ensure timeline is mapped, done during first pin */
  863. err = intel_context_pin(ce);
  864. if (err) {
  865. intel_context_put(ce);
  866. goto out;
  867. }
  868. /*
  869. * Start at a new wrap, and set seqno right before another wrap,
  870. * saving 30 minutes of nops
  871. */
  872. tl->seqno = -12u + 2 * (count & 3);
  873. __intel_timeline_get_seqno(tl, &dummy);
  874. rq = i915_request_create(ce);
  875. if (IS_ERR(rq)) {
  876. err = PTR_ERR(rq);
  877. intel_context_unpin(ce);
  878. intel_context_put(ce);
  879. goto out;
  880. }
  881. err = i915_sw_fence_await_dma_fence(&rq->submit,
  882. &watcher[0].rq->fence, 0,
  883. GFP_KERNEL);
  884. if (err < 0) {
  885. i915_request_add(rq);
  886. intel_context_unpin(ce);
  887. intel_context_put(ce);
  888. goto out;
  889. }
  890. switch_tl_lock(rq, watcher[0].rq);
  891. err = intel_timeline_read_hwsp(rq, watcher[0].rq, &hwsp);
  892. if (err == 0)
  893. err = emit_read_hwsp(watcher[0].rq, /* before */
  894. rq->fence.seqno, hwsp,
  895. &watcher[0].addr);
  896. switch_tl_lock(watcher[0].rq, rq);
  897. if (err) {
  898. i915_request_add(rq);
  899. intel_context_unpin(ce);
  900. intel_context_put(ce);
  901. goto out;
  902. }
  903. switch_tl_lock(rq, watcher[1].rq);
  904. err = intel_timeline_read_hwsp(rq, watcher[1].rq, &hwsp);
  905. if (err == 0)
  906. err = emit_read_hwsp(watcher[1].rq, /* after */
  907. rq->fence.seqno, hwsp,
  908. &watcher[1].addr);
  909. switch_tl_lock(watcher[1].rq, rq);
  910. if (err) {
  911. i915_request_add(rq);
  912. intel_context_unpin(ce);
  913. intel_context_put(ce);
  914. goto out;
  915. }
  916. i915_request_get(rq);
  917. i915_request_add(rq);
  918. rq = wrap_timeline(rq);
  919. intel_context_unpin(ce);
  920. intel_context_put(ce);
  921. if (IS_ERR(rq)) {
  922. err = PTR_ERR(rq);
  923. goto out;
  924. }
  925. err = i915_sw_fence_await_dma_fence(&watcher[1].rq->submit,
  926. &rq->fence, 0,
  927. GFP_KERNEL);
  928. if (err < 0) {
  929. i915_request_put(rq);
  930. goto out;
  931. }
  932. err = check_watcher(&watcher[0], "before", cmp_lt);
  933. i915_sw_fence_commit(submit);
  934. heap_fence_put(submit);
  935. if (err) {
  936. i915_request_put(rq);
  937. goto out;
  938. }
  939. count++;
  940. /* Flush the timeline before manually wrapping again */
  941. if (i915_request_wait(rq,
  942. I915_WAIT_INTERRUPTIBLE,
  943. HZ) < 0) {
  944. err = -ETIME;
  945. i915_request_put(rq);
  946. goto out;
  947. }
  948. retire_requests(tl);
  949. i915_request_put(rq);
  950. /* Single requests are limited to half a ring at most */
  951. if (8 * watcher[1].rq->ring->emit >
  952. 3 * watcher[1].rq->ring->size)
  953. break;
  954. } while (!__igt_timeout(end_time, NULL) &&
  955. count < (PAGE_SIZE / TIMELINE_SEQNO_BYTES - 1) / 2);
  956. pr_info("%s: simulated %lu wraps\n", engine->name, count);
  957. err = check_watcher(&watcher[1], "after", cmp_gte);
  958. if (err)
  959. goto out;
  960. }
  961. out:
  962. for (i = 0; i < ARRAY_SIZE(watcher); i++)
  963. cleanup_watcher(&watcher[i]);
  964. intel_timeline_unpin(tl);
  965. if (igt_flush_test(gt->i915))
  966. err = -EIO;
  967. out_free:
  968. intel_timeline_put(tl);
  969. return err;
  970. }
  971. static int live_hwsp_rollover_kernel(void *arg)
  972. {
  973. struct intel_gt *gt = arg;
  974. struct intel_engine_cs *engine;
  975. enum intel_engine_id id;
  976. int err = 0;
  977. /*
  978. * Run the host for long enough, and even the kernel context will
  979. * see a seqno rollover.
  980. */
  981. for_each_engine(engine, gt, id) {
  982. struct intel_context *ce = engine->kernel_context;
  983. struct intel_timeline *tl = ce->timeline;
  984. struct i915_request *rq[3] = {};
  985. int i;
  986. st_engine_heartbeat_disable(engine);
  987. if (intel_gt_wait_for_idle(gt, HZ / 2)) {
  988. err = -EIO;
  989. goto out;
  990. }
  991. GEM_BUG_ON(i915_active_fence_isset(&tl->last_request));
  992. tl->seqno = -2u;
  993. WRITE_ONCE(*(u32 *)tl->hwsp_seqno, tl->seqno);
  994. for (i = 0; i < ARRAY_SIZE(rq); i++) {
  995. struct i915_request *this;
  996. this = i915_request_create(ce);
  997. if (IS_ERR(this)) {
  998. err = PTR_ERR(this);
  999. goto out;
  1000. }
  1001. pr_debug("%s: create fence.seqnp:%d\n",
  1002. engine->name,
  1003. lower_32_bits(this->fence.seqno));
  1004. GEM_BUG_ON(rcu_access_pointer(this->timeline) != tl);
  1005. rq[i] = i915_request_get(this);
  1006. i915_request_add(this);
  1007. }
  1008. /* We expected a wrap! */
  1009. GEM_BUG_ON(rq[2]->fence.seqno > rq[0]->fence.seqno);
  1010. if (i915_request_wait(rq[2], 0, HZ / 5) < 0) {
  1011. pr_err("Wait for timeline wrap timed out!\n");
  1012. err = -EIO;
  1013. goto out;
  1014. }
  1015. for (i = 0; i < ARRAY_SIZE(rq); i++) {
  1016. if (!i915_request_completed(rq[i])) {
  1017. pr_err("Pre-wrap request not completed!\n");
  1018. err = -EINVAL;
  1019. goto out;
  1020. }
  1021. }
  1022. out:
  1023. for (i = 0; i < ARRAY_SIZE(rq); i++)
  1024. i915_request_put(rq[i]);
  1025. st_engine_heartbeat_enable(engine);
  1026. if (err)
  1027. break;
  1028. }
  1029. if (igt_flush_test(gt->i915))
  1030. err = -EIO;
  1031. return err;
  1032. }
  1033. static int live_hwsp_rollover_user(void *arg)
  1034. {
  1035. struct intel_gt *gt = arg;
  1036. struct intel_engine_cs *engine;
  1037. enum intel_engine_id id;
  1038. int err = 0;
  1039. /*
  1040. * Simulate a long running user context, and force the seqno wrap
  1041. * on the user's timeline.
  1042. */
  1043. for_each_engine(engine, gt, id) {
  1044. struct i915_request *rq[3] = {};
  1045. struct intel_timeline *tl;
  1046. struct intel_context *ce;
  1047. int i;
  1048. ce = intel_context_create(engine);
  1049. if (IS_ERR(ce))
  1050. return PTR_ERR(ce);
  1051. err = intel_context_alloc_state(ce);
  1052. if (err)
  1053. goto out;
  1054. tl = ce->timeline;
  1055. if (!tl->has_initial_breadcrumb)
  1056. goto out;
  1057. err = intel_context_pin(ce);
  1058. if (err)
  1059. goto out;
  1060. tl->seqno = -4u;
  1061. WRITE_ONCE(*(u32 *)tl->hwsp_seqno, tl->seqno);
  1062. for (i = 0; i < ARRAY_SIZE(rq); i++) {
  1063. struct i915_request *this;
  1064. this = intel_context_create_request(ce);
  1065. if (IS_ERR(this)) {
  1066. err = PTR_ERR(this);
  1067. goto out_unpin;
  1068. }
  1069. pr_debug("%s: create fence.seqnp:%d\n",
  1070. engine->name,
  1071. lower_32_bits(this->fence.seqno));
  1072. GEM_BUG_ON(rcu_access_pointer(this->timeline) != tl);
  1073. rq[i] = i915_request_get(this);
  1074. i915_request_add(this);
  1075. }
  1076. /* We expected a wrap! */
  1077. GEM_BUG_ON(rq[2]->fence.seqno > rq[0]->fence.seqno);
  1078. if (i915_request_wait(rq[2], 0, HZ / 5) < 0) {
  1079. pr_err("Wait for timeline wrap timed out!\n");
  1080. err = -EIO;
  1081. goto out_unpin;
  1082. }
  1083. for (i = 0; i < ARRAY_SIZE(rq); i++) {
  1084. if (!i915_request_completed(rq[i])) {
  1085. pr_err("Pre-wrap request not completed!\n");
  1086. err = -EINVAL;
  1087. goto out_unpin;
  1088. }
  1089. }
  1090. out_unpin:
  1091. intel_context_unpin(ce);
  1092. out:
  1093. for (i = 0; i < ARRAY_SIZE(rq); i++)
  1094. i915_request_put(rq[i]);
  1095. intel_context_put(ce);
  1096. if (err)
  1097. break;
  1098. }
  1099. if (igt_flush_test(gt->i915))
  1100. err = -EIO;
  1101. return err;
  1102. }
  1103. static int live_hwsp_recycle(void *arg)
  1104. {
  1105. struct intel_gt *gt = arg;
  1106. struct intel_engine_cs *engine;
  1107. enum intel_engine_id id;
  1108. unsigned long count;
  1109. int err = 0;
  1110. /*
  1111. * Check seqno writes into one timeline at a time. We expect to
  1112. * recycle the breadcrumb slot between iterations and neither
  1113. * want to confuse ourselves or the GPU.
  1114. */
  1115. count = 0;
  1116. for_each_engine(engine, gt, id) {
  1117. IGT_TIMEOUT(end_time);
  1118. if (!intel_engine_can_store_dword(engine))
  1119. continue;
  1120. intel_engine_pm_get(engine);
  1121. do {
  1122. struct intel_timeline *tl;
  1123. struct i915_request *rq;
  1124. tl = intel_timeline_create(gt);
  1125. if (IS_ERR(tl)) {
  1126. err = PTR_ERR(tl);
  1127. break;
  1128. }
  1129. rq = checked_tl_write(tl, engine, count);
  1130. if (IS_ERR(rq)) {
  1131. intel_timeline_put(tl);
  1132. err = PTR_ERR(rq);
  1133. break;
  1134. }
  1135. if (i915_request_wait(rq, 0, HZ / 5) < 0) {
  1136. pr_err("Wait for timeline writes timed out!\n");
  1137. i915_request_put(rq);
  1138. intel_timeline_put(tl);
  1139. err = -EIO;
  1140. break;
  1141. }
  1142. if (READ_ONCE(*tl->hwsp_seqno) != count) {
  1143. GEM_TRACE_ERR("Invalid seqno:%lu stored in timeline %llu @ %x found 0x%x\n",
  1144. count, tl->fence_context,
  1145. tl->hwsp_offset, *tl->hwsp_seqno);
  1146. GEM_TRACE_DUMP();
  1147. err = -EINVAL;
  1148. }
  1149. i915_request_put(rq);
  1150. intel_timeline_put(tl);
  1151. count++;
  1152. if (err)
  1153. break;
  1154. } while (!__igt_timeout(end_time, NULL));
  1155. intel_engine_pm_put(engine);
  1156. if (err)
  1157. break;
  1158. }
  1159. return err;
  1160. }
  1161. int intel_timeline_live_selftests(struct drm_i915_private *i915)
  1162. {
  1163. static const struct i915_subtest tests[] = {
  1164. SUBTEST(live_hwsp_recycle),
  1165. SUBTEST(live_hwsp_engine),
  1166. SUBTEST(live_hwsp_alternate),
  1167. SUBTEST(live_hwsp_wrap),
  1168. SUBTEST(live_hwsp_read),
  1169. SUBTEST(live_hwsp_rollover_kernel),
  1170. SUBTEST(live_hwsp_rollover_user),
  1171. };
  1172. if (intel_gt_is_wedged(to_gt(i915)))
  1173. return 0;
  1174. return intel_gt_live_subtests(tests, to_gt(i915));
  1175. }