.. | .. |
---|
24 | 24 | |
---|
25 | 25 | #include <linux/prime_numbers.h> |
---|
26 | 26 | |
---|
27 | | -#include "../i915_selftest.h" |
---|
| 27 | +#include "gem/i915_gem_context.h" |
---|
| 28 | +#include "gem/selftests/mock_context.h" |
---|
| 29 | + |
---|
| 30 | +#include "i915_scatterlist.h" |
---|
| 31 | +#include "i915_selftest.h" |
---|
28 | 32 | |
---|
29 | 33 | #include "mock_gem_device.h" |
---|
30 | | -#include "mock_context.h" |
---|
| 34 | +#include "mock_gtt.h" |
---|
31 | 35 | |
---|
32 | 36 | static bool assert_vma(struct i915_vma *vma, |
---|
33 | 37 | struct drm_i915_gem_object *obj, |
---|
.. | .. |
---|
35 | 39 | { |
---|
36 | 40 | bool ok = true; |
---|
37 | 41 | |
---|
38 | | - if (vma->vm != &ctx->ppgtt->vm) { |
---|
| 42 | + if (vma->vm != rcu_access_pointer(ctx->vm)) { |
---|
39 | 43 | pr_err("VMA created with wrong VM\n"); |
---|
40 | 44 | ok = false; |
---|
41 | 45 | } |
---|
.. | .. |
---|
58 | 62 | static struct i915_vma * |
---|
59 | 63 | checked_vma_instance(struct drm_i915_gem_object *obj, |
---|
60 | 64 | struct i915_address_space *vm, |
---|
61 | | - struct i915_ggtt_view *view) |
---|
| 65 | + const struct i915_ggtt_view *view) |
---|
62 | 66 | { |
---|
63 | 67 | struct i915_vma *vma; |
---|
64 | 68 | bool ok = true; |
---|
.. | .. |
---|
110 | 114 | list_for_each_entry(obj, objects, st_link) { |
---|
111 | 115 | for (pinned = 0; pinned <= 1; pinned++) { |
---|
112 | 116 | list_for_each_entry(ctx, contexts, link) { |
---|
113 | | - struct i915_address_space *vm = &ctx->ppgtt->vm; |
---|
| 117 | + struct i915_address_space *vm; |
---|
114 | 118 | struct i915_vma *vma; |
---|
115 | 119 | int err; |
---|
116 | 120 | |
---|
| 121 | + vm = i915_gem_context_get_vm_rcu(ctx); |
---|
117 | 122 | vma = checked_vma_instance(obj, vm, NULL); |
---|
| 123 | + i915_vm_put(vm); |
---|
118 | 124 | if (IS_ERR(vma)) |
---|
119 | 125 | return PTR_ERR(vma); |
---|
120 | 126 | |
---|
.. | .. |
---|
141 | 147 | |
---|
142 | 148 | static int igt_vma_create(void *arg) |
---|
143 | 149 | { |
---|
144 | | - struct drm_i915_private *i915 = arg; |
---|
| 150 | + struct i915_ggtt *ggtt = arg; |
---|
| 151 | + struct drm_i915_private *i915 = ggtt->vm.i915; |
---|
145 | 152 | struct drm_i915_gem_object *obj, *on; |
---|
146 | 153 | struct i915_gem_context *ctx, *cn; |
---|
147 | 154 | unsigned long num_obj, num_ctx; |
---|
.. | .. |
---|
166 | 173 | } |
---|
167 | 174 | |
---|
168 | 175 | nc = 0; |
---|
169 | | - for_each_prime_number(num_ctx, MAX_CONTEXT_HW_ID) { |
---|
| 176 | + for_each_prime_number(num_ctx, 2 * BITS_PER_LONG) { |
---|
170 | 177 | for (; nc < num_ctx; nc++) { |
---|
171 | 178 | ctx = mock_context(i915, "mock"); |
---|
172 | 179 | if (!ctx) |
---|
.. | .. |
---|
189 | 196 | list_del_init(&ctx->link); |
---|
190 | 197 | mock_context_close(ctx); |
---|
191 | 198 | } |
---|
| 199 | + |
---|
| 200 | + cond_resched(); |
---|
192 | 201 | } |
---|
193 | 202 | |
---|
194 | 203 | end: |
---|
.. | .. |
---|
245 | 254 | |
---|
246 | 255 | static int igt_vma_pin1(void *arg) |
---|
247 | 256 | { |
---|
248 | | - struct drm_i915_private *i915 = arg; |
---|
| 257 | + struct i915_ggtt *ggtt = arg; |
---|
249 | 258 | const struct pin_mode modes[] = { |
---|
250 | 259 | #define VALID(sz, fl) { .size = (sz), .flags = (fl), .assert = assert_pin_valid, .string = #sz ", " #fl ", (valid) " } |
---|
251 | 260 | #define __INVALID(sz, fl, check, eval) { .size = (sz), .flags = (fl), .assert = (check), .string = #sz ", " #fl ", (invalid " #eval ")" } |
---|
.. | .. |
---|
256 | 265 | |
---|
257 | 266 | VALID(0, PIN_GLOBAL | PIN_OFFSET_BIAS | 4096), |
---|
258 | 267 | VALID(0, PIN_GLOBAL | PIN_OFFSET_BIAS | 8192), |
---|
259 | | - VALID(0, PIN_GLOBAL | PIN_OFFSET_BIAS | (i915->ggtt.mappable_end - 4096)), |
---|
260 | | - VALID(0, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_BIAS | (i915->ggtt.mappable_end - 4096)), |
---|
261 | | - VALID(0, PIN_GLOBAL | PIN_OFFSET_BIAS | (i915->ggtt.vm.total - 4096)), |
---|
| 268 | + VALID(0, PIN_GLOBAL | PIN_OFFSET_BIAS | (ggtt->mappable_end - 4096)), |
---|
| 269 | + VALID(0, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_BIAS | (ggtt->mappable_end - 4096)), |
---|
| 270 | + VALID(0, PIN_GLOBAL | PIN_OFFSET_BIAS | (ggtt->vm.total - 4096)), |
---|
262 | 271 | |
---|
263 | | - VALID(0, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_FIXED | (i915->ggtt.mappable_end - 4096)), |
---|
264 | | - INVALID(0, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_FIXED | i915->ggtt.mappable_end), |
---|
265 | | - VALID(0, PIN_GLOBAL | PIN_OFFSET_FIXED | (i915->ggtt.vm.total - 4096)), |
---|
266 | | - INVALID(0, PIN_GLOBAL | PIN_OFFSET_FIXED | i915->ggtt.vm.total), |
---|
| 272 | + VALID(0, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_FIXED | (ggtt->mappable_end - 4096)), |
---|
| 273 | + INVALID(0, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_FIXED | ggtt->mappable_end), |
---|
| 274 | + VALID(0, PIN_GLOBAL | PIN_OFFSET_FIXED | (ggtt->vm.total - 4096)), |
---|
| 275 | + INVALID(0, PIN_GLOBAL | PIN_OFFSET_FIXED | ggtt->vm.total), |
---|
267 | 276 | INVALID(0, PIN_GLOBAL | PIN_OFFSET_FIXED | round_down(U64_MAX, PAGE_SIZE)), |
---|
268 | 277 | |
---|
269 | 278 | VALID(4096, PIN_GLOBAL), |
---|
270 | 279 | VALID(8192, PIN_GLOBAL), |
---|
271 | | - VALID(i915->ggtt.mappable_end - 4096, PIN_GLOBAL | PIN_MAPPABLE), |
---|
272 | | - VALID(i915->ggtt.mappable_end, PIN_GLOBAL | PIN_MAPPABLE), |
---|
273 | | - NOSPACE(i915->ggtt.mappable_end + 4096, PIN_GLOBAL | PIN_MAPPABLE), |
---|
274 | | - VALID(i915->ggtt.vm.total - 4096, PIN_GLOBAL), |
---|
275 | | - VALID(i915->ggtt.vm.total, PIN_GLOBAL), |
---|
276 | | - NOSPACE(i915->ggtt.vm.total + 4096, PIN_GLOBAL), |
---|
| 280 | + VALID(ggtt->mappable_end - 4096, PIN_GLOBAL | PIN_MAPPABLE), |
---|
| 281 | + VALID(ggtt->mappable_end, PIN_GLOBAL | PIN_MAPPABLE), |
---|
| 282 | + NOSPACE(ggtt->mappable_end + 4096, PIN_GLOBAL | PIN_MAPPABLE), |
---|
| 283 | + VALID(ggtt->vm.total - 4096, PIN_GLOBAL), |
---|
| 284 | + VALID(ggtt->vm.total, PIN_GLOBAL), |
---|
| 285 | + NOSPACE(ggtt->vm.total + 4096, PIN_GLOBAL), |
---|
277 | 286 | NOSPACE(round_down(U64_MAX, PAGE_SIZE), PIN_GLOBAL), |
---|
278 | | - INVALID(8192, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_FIXED | (i915->ggtt.mappable_end - 4096)), |
---|
279 | | - INVALID(8192, PIN_GLOBAL | PIN_OFFSET_FIXED | (i915->ggtt.vm.total - 4096)), |
---|
| 287 | + INVALID(8192, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_FIXED | (ggtt->mappable_end - 4096)), |
---|
| 288 | + INVALID(8192, PIN_GLOBAL | PIN_OFFSET_FIXED | (ggtt->vm.total - 4096)), |
---|
280 | 289 | INVALID(8192, PIN_GLOBAL | PIN_OFFSET_FIXED | (round_down(U64_MAX, PAGE_SIZE) - 4096)), |
---|
281 | 290 | |
---|
282 | | - VALID(8192, PIN_GLOBAL | PIN_OFFSET_BIAS | (i915->ggtt.mappable_end - 4096)), |
---|
| 291 | + VALID(8192, PIN_GLOBAL | PIN_OFFSET_BIAS | (ggtt->mappable_end - 4096)), |
---|
283 | 292 | |
---|
284 | 293 | #if !IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) |
---|
285 | 294 | /* Misusing BIAS is a programming error (it is not controllable |
---|
.. | .. |
---|
287 | 296 | * However, the tests are still quite interesting for checking |
---|
288 | 297 | * variable start, end and size. |
---|
289 | 298 | */ |
---|
290 | | - NOSPACE(0, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_BIAS | i915->ggtt.mappable_end), |
---|
291 | | - NOSPACE(0, PIN_GLOBAL | PIN_OFFSET_BIAS | i915->ggtt.vm.total), |
---|
292 | | - NOSPACE(8192, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_BIAS | (i915->ggtt.mappable_end - 4096)), |
---|
293 | | - NOSPACE(8192, PIN_GLOBAL | PIN_OFFSET_BIAS | (i915->ggtt.vm.total - 4096)), |
---|
| 299 | + NOSPACE(0, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_BIAS | ggtt->mappable_end), |
---|
| 300 | + NOSPACE(0, PIN_GLOBAL | PIN_OFFSET_BIAS | ggtt->vm.total), |
---|
| 301 | + NOSPACE(8192, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_BIAS | (ggtt->mappable_end - 4096)), |
---|
| 302 | + NOSPACE(8192, PIN_GLOBAL | PIN_OFFSET_BIAS | (ggtt->vm.total - 4096)), |
---|
294 | 303 | #endif |
---|
295 | 304 | { }, |
---|
296 | 305 | #undef NOSPACE |
---|
.. | .. |
---|
306 | 315 | * focusing on error handling of boundary conditions. |
---|
307 | 316 | */ |
---|
308 | 317 | |
---|
309 | | - GEM_BUG_ON(!drm_mm_clean(&i915->ggtt.vm.mm)); |
---|
| 318 | + GEM_BUG_ON(!drm_mm_clean(&ggtt->vm.mm)); |
---|
310 | 319 | |
---|
311 | | - obj = i915_gem_object_create_internal(i915, PAGE_SIZE); |
---|
| 320 | + obj = i915_gem_object_create_internal(ggtt->vm.i915, PAGE_SIZE); |
---|
312 | 321 | if (IS_ERR(obj)) |
---|
313 | 322 | return PTR_ERR(obj); |
---|
314 | 323 | |
---|
315 | | - vma = checked_vma_instance(obj, &i915->ggtt.vm, NULL); |
---|
| 324 | + vma = checked_vma_instance(obj, &ggtt->vm, NULL); |
---|
316 | 325 | if (IS_ERR(vma)) |
---|
317 | 326 | goto out; |
---|
318 | 327 | |
---|
.. | .. |
---|
337 | 346 | goto out; |
---|
338 | 347 | } |
---|
339 | 348 | } |
---|
| 349 | + |
---|
| 350 | + cond_resched(); |
---|
340 | 351 | } |
---|
341 | 352 | |
---|
342 | 353 | err = 0; |
---|
.. | .. |
---|
395 | 406 | return sg; |
---|
396 | 407 | } |
---|
397 | 408 | |
---|
398 | | -static unsigned int rotated_size(const struct intel_rotation_plane_info *a, |
---|
399 | | - const struct intel_rotation_plane_info *b) |
---|
| 409 | +static unsigned long remapped_index(const struct intel_remapped_info *r, |
---|
| 410 | + unsigned int n, |
---|
| 411 | + unsigned int x, |
---|
| 412 | + unsigned int y) |
---|
| 413 | +{ |
---|
| 414 | + return (r->plane[n].stride * y + |
---|
| 415 | + r->plane[n].offset + x); |
---|
| 416 | +} |
---|
| 417 | + |
---|
| 418 | +static struct scatterlist * |
---|
| 419 | +assert_remapped(struct drm_i915_gem_object *obj, |
---|
| 420 | + const struct intel_remapped_info *r, unsigned int n, |
---|
| 421 | + struct scatterlist *sg) |
---|
| 422 | +{ |
---|
| 423 | + unsigned int x, y; |
---|
| 424 | + unsigned int left = 0; |
---|
| 425 | + unsigned int offset; |
---|
| 426 | + |
---|
| 427 | + for (y = 0; y < r->plane[n].height; y++) { |
---|
| 428 | + for (x = 0; x < r->plane[n].width; x++) { |
---|
| 429 | + unsigned long src_idx; |
---|
| 430 | + dma_addr_t src; |
---|
| 431 | + |
---|
| 432 | + if (!sg) { |
---|
| 433 | + pr_err("Invalid sg table: too short at plane %d, (%d, %d)!\n", |
---|
| 434 | + n, x, y); |
---|
| 435 | + return ERR_PTR(-EINVAL); |
---|
| 436 | + } |
---|
| 437 | + if (!left) { |
---|
| 438 | + offset = 0; |
---|
| 439 | + left = sg_dma_len(sg); |
---|
| 440 | + } |
---|
| 441 | + |
---|
| 442 | + src_idx = remapped_index(r, n, x, y); |
---|
| 443 | + src = i915_gem_object_get_dma_address(obj, src_idx); |
---|
| 444 | + |
---|
| 445 | + if (left < PAGE_SIZE || left & (PAGE_SIZE-1)) { |
---|
| 446 | + pr_err("Invalid sg.length, found %d, expected %lu for remapped page (%d, %d) [src index %lu]\n", |
---|
| 447 | + sg_dma_len(sg), PAGE_SIZE, |
---|
| 448 | + x, y, src_idx); |
---|
| 449 | + return ERR_PTR(-EINVAL); |
---|
| 450 | + } |
---|
| 451 | + |
---|
| 452 | + if (sg_dma_address(sg) + offset != src) { |
---|
| 453 | + pr_err("Invalid address for remapped page (%d, %d) [src index %lu]\n", |
---|
| 454 | + x, y, src_idx); |
---|
| 455 | + return ERR_PTR(-EINVAL); |
---|
| 456 | + } |
---|
| 457 | + |
---|
| 458 | + left -= PAGE_SIZE; |
---|
| 459 | + offset += PAGE_SIZE; |
---|
| 460 | + |
---|
| 461 | + |
---|
| 462 | + if (!left) |
---|
| 463 | + sg = sg_next(sg); |
---|
| 464 | + } |
---|
| 465 | + } |
---|
| 466 | + |
---|
| 467 | + return sg; |
---|
| 468 | +} |
---|
| 469 | + |
---|
| 470 | +static unsigned int rotated_size(const struct intel_remapped_plane_info *a, |
---|
| 471 | + const struct intel_remapped_plane_info *b) |
---|
400 | 472 | { |
---|
401 | 473 | return a->width * a->height + b->width * b->height; |
---|
402 | 474 | } |
---|
403 | 475 | |
---|
404 | | -static int igt_vma_rotate(void *arg) |
---|
| 476 | +static int igt_vma_rotate_remap(void *arg) |
---|
405 | 477 | { |
---|
406 | | - struct drm_i915_private *i915 = arg; |
---|
407 | | - struct i915_address_space *vm = &i915->ggtt.vm; |
---|
| 478 | + struct i915_ggtt *ggtt = arg; |
---|
| 479 | + struct i915_address_space *vm = &ggtt->vm; |
---|
408 | 480 | struct drm_i915_gem_object *obj; |
---|
409 | | - const struct intel_rotation_plane_info planes[] = { |
---|
| 481 | + const struct intel_remapped_plane_info planes[] = { |
---|
410 | 482 | { .width = 1, .height = 1, .stride = 1 }, |
---|
411 | 483 | { .width = 2, .height = 2, .stride = 2 }, |
---|
412 | 484 | { .width = 4, .height = 4, .stride = 4 }, |
---|
.. | .. |
---|
424 | 496 | { .width = 6, .height = 4, .stride = 6 }, |
---|
425 | 497 | { } |
---|
426 | 498 | }, *a, *b; |
---|
| 499 | + enum i915_ggtt_view_type types[] = { |
---|
| 500 | + I915_GGTT_VIEW_ROTATED, |
---|
| 501 | + I915_GGTT_VIEW_REMAPPED, |
---|
| 502 | + 0, |
---|
| 503 | + }, *t; |
---|
427 | 504 | const unsigned int max_pages = 64; |
---|
428 | 505 | int err = -ENOMEM; |
---|
429 | 506 | |
---|
.. | .. |
---|
431 | 508 | * that the page layout within the rotated VMA match our expectations. |
---|
432 | 509 | */ |
---|
433 | 510 | |
---|
434 | | - obj = i915_gem_object_create_internal(i915, max_pages * PAGE_SIZE); |
---|
| 511 | + obj = i915_gem_object_create_internal(vm->i915, max_pages * PAGE_SIZE); |
---|
435 | 512 | if (IS_ERR(obj)) |
---|
436 | 513 | goto out; |
---|
437 | 514 | |
---|
| 515 | + for (t = types; *t; t++) { |
---|
438 | 516 | for (a = planes; a->width; a++) { |
---|
439 | 517 | for (b = planes + ARRAY_SIZE(planes); b-- != planes; ) { |
---|
440 | 518 | struct i915_ggtt_view view; |
---|
.. | .. |
---|
445 | 523 | GEM_BUG_ON(max_offset > max_pages); |
---|
446 | 524 | max_offset = max_pages - max_offset; |
---|
447 | 525 | |
---|
448 | | - view.type = I915_GGTT_VIEW_ROTATED; |
---|
| 526 | + view.type = *t; |
---|
449 | 527 | view.rotated.plane[0] = *a; |
---|
450 | 528 | view.rotated.plane[1] = *b; |
---|
451 | 529 | |
---|
.. | .. |
---|
466 | 544 | goto out_object; |
---|
467 | 545 | } |
---|
468 | 546 | |
---|
469 | | - if (vma->size != rotated_size(a, b) * PAGE_SIZE) { |
---|
| 547 | + if (view.type == I915_GGTT_VIEW_ROTATED && |
---|
| 548 | + vma->size != rotated_size(a, b) * PAGE_SIZE) { |
---|
470 | 549 | pr_err("VMA is wrong size, expected %lu, found %llu\n", |
---|
471 | 550 | PAGE_SIZE * rotated_size(a, b), vma->size); |
---|
472 | 551 | err = -EINVAL; |
---|
473 | 552 | goto out_object; |
---|
474 | 553 | } |
---|
475 | 554 | |
---|
476 | | - if (vma->pages->nents != rotated_size(a, b)) { |
---|
| 555 | + if (view.type == I915_GGTT_VIEW_REMAPPED && |
---|
| 556 | + vma->size > rotated_size(a, b) * PAGE_SIZE) { |
---|
| 557 | + pr_err("VMA is wrong size, expected %lu, found %llu\n", |
---|
| 558 | + PAGE_SIZE * rotated_size(a, b), vma->size); |
---|
| 559 | + err = -EINVAL; |
---|
| 560 | + goto out_object; |
---|
| 561 | + } |
---|
| 562 | + |
---|
| 563 | + if (vma->pages->nents > rotated_size(a, b)) { |
---|
477 | 564 | pr_err("sg table is wrong sizeo, expected %u, found %u nents\n", |
---|
478 | 565 | rotated_size(a, b), vma->pages->nents); |
---|
479 | 566 | err = -EINVAL; |
---|
.. | .. |
---|
495 | 582 | |
---|
496 | 583 | sg = vma->pages->sgl; |
---|
497 | 584 | for (n = 0; n < ARRAY_SIZE(view.rotated.plane); n++) { |
---|
498 | | - sg = assert_rotated(obj, &view.rotated, n, sg); |
---|
| 585 | + if (view.type == I915_GGTT_VIEW_ROTATED) |
---|
| 586 | + sg = assert_rotated(obj, &view.rotated, n, sg); |
---|
| 587 | + else |
---|
| 588 | + sg = assert_remapped(obj, &view.remapped, n, sg); |
---|
499 | 589 | if (IS_ERR(sg)) { |
---|
500 | | - pr_err("Inconsistent VMA pages for plane %d: [(%d, %d, %d, %d), (%d, %d, %d, %d)]\n", n, |
---|
| 590 | + pr_err("Inconsistent %s VMA pages for plane %d: [(%d, %d, %d, %d), (%d, %d, %d, %d)]\n", |
---|
| 591 | + view.type == I915_GGTT_VIEW_ROTATED ? |
---|
| 592 | + "rotated" : "remapped", n, |
---|
501 | 593 | view.rotated.plane[0].width, |
---|
502 | 594 | view.rotated.plane[0].height, |
---|
503 | 595 | view.rotated.plane[0].stride, |
---|
.. | .. |
---|
512 | 604 | } |
---|
513 | 605 | |
---|
514 | 606 | i915_vma_unpin(vma); |
---|
| 607 | + |
---|
| 608 | + cond_resched(); |
---|
515 | 609 | } |
---|
516 | 610 | } |
---|
517 | 611 | } |
---|
| 612 | + } |
---|
518 | 613 | } |
---|
519 | 614 | |
---|
520 | 615 | out_object: |
---|
.. | .. |
---|
531 | 626 | struct sgt_iter sgt; |
---|
532 | 627 | dma_addr_t dma; |
---|
533 | 628 | |
---|
534 | | - for_each_sgt_dma(dma, sgt, vma->pages) { |
---|
| 629 | + for_each_sgt_daddr(dma, sgt, vma->pages) { |
---|
535 | 630 | dma_addr_t src; |
---|
536 | 631 | |
---|
537 | 632 | if (!size) { |
---|
.. | .. |
---|
602 | 697 | |
---|
603 | 698 | static int igt_vma_partial(void *arg) |
---|
604 | 699 | { |
---|
605 | | - struct drm_i915_private *i915 = arg; |
---|
606 | | - struct i915_address_space *vm = &i915->ggtt.vm; |
---|
| 700 | + struct i915_ggtt *ggtt = arg; |
---|
| 701 | + struct i915_address_space *vm = &ggtt->vm; |
---|
607 | 702 | const unsigned int npages = 1021; /* prime! */ |
---|
608 | 703 | struct drm_i915_gem_object *obj; |
---|
609 | 704 | const struct phase { |
---|
.. | .. |
---|
621 | 716 | * we are returned the same VMA when we later request the same range. |
---|
622 | 717 | */ |
---|
623 | 718 | |
---|
624 | | - obj = i915_gem_object_create_internal(i915, npages*PAGE_SIZE); |
---|
| 719 | + obj = i915_gem_object_create_internal(vm->i915, npages * PAGE_SIZE); |
---|
625 | 720 | if (IS_ERR(obj)) |
---|
626 | 721 | goto out; |
---|
627 | 722 | |
---|
.. | .. |
---|
666 | 761 | |
---|
667 | 762 | i915_vma_unpin(vma); |
---|
668 | 763 | nvma++; |
---|
| 764 | + |
---|
| 765 | + cond_resched(); |
---|
669 | 766 | } |
---|
670 | 767 | } |
---|
671 | 768 | |
---|
672 | 769 | count = 0; |
---|
673 | | - list_for_each_entry(vma, &obj->vma_list, obj_link) |
---|
| 770 | + list_for_each_entry(vma, &obj->vma.list, obj_link) |
---|
674 | 771 | count++; |
---|
675 | 772 | if (count != nvma) { |
---|
676 | 773 | pr_err("(%s) All partial vma were not recorded on the obj->vma_list: found %u, expected %u\n", |
---|
.. | .. |
---|
699 | 796 | i915_vma_unpin(vma); |
---|
700 | 797 | |
---|
701 | 798 | count = 0; |
---|
702 | | - list_for_each_entry(vma, &obj->vma_list, obj_link) |
---|
| 799 | + list_for_each_entry(vma, &obj->vma.list, obj_link) |
---|
703 | 800 | count++; |
---|
704 | 801 | if (count != nvma) { |
---|
705 | 802 | pr_err("(%s) allocated an extra full vma!\n", p->name); |
---|
.. | .. |
---|
719 | 816 | static const struct i915_subtest tests[] = { |
---|
720 | 817 | SUBTEST(igt_vma_create), |
---|
721 | 818 | SUBTEST(igt_vma_pin1), |
---|
722 | | - SUBTEST(igt_vma_rotate), |
---|
| 819 | + SUBTEST(igt_vma_rotate_remap), |
---|
723 | 820 | SUBTEST(igt_vma_partial), |
---|
724 | 821 | }; |
---|
725 | 822 | struct drm_i915_private *i915; |
---|
| 823 | + struct i915_ggtt *ggtt; |
---|
726 | 824 | int err; |
---|
727 | 825 | |
---|
728 | 826 | i915 = mock_gem_device(); |
---|
729 | 827 | if (!i915) |
---|
730 | 828 | return -ENOMEM; |
---|
731 | 829 | |
---|
732 | | - mutex_lock(&i915->drm.struct_mutex); |
---|
733 | | - err = i915_subtests(tests, i915); |
---|
734 | | - mutex_unlock(&i915->drm.struct_mutex); |
---|
| 830 | + ggtt = kmalloc(sizeof(*ggtt), GFP_KERNEL); |
---|
| 831 | + if (!ggtt) { |
---|
| 832 | + err = -ENOMEM; |
---|
| 833 | + goto out_put; |
---|
| 834 | + } |
---|
| 835 | + mock_init_ggtt(i915, ggtt); |
---|
735 | 836 | |
---|
736 | | - drm_dev_put(&i915->drm); |
---|
| 837 | + err = i915_subtests(tests, ggtt); |
---|
| 838 | + |
---|
| 839 | + mock_device_flush(i915); |
---|
| 840 | + i915_gem_drain_freed_objects(i915); |
---|
| 841 | + mock_fini_ggtt(ggtt); |
---|
| 842 | + kfree(ggtt); |
---|
| 843 | +out_put: |
---|
| 844 | + mock_destroy_device(i915); |
---|
737 | 845 | return err; |
---|
738 | 846 | } |
---|
739 | 847 | |
---|
| 848 | +static int igt_vma_remapped_gtt(void *arg) |
---|
| 849 | +{ |
---|
| 850 | + struct drm_i915_private *i915 = arg; |
---|
| 851 | + const struct intel_remapped_plane_info planes[] = { |
---|
| 852 | + { .width = 1, .height = 1, .stride = 1 }, |
---|
| 853 | + { .width = 2, .height = 2, .stride = 2 }, |
---|
| 854 | + { .width = 4, .height = 4, .stride = 4 }, |
---|
| 855 | + { .width = 8, .height = 8, .stride = 8 }, |
---|
| 856 | + |
---|
| 857 | + { .width = 3, .height = 5, .stride = 3 }, |
---|
| 858 | + { .width = 3, .height = 5, .stride = 4 }, |
---|
| 859 | + { .width = 3, .height = 5, .stride = 5 }, |
---|
| 860 | + |
---|
| 861 | + { .width = 5, .height = 3, .stride = 5 }, |
---|
| 862 | + { .width = 5, .height = 3, .stride = 7 }, |
---|
| 863 | + { .width = 5, .height = 3, .stride = 9 }, |
---|
| 864 | + |
---|
| 865 | + { .width = 4, .height = 6, .stride = 6 }, |
---|
| 866 | + { .width = 6, .height = 4, .stride = 6 }, |
---|
| 867 | + { } |
---|
| 868 | + }, *p; |
---|
| 869 | + enum i915_ggtt_view_type types[] = { |
---|
| 870 | + I915_GGTT_VIEW_ROTATED, |
---|
| 871 | + I915_GGTT_VIEW_REMAPPED, |
---|
| 872 | + 0, |
---|
| 873 | + }, *t; |
---|
| 874 | + struct drm_i915_gem_object *obj; |
---|
| 875 | + intel_wakeref_t wakeref; |
---|
| 876 | + int err = 0; |
---|
| 877 | + |
---|
| 878 | + obj = i915_gem_object_create_internal(i915, 10 * 10 * PAGE_SIZE); |
---|
| 879 | + if (IS_ERR(obj)) |
---|
| 880 | + return PTR_ERR(obj); |
---|
| 881 | + |
---|
| 882 | + wakeref = intel_runtime_pm_get(&i915->runtime_pm); |
---|
| 883 | + |
---|
| 884 | + for (t = types; *t; t++) { |
---|
| 885 | + for (p = planes; p->width; p++) { |
---|
| 886 | + struct i915_ggtt_view view = { |
---|
| 887 | + .type = *t, |
---|
| 888 | + .rotated.plane[0] = *p, |
---|
| 889 | + }; |
---|
| 890 | + struct i915_vma *vma; |
---|
| 891 | + u32 __iomem *map; |
---|
| 892 | + unsigned int x, y; |
---|
| 893 | + int err; |
---|
| 894 | + |
---|
| 895 | + i915_gem_object_lock(obj, NULL); |
---|
| 896 | + err = i915_gem_object_set_to_gtt_domain(obj, true); |
---|
| 897 | + i915_gem_object_unlock(obj); |
---|
| 898 | + if (err) |
---|
| 899 | + goto out; |
---|
| 900 | + |
---|
| 901 | + vma = i915_gem_object_ggtt_pin(obj, &view, 0, 0, PIN_MAPPABLE); |
---|
| 902 | + if (IS_ERR(vma)) { |
---|
| 903 | + err = PTR_ERR(vma); |
---|
| 904 | + goto out; |
---|
| 905 | + } |
---|
| 906 | + |
---|
| 907 | + GEM_BUG_ON(vma->ggtt_view.type != *t); |
---|
| 908 | + |
---|
| 909 | + map = i915_vma_pin_iomap(vma); |
---|
| 910 | + i915_vma_unpin(vma); |
---|
| 911 | + if (IS_ERR(map)) { |
---|
| 912 | + err = PTR_ERR(map); |
---|
| 913 | + goto out; |
---|
| 914 | + } |
---|
| 915 | + |
---|
| 916 | + for (y = 0 ; y < p->height; y++) { |
---|
| 917 | + for (x = 0 ; x < p->width; x++) { |
---|
| 918 | + unsigned int offset; |
---|
| 919 | + u32 val = y << 16 | x; |
---|
| 920 | + |
---|
| 921 | + if (*t == I915_GGTT_VIEW_ROTATED) |
---|
| 922 | + offset = (x * p->height + y) * PAGE_SIZE; |
---|
| 923 | + else |
---|
| 924 | + offset = (y * p->width + x) * PAGE_SIZE; |
---|
| 925 | + |
---|
| 926 | + iowrite32(val, &map[offset / sizeof(*map)]); |
---|
| 927 | + } |
---|
| 928 | + } |
---|
| 929 | + |
---|
| 930 | + i915_vma_unpin_iomap(vma); |
---|
| 931 | + |
---|
| 932 | + vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, PIN_MAPPABLE); |
---|
| 933 | + if (IS_ERR(vma)) { |
---|
| 934 | + err = PTR_ERR(vma); |
---|
| 935 | + goto out; |
---|
| 936 | + } |
---|
| 937 | + |
---|
| 938 | + GEM_BUG_ON(vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL); |
---|
| 939 | + |
---|
| 940 | + map = i915_vma_pin_iomap(vma); |
---|
| 941 | + i915_vma_unpin(vma); |
---|
| 942 | + if (IS_ERR(map)) { |
---|
| 943 | + err = PTR_ERR(map); |
---|
| 944 | + goto out; |
---|
| 945 | + } |
---|
| 946 | + |
---|
| 947 | + for (y = 0 ; y < p->height; y++) { |
---|
| 948 | + for (x = 0 ; x < p->width; x++) { |
---|
| 949 | + unsigned int offset, src_idx; |
---|
| 950 | + u32 exp = y << 16 | x; |
---|
| 951 | + u32 val; |
---|
| 952 | + |
---|
| 953 | + if (*t == I915_GGTT_VIEW_ROTATED) |
---|
| 954 | + src_idx = rotated_index(&view.rotated, 0, x, y); |
---|
| 955 | + else |
---|
| 956 | + src_idx = remapped_index(&view.remapped, 0, x, y); |
---|
| 957 | + offset = src_idx * PAGE_SIZE; |
---|
| 958 | + |
---|
| 959 | + val = ioread32(&map[offset / sizeof(*map)]); |
---|
| 960 | + if (val != exp) { |
---|
| 961 | + pr_err("%s VMA write test failed, expected 0x%x, found 0x%x\n", |
---|
| 962 | + *t == I915_GGTT_VIEW_ROTATED ? "Rotated" : "Remapped", |
---|
| 963 | + val, exp); |
---|
| 964 | + i915_vma_unpin_iomap(vma); |
---|
| 965 | + goto out; |
---|
| 966 | + } |
---|
| 967 | + } |
---|
| 968 | + } |
---|
| 969 | + i915_vma_unpin_iomap(vma); |
---|
| 970 | + |
---|
| 971 | + cond_resched(); |
---|
| 972 | + } |
---|
| 973 | + } |
---|
| 974 | + |
---|
| 975 | +out: |
---|
| 976 | + intel_runtime_pm_put(&i915->runtime_pm, wakeref); |
---|
| 977 | + i915_gem_object_put(obj); |
---|
| 978 | + |
---|
| 979 | + return err; |
---|
| 980 | +} |
---|
| 981 | + |
---|
| 982 | +int i915_vma_live_selftests(struct drm_i915_private *i915) |
---|
| 983 | +{ |
---|
| 984 | + static const struct i915_subtest tests[] = { |
---|
| 985 | + SUBTEST(igt_vma_remapped_gtt), |
---|
| 986 | + }; |
---|
| 987 | + |
---|
| 988 | + return i915_subtests(tests, i915); |
---|
| 989 | +} |
---|