Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915: Use the vma resource as argument for gtt binding / unbinding

When introducing asynchronous unbinding, the vma itself may no longer
be alive when the actual binding or unbinding takes place.

Update the gtt i915_vma_ops accordingly to take a struct i915_vma_resource
instead of a struct i915_vma for the bind_vma() and unbind_vma() ops.
Similarly change the insert_entries() op for struct i915_address_space.

Replace a couple of i915_vma_snapshot members with their newly introduced
i915_vma_resource counterparts, since they have the same lifetime.

Also make sure to avoid changing the struct i915_vma_flags (in particular
the bind flags) async. That should now only be done sync under the
vm mutex.

v2:
- Update the vma_res::bound_flags when binding to the aliased ggtt
v6:
- Remove I915_VMA_ALLOC_BIT (Matthew Auld)
- Change some members of struct i915_vma_resource from unsigned long to u64
(Matthew Auld)
v7:
- Fix vma resource size parameters to be u64 rather than unsigned long
(Matthew Auld)

Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220110172219.107131-3-thomas.hellstrom@linux.intel.com

+314 -214
+15 -12
drivers/gpu/drm/i915/display/intel_dpt.c
··· 48 48 } 49 49 50 50 static void dpt_insert_entries(struct i915_address_space *vm, 51 - struct i915_vma *vma, 51 + struct i915_vma_resource *vma_res, 52 52 enum i915_cache_level level, 53 53 u32 flags) 54 54 { ··· 64 64 * not to allow the user to override access to a read only page. 65 65 */ 66 66 67 - i = vma->node.start / I915_GTT_PAGE_SIZE; 68 - for_each_sgt_daddr(addr, sgt_iter, vma->pages) 67 + i = vma_res->start / I915_GTT_PAGE_SIZE; 68 + for_each_sgt_daddr(addr, sgt_iter, vma_res->bi.pages) 69 69 gen8_set_pte(&base[i++], pte_encode | addr); 70 70 } 71 71 ··· 76 76 77 77 static void dpt_bind_vma(struct i915_address_space *vm, 78 78 struct i915_vm_pt_stash *stash, 79 - struct i915_vma *vma, 79 + struct i915_vma_resource *vma_res, 80 80 enum i915_cache_level cache_level, 81 81 u32 flags) 82 82 { 83 - struct drm_i915_gem_object *obj = vma->obj; 84 83 u32 pte_flags; 84 + 85 + if (vma_res->bound_flags) 86 + return; 85 87 86 88 /* Applicable to VLV (gen8+ do not support RO in the GGTT) */ 87 89 pte_flags = 0; 88 - if (vma->vm->has_read_only && i915_gem_object_is_readonly(obj)) 90 + if (vm->has_read_only && vma_res->bi.readonly) 89 91 pte_flags |= PTE_READ_ONLY; 90 - if (i915_gem_object_is_lmem(obj)) 92 + if (vma_res->bi.lmem) 91 93 pte_flags |= PTE_LM; 92 94 93 - vma->vm->insert_entries(vma->vm, vma, cache_level, pte_flags); 95 + vm->insert_entries(vm, vma_res, cache_level, pte_flags); 94 96 95 - vma->page_sizes.gtt = I915_GTT_PAGE_SIZE; 97 + vma_res->page_sizes_gtt = I915_GTT_PAGE_SIZE; 96 98 97 99 /* 98 100 * Without aliasing PPGTT there's no difference between 99 101 * GLOBAL/LOCAL_BIND, it's all the same ptes. Hence unconditionally 100 102 * upgrade to both bound if we bind either to avoid double-binding. 101 103 */ 102 - atomic_or(I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND, &vma->flags); 104 + vma_res->bound_flags = I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND; 103 105 } 104 106 105 - static void dpt_unbind_vma(struct i915_address_space *vm, struct i915_vma *vma) 107 + static void dpt_unbind_vma(struct i915_address_space *vm, 108 + struct i915_vma_resource *vma_res) 106 109 { 107 - vm->clear_range(vm, vma->node.start, vma->size); 110 + vm->clear_range(vm, vma_res->start, vma_res->vma_size); 108 111 } 109 112 110 113 static void dpt_cleanup(struct i915_address_space *vm)
+2 -25
drivers/gpu/drm/i915/gem/i915_gem_object_types.h
··· 15 15 16 16 #include "i915_active.h" 17 17 #include "i915_selftest.h" 18 + #include "i915_vma_resource.h" 18 19 19 20 struct drm_i915_gem_object; 20 21 struct intel_fronbuffer; ··· 567 566 struct sg_table *pages; 568 567 void *mapping; 569 568 570 - struct i915_page_sizes { 571 - /** 572 - * The sg mask of the pages sg_table. i.e the mask of 573 - * of the lengths for each sg entry. 574 - */ 575 - unsigned int phys; 576 - 577 - /** 578 - * The gtt page sizes we are allowed to use given the 579 - * sg mask and the supported page sizes. This will 580 - * express the smallest unit we can use for the whole 581 - * object, as well as the larger sizes we may be able 582 - * to use opportunistically. 583 - */ 584 - unsigned int sg; 585 - 586 - /** 587 - * The actual gtt page size usage. Since we can have 588 - * multiple vma associated with this object we need to 589 - * prevent any trampling of state, hence a copy of this 590 - * struct also lives in each vma, therefore the gtt 591 - * value here should only be read/write through the vma. 592 - */ 593 - unsigned int gtt; 594 - } page_sizes; 569 + struct i915_page_sizes page_sizes; 595 570 596 571 I915_SELFTEST_DECLARE(unsigned int page_mask); 597 572
+16 -21
drivers/gpu/drm/i915/gem/selftests/huge_pages.c
··· 370 370 err = -EINVAL; 371 371 } 372 372 373 - if (!HAS_PAGE_SIZES(i915, vma->page_sizes.gtt)) { 373 + if (!HAS_PAGE_SIZES(i915, vma->resource->page_sizes_gtt)) { 374 374 pr_err("unsupported page_sizes.gtt=%u, supported=%u\n", 375 - vma->page_sizes.gtt & ~supported, supported); 375 + vma->resource->page_sizes_gtt & ~supported, supported); 376 376 err = -EINVAL; 377 377 } 378 378 ··· 403 403 if (i915_gem_object_is_lmem(obj) && 404 404 IS_ALIGNED(vma->node.start, SZ_2M) && 405 405 vma->page_sizes.sg & SZ_2M && 406 - vma->page_sizes.gtt < SZ_2M) { 406 + vma->resource->page_sizes_gtt < SZ_2M) { 407 407 pr_err("gtt pages mismatch for LMEM, expected 2M GTT pages, sg(%u), gtt(%u)\n", 408 - vma->page_sizes.sg, vma->page_sizes.gtt); 409 - err = -EINVAL; 410 - } 411 - 412 - if (obj->mm.page_sizes.gtt) { 413 - pr_err("obj->page_sizes.gtt(%u) should never be set\n", 414 - obj->mm.page_sizes.gtt); 408 + vma->page_sizes.sg, vma->resource->page_sizes_gtt); 415 409 err = -EINVAL; 416 410 } 417 411 ··· 541 547 goto out_unpin; 542 548 } 543 549 544 - if (vma->page_sizes.gtt != page_size) { 550 + if (vma->resource->page_sizes_gtt != page_size) { 545 551 pr_err("%s page_sizes.gtt=%u, expected=%u\n", 546 - __func__, vma->page_sizes.gtt, 552 + __func__, vma->resource->page_sizes_gtt, 547 553 page_size); 548 554 err = -EINVAL; 549 555 goto out_unpin; ··· 624 630 625 631 err = igt_check_page_sizes(vma); 626 632 627 - if (vma->page_sizes.gtt != page_size) { 633 + if (vma->resource->page_sizes_gtt != page_size) { 628 634 pr_err("page_sizes.gtt=%u, expected %u\n", 629 - vma->page_sizes.gtt, page_size); 635 + vma->resource->page_sizes_gtt, page_size); 630 636 err = -EINVAL; 631 637 } 632 638 ··· 651 657 652 658 err = igt_check_page_sizes(vma); 653 659 654 - if (vma->page_sizes.gtt != I915_GTT_PAGE_SIZE_4K) { 660 + if (vma->resource->page_sizes_gtt != I915_GTT_PAGE_SIZE_4K) { 655 661 pr_err("page_sizes.gtt=%u, expected %llu\n", 656 - vma->page_sizes.gtt, I915_GTT_PAGE_SIZE_4K); 662 + vma->resource->page_sizes_gtt, 663 + I915_GTT_PAGE_SIZE_4K); 657 664 err = -EINVAL; 658 665 } 659 666 ··· 800 805 } 801 806 } 802 807 803 - if (vma->page_sizes.gtt != expected_gtt) { 808 + if (vma->resource->page_sizes_gtt != expected_gtt) { 804 809 pr_err("gtt=%u, expected=%u, size=%zd, single=%s\n", 805 - vma->page_sizes.gtt, expected_gtt, 810 + vma->resource->page_sizes_gtt, expected_gtt, 806 811 obj->base.size, yesno(!!single)); 807 812 err = -EINVAL; 808 813 break; ··· 956 961 } 957 962 } 958 963 959 - if (vma->page_sizes.gtt != expected_gtt) { 964 + if (vma->resource->page_sizes_gtt != expected_gtt) { 960 965 pr_err("gtt=%u, expected=%u, i=%d, single=%s\n", 961 - vma->page_sizes.gtt, expected_gtt, i, 962 - yesno(!!single)); 966 + vma->resource->page_sizes_gtt, 967 + expected_gtt, i, yesno(!!single)); 963 968 err = -EINVAL; 964 969 goto out_vma_unpin; 965 970 }
+10 -9
drivers/gpu/drm/i915/gt/gen6_ppgtt.c
··· 104 104 } 105 105 106 106 static void gen6_ppgtt_insert_entries(struct i915_address_space *vm, 107 - struct i915_vma *vma, 107 + struct i915_vma_resource *vma_res, 108 108 enum i915_cache_level cache_level, 109 109 u32 flags) 110 110 { 111 111 struct i915_ppgtt *ppgtt = i915_vm_to_ppgtt(vm); 112 112 struct i915_page_directory * const pd = ppgtt->pd; 113 - unsigned int first_entry = vma->node.start / I915_GTT_PAGE_SIZE; 113 + unsigned int first_entry = vma_res->start / I915_GTT_PAGE_SIZE; 114 114 unsigned int act_pt = first_entry / GEN6_PTES; 115 115 unsigned int act_pte = first_entry % GEN6_PTES; 116 116 const u32 pte_encode = vm->pte_encode(0, cache_level, flags); 117 - struct sgt_dma iter = sgt_dma(vma); 117 + struct sgt_dma iter = sgt_dma(vma_res); 118 118 gen6_pte_t *vaddr; 119 119 120 120 GEM_BUG_ON(!pd->entry[act_pt]); ··· 140 140 } 141 141 } while (1); 142 142 143 - vma->page_sizes.gtt = I915_GTT_PAGE_SIZE; 143 + vma_res->page_sizes_gtt = I915_GTT_PAGE_SIZE; 144 144 } 145 145 146 146 static void gen6_flush_pd(struct gen6_ppgtt *ppgtt, u64 start, u64 end) ··· 271 271 272 272 static void pd_vma_bind(struct i915_address_space *vm, 273 273 struct i915_vm_pt_stash *stash, 274 - struct i915_vma *vma, 274 + struct i915_vma_resource *vma_res, 275 275 enum i915_cache_level cache_level, 276 276 u32 unused) 277 277 { 278 278 struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm); 279 - struct gen6_ppgtt *ppgtt = vma->private; 280 - u32 ggtt_offset = i915_ggtt_offset(vma) / I915_GTT_PAGE_SIZE; 279 + struct gen6_ppgtt *ppgtt = vma_res->private; 280 + u32 ggtt_offset = vma_res->start / I915_GTT_PAGE_SIZE; 281 281 282 282 ppgtt->pp_dir = ggtt_offset * sizeof(gen6_pte_t) << 10; 283 283 ppgtt->pd_addr = (gen6_pte_t __iomem *)ggtt->gsm + ggtt_offset; ··· 285 285 gen6_flush_pd(ppgtt, 0, ppgtt->base.vm.total); 286 286 } 287 287 288 - static void pd_vma_unbind(struct i915_address_space *vm, struct i915_vma *vma) 288 + static void pd_vma_unbind(struct i915_address_space *vm, 289 + struct i915_vma_resource *vma_res) 289 290 { 290 - struct gen6_ppgtt *ppgtt = vma->private; 291 + struct gen6_ppgtt *ppgtt = vma_res->private; 291 292 struct i915_page_directory * const pd = ppgtt->base.pd; 292 293 struct i915_page_table *pt; 293 294 unsigned int pde;
+19 -18
drivers/gpu/drm/i915/gt/gen8_ppgtt.c
··· 453 453 return idx; 454 454 } 455 455 456 - static void gen8_ppgtt_insert_huge(struct i915_vma *vma, 456 + static void gen8_ppgtt_insert_huge(struct i915_address_space *vm, 457 + struct i915_vma_resource *vma_res, 457 458 struct sgt_dma *iter, 458 459 enum i915_cache_level cache_level, 459 460 u32 flags) 460 461 { 461 462 const gen8_pte_t pte_encode = gen8_pte_encode(0, cache_level, flags); 462 463 unsigned int rem = sg_dma_len(iter->sg); 463 - u64 start = vma->node.start; 464 + u64 start = vma_res->start; 464 465 465 - GEM_BUG_ON(!i915_vm_is_4lvl(vma->vm)); 466 + GEM_BUG_ON(!i915_vm_is_4lvl(vm)); 466 467 467 468 do { 468 469 struct i915_page_directory * const pdp = 469 - gen8_pdp_for_page_address(vma->vm, start); 470 + gen8_pdp_for_page_address(vm, start); 470 471 struct i915_page_directory * const pd = 471 472 i915_pd_entry(pdp, __gen8_pte_index(start, 2)); 472 473 gen8_pte_t encode = pte_encode; ··· 476 475 gen8_pte_t *vaddr; 477 476 u16 index; 478 477 479 - if (vma->page_sizes.sg & I915_GTT_PAGE_SIZE_2M && 478 + if (vma_res->bi.page_sizes.sg & I915_GTT_PAGE_SIZE_2M && 480 479 IS_ALIGNED(iter->dma, I915_GTT_PAGE_SIZE_2M) && 481 480 rem >= I915_GTT_PAGE_SIZE_2M && 482 481 !__gen8_pte_index(start, 0)) { ··· 493 492 page_size = I915_GTT_PAGE_SIZE; 494 493 495 494 if (!index && 496 - vma->page_sizes.sg & I915_GTT_PAGE_SIZE_64K && 495 + vma_res->bi.page_sizes.sg & I915_GTT_PAGE_SIZE_64K && 497 496 IS_ALIGNED(iter->dma, I915_GTT_PAGE_SIZE_64K) && 498 497 (IS_ALIGNED(rem, I915_GTT_PAGE_SIZE_64K) || 499 498 rem >= (I915_PDES - index) * I915_GTT_PAGE_SIZE)) ··· 542 541 */ 543 542 if (maybe_64K != -1 && 544 543 (index == I915_PDES || 545 - (i915_vm_has_scratch_64K(vma->vm) && 546 - !iter->sg && IS_ALIGNED(vma->node.start + 547 - vma->node.size, 544 + (i915_vm_has_scratch_64K(vm) && 545 + !iter->sg && IS_ALIGNED(vma_res->start + 546 + vma_res->node_size, 548 547 I915_GTT_PAGE_SIZE_2M)))) { 549 548 vaddr = px_vaddr(pd); 550 549 vaddr[maybe_64K] |= GEN8_PDE_IPS_64K; ··· 560 559 * instead - which we detect as missing results during 561 560 * selftests. 562 561 */ 563 - if (I915_SELFTEST_ONLY(vma->vm->scrub_64K)) { 562 + if (I915_SELFTEST_ONLY(vm->scrub_64K)) { 564 563 u16 i; 565 564 566 - encode = vma->vm->scratch[0]->encode; 565 + encode = vm->scratch[0]->encode; 567 566 vaddr = px_vaddr(i915_pt_entry(pd, maybe_64K)); 568 567 569 568 for (i = 1; i < index; i += 16) ··· 573 572 } 574 573 } 575 574 576 - vma->page_sizes.gtt |= page_size; 575 + vma_res->page_sizes_gtt |= page_size; 577 576 } while (iter->sg && sg_dma_len(iter->sg)); 578 577 } 579 578 580 579 static void gen8_ppgtt_insert(struct i915_address_space *vm, 581 - struct i915_vma *vma, 580 + struct i915_vma_resource *vma_res, 582 581 enum i915_cache_level cache_level, 583 582 u32 flags) 584 583 { 585 584 struct i915_ppgtt * const ppgtt = i915_vm_to_ppgtt(vm); 586 - struct sgt_dma iter = sgt_dma(vma); 585 + struct sgt_dma iter = sgt_dma(vma_res); 587 586 588 - if (vma->page_sizes.sg > I915_GTT_PAGE_SIZE) { 589 - gen8_ppgtt_insert_huge(vma, &iter, cache_level, flags); 587 + if (vma_res->bi.page_sizes.sg > I915_GTT_PAGE_SIZE) { 588 + gen8_ppgtt_insert_huge(vm, vma_res, &iter, cache_level, flags); 590 589 } else { 591 - u64 idx = vma->node.start >> GEN8_PTE_SHIFT; 590 + u64 idx = vma_res->start >> GEN8_PTE_SHIFT; 592 591 593 592 do { 594 593 struct i915_page_directory * const pdp = ··· 598 597 cache_level, flags); 599 598 } while (idx); 600 599 601 - vma->page_sizes.gtt = I915_GTT_PAGE_SIZE; 600 + vma_res->page_sizes_gtt = I915_GTT_PAGE_SIZE; 602 601 } 603 602 } 604 603
+2 -2
drivers/gpu/drm/i915/gt/intel_engine_cs.c
··· 1718 1718 drm_printf(m, 1719 1719 "[head %04x, postfix %04x, tail %04x, batch 0x%08x_%08x]:\n", 1720 1720 rq->head, rq->postfix, rq->tail, 1721 - vsnap ? upper_32_bits(vsnap->gtt_offset) : ~0u, 1722 - vsnap ? lower_32_bits(vsnap->gtt_offset) : ~0u); 1721 + vsnap ? upper_32_bits(vsnap->vma_resource->start) : ~0u, 1722 + vsnap ? lower_32_bits(vsnap->vma_resource->start) : ~0u); 1723 1723 1724 1724 size = rq->tail - rq->head; 1725 1725 if (rq->tail < rq->head)
+37 -33
drivers/gpu/drm/i915/gt/intel_ggtt.c
··· 218 218 } 219 219 220 220 static void gen8_ggtt_insert_entries(struct i915_address_space *vm, 221 - struct i915_vma *vma, 221 + struct i915_vma_resource *vma_res, 222 222 enum i915_cache_level level, 223 223 u32 flags) 224 224 { ··· 235 235 */ 236 236 237 237 gte = (gen8_pte_t __iomem *)ggtt->gsm; 238 - gte += vma->node.start / I915_GTT_PAGE_SIZE; 239 - end = gte + vma->node.size / I915_GTT_PAGE_SIZE; 238 + gte += vma_res->start / I915_GTT_PAGE_SIZE; 239 + end = gte + vma_res->node_size / I915_GTT_PAGE_SIZE; 240 240 241 - for_each_sgt_daddr(addr, iter, vma->pages) 241 + for_each_sgt_daddr(addr, iter, vma_res->bi.pages) 242 242 gen8_set_pte(gte++, pte_encode | addr); 243 243 GEM_BUG_ON(gte > end); 244 244 ··· 275 275 * through the GMADR mapped BAR (i915->mm.gtt->gtt). 276 276 */ 277 277 static void gen6_ggtt_insert_entries(struct i915_address_space *vm, 278 - struct i915_vma *vma, 278 + struct i915_vma_resource *vma_res, 279 279 enum i915_cache_level level, 280 280 u32 flags) 281 281 { ··· 286 286 dma_addr_t addr; 287 287 288 288 gte = (gen6_pte_t __iomem *)ggtt->gsm; 289 - gte += vma->node.start / I915_GTT_PAGE_SIZE; 290 - end = gte + vma->node.size / I915_GTT_PAGE_SIZE; 289 + gte += vma_res->start / I915_GTT_PAGE_SIZE; 290 + end = gte + vma_res->node_size / I915_GTT_PAGE_SIZE; 291 291 292 - for_each_sgt_daddr(addr, iter, vma->pages) 292 + for_each_sgt_daddr(addr, iter, vma_res->bi.pages) 293 293 iowrite32(vm->pte_encode(addr, level, flags), gte++); 294 294 GEM_BUG_ON(gte > end); 295 295 ··· 372 372 373 373 struct insert_entries { 374 374 struct i915_address_space *vm; 375 - struct i915_vma *vma; 375 + struct i915_vma_resource *vma_res; 376 376 enum i915_cache_level level; 377 377 u32 flags; 378 378 }; ··· 381 381 { 382 382 struct insert_entries *arg = _arg; 383 383 384 - gen8_ggtt_insert_entries(arg->vm, arg->vma, arg->level, arg->flags); 384 + gen8_ggtt_insert_entries(arg->vm, arg->vma_res, arg->level, arg->flags); 385 385 bxt_vtd_ggtt_wa(arg->vm); 386 386 387 387 return 0; 388 388 } 389 389 390 390 static void bxt_vtd_ggtt_insert_entries__BKL(struct i915_address_space *vm, 391 - struct i915_vma *vma, 391 + struct i915_vma_resource *vma_res, 392 392 enum i915_cache_level level, 393 393 u32 flags) 394 394 { 395 - struct insert_entries arg = { vm, vma, level, flags }; 395 + struct insert_entries arg = { vm, vma_res, level, flags }; 396 396 397 397 stop_machine(bxt_vtd_ggtt_insert_entries__cb, &arg, NULL); 398 398 } ··· 431 431 } 432 432 433 433 static void i915_ggtt_insert_entries(struct i915_address_space *vm, 434 - struct i915_vma *vma, 434 + struct i915_vma_resource *vma_res, 435 435 enum i915_cache_level cache_level, 436 436 u32 unused) 437 437 { 438 438 unsigned int flags = (cache_level == I915_CACHE_NONE) ? 439 439 AGP_USER_MEMORY : AGP_USER_CACHED_MEMORY; 440 440 441 - intel_gtt_insert_sg_entries(vma->pages, vma->node.start >> PAGE_SHIFT, 441 + intel_gtt_insert_sg_entries(vma_res->bi.pages, vma_res->start >> PAGE_SHIFT, 442 442 flags); 443 443 } 444 444 ··· 450 450 451 451 static void ggtt_bind_vma(struct i915_address_space *vm, 452 452 struct i915_vm_pt_stash *stash, 453 - struct i915_vma *vma, 453 + struct i915_vma_resource *vma_res, 454 454 enum i915_cache_level cache_level, 455 455 u32 flags) 456 456 { 457 - struct drm_i915_gem_object *obj = vma->obj; 458 457 u32 pte_flags; 459 458 460 - if (i915_vma_is_bound(vma, ~flags & I915_VMA_BIND_MASK)) 459 + if (vma_res->bound_flags & (~flags & I915_VMA_BIND_MASK)) 461 460 return; 461 + 462 + vma_res->bound_flags |= flags; 462 463 463 464 /* Applicable to VLV (gen8+ do not support RO in the GGTT) */ 464 465 pte_flags = 0; 465 - if (i915_gem_object_is_readonly(obj)) 466 + if (vma_res->bi.readonly) 466 467 pte_flags |= PTE_READ_ONLY; 467 - if (i915_gem_object_is_lmem(obj)) 468 + if (vma_res->bi.lmem) 468 469 pte_flags |= PTE_LM; 469 470 470 - vm->insert_entries(vm, vma, cache_level, pte_flags); 471 - vma->page_sizes.gtt = I915_GTT_PAGE_SIZE; 471 + vm->insert_entries(vm, vma_res, cache_level, pte_flags); 472 + vma_res->page_sizes_gtt = I915_GTT_PAGE_SIZE; 472 473 } 473 474 474 - static void ggtt_unbind_vma(struct i915_address_space *vm, struct i915_vma *vma) 475 + static void ggtt_unbind_vma(struct i915_address_space *vm, 476 + struct i915_vma_resource *vma_res) 475 477 { 476 - vm->clear_range(vm, vma->node.start, vma->size); 478 + vm->clear_range(vm, vma_res->start, vma_res->vma_size); 477 479 } 478 480 479 481 static int ggtt_reserve_guc_top(struct i915_ggtt *ggtt) ··· 608 606 609 607 static void aliasing_gtt_bind_vma(struct i915_address_space *vm, 610 608 struct i915_vm_pt_stash *stash, 611 - struct i915_vma *vma, 609 + struct i915_vma_resource *vma_res, 612 610 enum i915_cache_level cache_level, 613 611 u32 flags) 614 612 { ··· 616 614 617 615 /* Currently applicable only to VLV */ 618 616 pte_flags = 0; 619 - if (i915_gem_object_is_readonly(vma->obj)) 617 + if (vma_res->bi.readonly) 620 618 pte_flags |= PTE_READ_ONLY; 621 619 622 620 if (flags & I915_VMA_LOCAL_BIND) 623 621 ppgtt_bind_vma(&i915_vm_to_ggtt(vm)->alias->vm, 624 - stash, vma, cache_level, flags); 622 + stash, vma_res, cache_level, flags); 625 623 626 624 if (flags & I915_VMA_GLOBAL_BIND) 627 - vm->insert_entries(vm, vma, cache_level, pte_flags); 625 + vm->insert_entries(vm, vma_res, cache_level, pte_flags); 626 + 627 + vma_res->bound_flags |= flags; 628 628 } 629 629 630 630 static void aliasing_gtt_unbind_vma(struct i915_address_space *vm, 631 - struct i915_vma *vma) 631 + struct i915_vma_resource *vma_res) 632 632 { 633 - if (i915_vma_is_bound(vma, I915_VMA_GLOBAL_BIND)) 634 - vm->clear_range(vm, vma->node.start, vma->size); 633 + if (vma_res->bound_flags & I915_VMA_GLOBAL_BIND) 634 + vm->clear_range(vm, vma_res->start, vma_res->vma_size); 635 635 636 - if (i915_vma_is_bound(vma, I915_VMA_LOCAL_BIND)) 637 - ppgtt_unbind_vma(&i915_vm_to_ggtt(vm)->alias->vm, vma); 636 + if (vma_res->bound_flags & I915_VMA_LOCAL_BIND) 637 + ppgtt_unbind_vma(&i915_vm_to_ggtt(vm)->alias->vm, vma_res); 638 638 } 639 639 640 640 static int init_aliasing_ppgtt(struct i915_ggtt *ggtt) ··· 1257 1253 atomic_read(&vma->flags) & I915_VMA_BIND_MASK; 1258 1254 1259 1255 GEM_BUG_ON(!was_bound); 1260 - vma->ops->bind_vma(&ggtt->vm, NULL, vma, 1256 + vma->ops->bind_vma(&ggtt->vm, NULL, vma->resource, 1261 1257 obj ? obj->cache_level : 0, 1262 1258 was_bound); 1263 1259 if (obj) { /* only used during resume => exclusive access */
+9 -7
drivers/gpu/drm/i915/gt/intel_gtt.h
··· 27 27 28 28 #include "gt/intel_reset.h" 29 29 #include "i915_selftest.h" 30 + #include "i915_vma_resource.h" 30 31 #include "i915_vma_types.h" 31 32 32 33 #define I915_GFP_ALLOW_FAIL (GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN) ··· 201 200 /* Map an object into an address space with the given cache flags. */ 202 201 void (*bind_vma)(struct i915_address_space *vm, 203 202 struct i915_vm_pt_stash *stash, 204 - struct i915_vma *vma, 203 + struct i915_vma_resource *vma_res, 205 204 enum i915_cache_level cache_level, 206 205 u32 flags); 207 206 /* ··· 209 208 * setting the valid PTE entries to a reserved scratch page. 210 209 */ 211 210 void (*unbind_vma)(struct i915_address_space *vm, 212 - struct i915_vma *vma); 211 + struct i915_vma_resource *vma_res); 212 + 213 213 }; 214 214 215 215 struct i915_address_space { ··· 287 285 enum i915_cache_level cache_level, 288 286 u32 flags); 289 287 void (*insert_entries)(struct i915_address_space *vm, 290 - struct i915_vma *vma, 288 + struct i915_vma_resource *vma_res, 291 289 enum i915_cache_level cache_level, 292 290 u32 flags); 293 291 void (*cleanup)(struct i915_address_space *vm); ··· 600 598 601 599 void ppgtt_bind_vma(struct i915_address_space *vm, 602 600 struct i915_vm_pt_stash *stash, 603 - struct i915_vma *vma, 601 + struct i915_vma_resource *vma_res, 604 602 enum i915_cache_level cache_level, 605 603 u32 flags); 606 604 void ppgtt_unbind_vma(struct i915_address_space *vm, 607 - struct i915_vma *vma); 605 + struct i915_vma_resource *vma_res); 608 606 609 607 void gtt_write_workarounds(struct intel_gt *gt); 610 608 ··· 627 625 static inline struct sgt_dma { 628 626 struct scatterlist *sg; 629 627 dma_addr_t dma, max; 630 - } sgt_dma(struct i915_vma *vma) { 631 - struct scatterlist *sg = vma->pages->sgl; 628 + } sgt_dma(struct i915_vma_resource *vma_res) { 629 + struct scatterlist *sg = vma_res->bi.pages->sgl; 632 630 dma_addr_t addr = sg_dma_address(sg); 633 631 634 632 return (struct sgt_dma){ sg, addr, addr + sg_dma_len(sg) };
+12 -10
drivers/gpu/drm/i915/gt/intel_ppgtt.c
··· 179 179 180 180 void ppgtt_bind_vma(struct i915_address_space *vm, 181 181 struct i915_vm_pt_stash *stash, 182 - struct i915_vma *vma, 182 + struct i915_vma_resource *vma_res, 183 183 enum i915_cache_level cache_level, 184 184 u32 flags) 185 185 { 186 186 u32 pte_flags; 187 187 188 - if (!test_bit(I915_VMA_ALLOC_BIT, __i915_vma_flags(vma))) { 189 - vm->allocate_va_range(vm, stash, vma->node.start, vma->size); 190 - set_bit(I915_VMA_ALLOC_BIT, __i915_vma_flags(vma)); 188 + if (!vma_res->allocated) { 189 + vm->allocate_va_range(vm, stash, vma_res->start, 190 + vma_res->vma_size); 191 + vma_res->allocated = true; 191 192 } 192 193 193 194 /* Applicable to VLV, and gen8+ */ 194 195 pte_flags = 0; 195 - if (i915_gem_object_is_readonly(vma->obj)) 196 + if (vma_res->bi.readonly) 196 197 pte_flags |= PTE_READ_ONLY; 197 - if (i915_gem_object_is_lmem(vma->obj)) 198 + if (vma_res->bi.lmem) 198 199 pte_flags |= PTE_LM; 199 200 200 - vm->insert_entries(vm, vma, cache_level, pte_flags); 201 + vm->insert_entries(vm, vma_res, cache_level, pte_flags); 201 202 wmb(); 202 203 } 203 204 204 - void ppgtt_unbind_vma(struct i915_address_space *vm, struct i915_vma *vma) 205 + void ppgtt_unbind_vma(struct i915_address_space *vm, 206 + struct i915_vma_resource *vma_res) 205 207 { 206 - if (test_and_clear_bit(I915_VMA_ALLOC_BIT, __i915_vma_flags(vma))) 207 - vm->clear_range(vm, vma->node.start, vma->size); 208 + if (vma_res->allocated) 209 + vm->clear_range(vm, vma_res->start, vma_res->vma_size); 208 210 } 209 211 210 212 static unsigned long pd_count(u64 size, int shift)
+6 -7
drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
··· 448 448 { 449 449 struct drm_i915_gem_object *obj = uc_fw->obj; 450 450 struct i915_ggtt *ggtt = __uc_fw_to_gt(uc_fw)->ggtt; 451 - struct i915_vma *dummy = &uc_fw->dummy; 451 + struct i915_vma_resource *dummy = &uc_fw->dummy; 452 452 u32 pte_flags = 0; 453 453 454 - dummy->node.start = uc_fw_ggtt_offset(uc_fw); 455 - dummy->node.size = obj->base.size; 456 - dummy->pages = obj->mm.pages; 457 - dummy->vm = &ggtt->vm; 454 + dummy->start = uc_fw_ggtt_offset(uc_fw); 455 + dummy->node_size = obj->base.size; 456 + dummy->bi.pages = obj->mm.pages; 458 457 459 458 GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj)); 460 - GEM_BUG_ON(dummy->node.size > ggtt->uc_fw.size); 459 + GEM_BUG_ON(dummy->node_size > ggtt->uc_fw.size); 461 460 462 461 /* uc_fw->obj cache domains were not controlled across suspend */ 463 462 if (i915_gem_object_has_struct_page(obj)) 464 - drm_clflush_sg(dummy->pages); 463 + drm_clflush_sg(dummy->bi.pages); 465 464 466 465 if (i915_gem_object_is_lmem(obj)) 467 466 pte_flags |= PTE_LM;
+1 -1
drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
··· 85 85 * threaded as it done during driver load (inherently single threaded) 86 86 * or during a GT reset (mutex guarantees single threaded). 87 87 */ 88 - struct i915_vma dummy; 88 + struct i915_vma_resource dummy; 89 89 struct i915_vma *rsa_data; 90 90 91 91 /*
+2 -1
drivers/gpu/drm/i915/i915_debugfs.c
··· 171 171 seq_printf(m, " (%s offset: %08llx, size: %08llx, pages: %s", 172 172 stringify_vma_type(vma), 173 173 vma->node.start, vma->node.size, 174 - stringify_page_sizes(vma->page_sizes.gtt, NULL, 0)); 174 + stringify_page_sizes(vma->resource->page_sizes_gtt, 175 + NULL, 0)); 175 176 if (i915_vma_is_ggtt(vma) || i915_vma_is_dpt(vma)) { 176 177 switch (vma->ggtt_view.type) { 177 178 case I915_GGTT_VIEW_NORMAL:
+3 -3
drivers/gpu/drm/i915/i915_gpu_error.c
··· 1040 1040 strcpy(dst->name, vsnap->name); 1041 1041 dst->next = NULL; 1042 1042 1043 - dst->gtt_offset = vsnap->gtt_offset; 1044 - dst->gtt_size = vsnap->gtt_size; 1045 - dst->gtt_page_sizes = vsnap->page_sizes; 1043 + dst->gtt_offset = vsnap->vma_resource->start; 1044 + dst->gtt_size = vsnap->vma_resource->node_size; 1045 + dst->gtt_page_sizes = vsnap->vma_resource->page_sizes_gtt; 1046 1046 dst->unused = 0; 1047 1047 1048 1048 ret = -EINVAL;
+20 -4
drivers/gpu/drm/i915/i915_vma.c
··· 298 298 struct i915_vma *vma = vw->vma; 299 299 300 300 vma->ops->bind_vma(vw->vm, &vw->stash, 301 - vma, vw->cache_level, vw->flags); 301 + vma->resource, vw->cache_level, vw->flags); 302 302 } 303 303 304 304 static void __vma_release(struct dma_fence_work *work) ··· 375 375 #define i915_vma_verify_bind_complete(_vma) 0 376 376 #endif 377 377 378 + I915_SELFTEST_EXPORT void 379 + i915_vma_resource_init_from_vma(struct i915_vma_resource *vma_res, 380 + struct i915_vma *vma) 381 + { 382 + struct drm_i915_gem_object *obj = vma->obj; 383 + 384 + i915_vma_resource_init(vma_res, vma->pages, &vma->page_sizes, 385 + i915_gem_object_is_readonly(obj), 386 + i915_gem_object_is_lmem(obj), 387 + vma->private, 388 + vma->node.start, 389 + vma->node.size, 390 + vma->size); 391 + } 392 + 378 393 /** 379 394 * i915_vma_bind - Sets up PTEs for an VMA in it's corresponding address space. 380 395 * @vma: VMA to map ··· 447 432 GEM_WARN_ON(!vma_flags); 448 433 kfree(vma_res); 449 434 } else { 450 - i915_vma_resource_init(vma_res); 435 + i915_vma_resource_init_from_vma(vma_res, vma); 451 436 vma->resource = vma_res; 452 437 } 453 438 trace_i915_vma_bind(vma, bind_flags); ··· 487 472 if (ret) 488 473 return ret; 489 474 } 490 - vma->ops->bind_vma(vma->vm, NULL, vma, cache_level, bind_flags); 475 + vma->ops->bind_vma(vma->vm, NULL, vma->resource, cache_level, 476 + bind_flags); 491 477 } 492 478 493 479 atomic_or(bind_flags, &vma->flags); ··· 1739 1723 1740 1724 if (likely(atomic_read(&vma->vm->open))) { 1741 1725 trace_i915_vma_unbind(vma); 1742 - vma->ops->unbind_vma(vma->vm, vma); 1726 + vma->ops->unbind_vma(vma->vm, vma->resource); 1743 1727 } 1744 1728 atomic_and(~(I915_VMA_BIND_MASK | I915_VMA_ERROR | I915_VMA_GGTT_WRITE), 1745 1729 &vma->flags);
+5 -6
drivers/gpu/drm/i915/i915_vma.h
··· 339 339 */ 340 340 void i915_vma_unpin_iomap(struct i915_vma *vma); 341 341 342 - static inline struct page *i915_vma_first_page(struct i915_vma *vma) 343 - { 344 - GEM_BUG_ON(!vma->pages); 345 - return sg_page(vma->pages->sgl); 346 - } 347 - 348 342 /** 349 343 * i915_vma_pin_fence - pin fencing state 350 344 * @vma: vma to pin fencing for ··· 438 444 { 439 445 return i915_vma_resource_get(vma->resource); 440 446 } 447 + 448 + #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) 449 + void i915_vma_resource_init_from_vma(struct i915_vma_resource *vma_res, 450 + struct i915_vma *vma); 451 + #endif 441 452 442 453 void i915_vma_module_exit(void); 443 454 int i915_vma_module_init(void);
+3 -6
drivers/gpu/drm/i915/i915_vma_resource.c
··· 23 23 }; 24 24 25 25 /** 26 - * i915_vma_resource_init - Initialize a vma resource. 26 + * __i915_vma_resource_init - Initialize a vma resource. 27 27 * @vma_res: The vma resource to initialize 28 28 * 29 - * Initializes a vma resource allocated using i915_vma_resource_alloc(). 30 - * The reason for having separate allocate and initialize function is that 31 - * initialization may need to be performed from under a lock where 32 - * allocation is not allowed. 29 + * Initializes the private members of a vma resource. 33 30 */ 34 - void i915_vma_resource_init(struct i915_vma_resource *vma_res) 31 + void __i915_vma_resource_init(struct i915_vma_resource *vma_res) 35 32 { 36 33 spin_lock_init(&vma_res->lock); 37 34 dma_fence_init(&vma_res->unbind_fence, &unbind_fence_ops,
+96 -3
drivers/gpu/drm/i915/i915_vma_resource.h
··· 9 9 #include <linux/dma-fence.h> 10 10 #include <linux/refcount.h> 11 11 12 + #include "i915_gem.h" 13 + 14 + struct i915_page_sizes { 15 + /** 16 + * The sg mask of the pages sg_table. i.e the mask of 17 + * the lengths for each sg entry. 18 + */ 19 + unsigned int phys; 20 + 21 + /** 22 + * The gtt page sizes we are allowed to use given the 23 + * sg mask and the supported page sizes. This will 24 + * express the smallest unit we can use for the whole 25 + * object, as well as the larger sizes we may be able 26 + * to use opportunistically. 27 + */ 28 + unsigned int sg; 29 + }; 30 + 12 31 /** 13 32 * struct i915_vma_resource - Snapshotted unbind information. 14 33 * @unbind_fence: Fence to mark unbinding complete. Note that this fence ··· 38 19 * @hold_count: Number of holders blocking the fence from finishing. 39 20 * The vma itself is keeping a hold, which is released when unbind 40 21 * is scheduled. 22 + * @private: Bind backend private info. 23 + * @start: Offset into the address space of bind range start. 24 + * @node_size: Size of the allocated range manager node. 25 + * @vma_size: Bind size. 26 + * @page_sizes_gtt: Resulting page sizes from the bind operation. 27 + * @bound_flags: Flags indicating binding status. 28 + * @allocated: Backend private data. TODO: Should move into @private. 41 29 * 42 30 * The lifetime of a struct i915_vma_resource is from a binding request to 43 31 * the actual possible asynchronous unbind has completed. ··· 54 28 /* See above for description of the lock. */ 55 29 spinlock_t lock; 56 30 refcount_t hold_count; 31 + 32 + /** 33 + * struct i915_vma_bindinfo - Information needed for async bind 34 + * only but that can be dropped after the bind has taken place. 35 + * Consider making this a separate argument to the bind_vma 36 + * op, coalescing with other arguments like vm, stash, cache_level 37 + * and flags 38 + * @pages: The pages sg-table. 39 + * @page_sizes: Page sizes of the pages. 40 + * @readonly: Whether the vma should be bound read-only. 41 + * @lmem: Whether the vma points to lmem. 42 + */ 43 + struct i915_vma_bindinfo { 44 + struct sg_table *pages; 45 + struct i915_page_sizes page_sizes; 46 + bool readonly:1; 47 + bool lmem:1; 48 + } bi; 49 + 50 + void *private; 51 + u64 start; 52 + u64 node_size; 53 + u64 vma_size; 54 + u32 page_sizes_gtt; 55 + u32 bound_flags; 56 + bool allocated:1; 57 57 }; 58 58 59 59 bool i915_vma_resource_hold(struct i915_vma_resource *vma_res, ··· 91 39 struct i915_vma_resource *i915_vma_resource_alloc(void); 92 40 93 41 struct dma_fence *i915_vma_resource_unbind(struct i915_vma_resource *vma_res); 42 + 43 + void __i915_vma_resource_init(struct i915_vma_resource *vma_res); 94 44 95 45 /** 96 46 * i915_vma_resource_get - Take a reference on a vma resource ··· 116 62 dma_fence_put(&vma_res->unbind_fence); 117 63 } 118 64 119 - #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) 120 - void i915_vma_resource_init(struct i915_vma_resource *vma_res); 121 - #endif 65 + /** 66 + * i915_vma_resource_init - Initialize a vma resource. 67 + * @vma_res: The vma resource to initialize 68 + * @pages: The pages sg-table. 69 + * @page_sizes: Page sizes of the pages. 70 + * @readonly: Whether the vma should be bound read-only. 71 + * @lmem: Whether the vma points to lmem. 72 + * @private: Bind backend private info. 73 + * @start: Offset into the address space of bind range start. 74 + * @node_size: Size of the allocated range manager node. 75 + * @size: Bind size. 76 + * 77 + * Initializes a vma resource allocated using i915_vma_resource_alloc(). 78 + * The reason for having separate allocate and initialize function is that 79 + * initialization may need to be performed from under a lock where 80 + * allocation is not allowed. 81 + */ 82 + static inline void i915_vma_resource_init(struct i915_vma_resource *vma_res, 83 + struct sg_table *pages, 84 + const struct i915_page_sizes *page_sizes, 85 + bool readonly, 86 + bool lmem, 87 + void *private, 88 + u64 start, 89 + u64 node_size, 90 + u64 size) 91 + { 92 + __i915_vma_resource_init(vma_res); 93 + vma_res->bi.pages = pages; 94 + vma_res->bi.page_sizes = *page_sizes; 95 + vma_res->bi.readonly = readonly; 96 + vma_res->bi.lmem = lmem; 97 + vma_res->private = private; 98 + vma_res->start = start; 99 + vma_res->node_size = node_size; 100 + vma_res->vma_size = size; 101 + } 102 + 103 + static inline void i915_vma_resource_fini(struct i915_vma_resource *vma_res) 104 + { 105 + GEM_BUG_ON(refcount_read(&vma_res->hold_count) != 1); 106 + } 122 107 123 108 #endif
-4
drivers/gpu/drm/i915/i915_vma_snapshot.c
··· 24 24 assert_object_held(vma->obj); 25 25 26 26 vsnap->name = name; 27 - vsnap->size = vma->size; 28 27 vsnap->obj_size = vma->obj->base.size; 29 - vsnap->gtt_offset = vma->node.start; 30 - vsnap->gtt_size = vma->node.size; 31 - vsnap->page_sizes = vma->page_sizes.gtt; 32 28 vsnap->pages = vma->pages; 33 29 vsnap->pages_rsgt = NULL; 34 30 vsnap->mr = NULL;
-8
drivers/gpu/drm/i915/i915_vma_snapshot.h
··· 23 23 24 24 /** 25 25 * struct i915_vma_snapshot - Snapshot of vma metadata. 26 - * @size: The vma size in bytes. 27 26 * @obj_size: The size of the underlying object in bytes. 28 - * @gtt_offset: The gtt offset the vma is bound to. 29 - * @gtt_size: The size in bytes allocated for the vma in the GTT. 30 27 * @pages: The struct sg_table pointing to the pages bound. 31 28 * @pages_rsgt: The refcounted sg_table holding the reference for @pages if any. 32 29 * @mr: The memory region pointed for the pages bound. 33 30 * @kref: Reference for this structure. 34 31 * @vma_resource: Pointer to the vma resource representing the vma binding. 35 - * @page_sizes: The vma GTT page sizes information. 36 32 * @onstack: Whether the structure shouldn't be freed on final put. 37 33 * @present: Whether the structure is present and initialized. 38 34 */ 39 35 struct i915_vma_snapshot { 40 36 const char *name; 41 - size_t size; 42 37 size_t obj_size; 43 - size_t gtt_offset; 44 - size_t gtt_size; 45 38 struct sg_table *pages; 46 39 struct i915_refct_sgt *pages_rsgt; 47 40 struct intel_memory_region *mr; 48 41 struct kref kref; 49 42 struct i915_vma_resource *vma_resource; 50 - u32 page_sizes; 51 43 bool onstack:1; 52 44 bool present:1; 53 45 };
+6 -8
drivers/gpu/drm/i915/i915_vma_types.h
··· 240 240 241 241 #define I915_VMA_BIND_MASK (I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND) 242 242 243 - #define I915_VMA_ALLOC_BIT 12 244 - 245 - #define I915_VMA_ERROR_BIT 13 243 + #define I915_VMA_ERROR_BIT 12 246 244 #define I915_VMA_ERROR ((int)BIT(I915_VMA_ERROR_BIT)) 247 245 248 - #define I915_VMA_GGTT_BIT 14 249 - #define I915_VMA_CAN_FENCE_BIT 15 250 - #define I915_VMA_USERFAULT_BIT 16 251 - #define I915_VMA_GGTT_WRITE_BIT 17 246 + #define I915_VMA_GGTT_BIT 13 247 + #define I915_VMA_CAN_FENCE_BIT 14 248 + #define I915_VMA_USERFAULT_BIT 15 249 + #define I915_VMA_GGTT_WRITE_BIT 16 252 250 253 251 #define I915_VMA_GGTT ((int)BIT(I915_VMA_GGTT_BIT)) 254 252 #define I915_VMA_CAN_FENCE ((int)BIT(I915_VMA_CAN_FENCE_BIT)) 255 253 #define I915_VMA_USERFAULT ((int)BIT(I915_VMA_USERFAULT_BIT)) 256 254 #define I915_VMA_GGTT_WRITE ((int)BIT(I915_VMA_GGTT_WRITE_BIT)) 257 255 258 - #define I915_VMA_SCANOUT_BIT 18 256 + #define I915_VMA_SCANOUT_BIT 17 259 257 #define I915_VMA_SCANOUT ((int)BIT(I915_VMA_SCANOUT_BIT)) 260 258 261 259 struct i915_active active;
+44 -20
drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
··· 239 239 unsigned long end_time) 240 240 { 241 241 I915_RND_STATE(seed_prng); 242 - struct i915_vma *mock_vma; 242 + struct i915_vma_resource *mock_vma_res; 243 243 unsigned int size; 244 244 245 - mock_vma = kzalloc(sizeof(*mock_vma), GFP_KERNEL); 246 - if (!mock_vma) 245 + mock_vma_res = kzalloc(sizeof(*mock_vma_res), GFP_KERNEL); 246 + if (!mock_vma_res) 247 247 return -ENOMEM; 248 248 249 249 /* Keep creating larger objects until one cannot fit into the hole */ ··· 269 269 break; 270 270 } while (count >>= 1); 271 271 if (!count) { 272 - kfree(mock_vma); 272 + kfree(mock_vma_res); 273 273 return -ENOMEM; 274 274 } 275 275 GEM_BUG_ON(!order); ··· 343 343 break; 344 344 } 345 345 346 - mock_vma->pages = obj->mm.pages; 347 - mock_vma->node.size = BIT_ULL(size); 348 - mock_vma->node.start = addr; 346 + mock_vma_res->bi.pages = obj->mm.pages; 347 + mock_vma_res->node_size = BIT_ULL(size); 348 + mock_vma_res->start = addr; 349 349 350 350 with_intel_runtime_pm(vm->gt->uncore->rpm, wakeref) 351 - vm->insert_entries(vm, mock_vma, 351 + vm->insert_entries(vm, mock_vma_res, 352 352 I915_CACHE_NONE, 0); 353 353 } 354 354 count = n; ··· 371 371 cleanup_freed_objects(vm->i915); 372 372 } 373 373 374 - kfree(mock_vma); 374 + kfree(mock_vma_res); 375 375 return 0; 376 376 } 377 377 ··· 1280 1280 atomic_set(&vma->pages_count, I915_VMA_PAGES_ACTIVE); 1281 1281 __i915_gem_object_pin_pages(obj); 1282 1282 vma->pages = obj->mm.pages; 1283 + vma->resource->bi.pages = vma->pages; 1283 1284 1284 1285 mutex_lock(&vma->vm->mutex); 1285 1286 list_add_tail(&vma->vm_link, &vma->vm->bound_list); ··· 1355 1354 obj->cache_level, 1356 1355 0); 1357 1356 if (!err) { 1358 - i915_vma_resource_init(vma_res); 1357 + i915_vma_resource_init_from_vma(vma_res, vma); 1359 1358 vma->resource = vma_res; 1360 1359 } else { 1361 1360 kfree(vma_res); ··· 1534 1533 err = i915_gem_gtt_insert(vm, &vma->node, obj->base.size, 0, 1535 1534 obj->cache_level, 0, vm->total, 0); 1536 1535 if (!err) { 1537 - i915_vma_resource_init(vma_res); 1536 + i915_vma_resource_init_from_vma(vma_res, vma); 1538 1537 vma->resource = vma_res; 1539 1538 } else { 1540 1539 kfree(vma_res); ··· 1961 1960 struct i915_vm_pt_stash stash = {}; 1962 1961 struct i915_request *rq; 1963 1962 struct i915_gem_ww_ctx ww; 1963 + struct i915_vma_resource *vma_res; 1964 1964 u64 offset; 1965 1965 1966 1966 offset = igt_random_offset(&prng, ··· 1981 1979 i915_gem_object_unlock(bbe); 1982 1980 if (err) 1983 1981 goto end; 1982 + 1983 + vma_res = i915_vma_resource_alloc(); 1984 + if (IS_ERR(vma_res)) { 1985 + i915_vma_put_pages(vma); 1986 + err = PTR_ERR(vma_res); 1987 + goto end; 1988 + } 1984 1989 1985 1990 i915_gem_ww_ctx_init(&ww, false); 1986 1991 retry: ··· 2010 2001 goto retry; 2011 2002 } 2012 2003 i915_gem_ww_ctx_fini(&ww); 2013 - if (err) 2004 + if (err) { 2005 + kfree(vma_res); 2014 2006 goto end; 2007 + } 2015 2008 2009 + i915_vma_resource_init_from_vma(vma_res, vma); 2016 2010 /* Prime the TLB with the dummy pages */ 2017 2011 for (i = 0; i < count; i++) { 2018 - vma->node.start = offset + i * PAGE_SIZE; 2019 - vm->insert_entries(vm, vma, I915_CACHE_NONE, 0); 2012 + vma_res->start = offset + i * PAGE_SIZE; 2013 + vm->insert_entries(vm, vma_res, I915_CACHE_NONE, 2014 + 0); 2020 2015 2021 - rq = submit_batch(ce, vma->node.start); 2016 + rq = submit_batch(ce, vma_res->start); 2022 2017 if (IS_ERR(rq)) { 2023 2018 err = PTR_ERR(rq); 2019 + i915_vma_resource_fini(vma_res); 2020 + kfree(vma_res); 2024 2021 goto end; 2025 2022 } 2026 2023 i915_request_put(rq); 2027 2024 } 2028 - 2025 + i915_vma_resource_fini(vma_res); 2029 2026 i915_vma_put_pages(vma); 2030 2027 2031 2028 err = context_sync(ce); 2032 2029 if (err) { 2033 2030 pr_err("%s: dummy setup timed out\n", 2034 2031 ce->engine->name); 2032 + kfree(vma_res); 2035 2033 goto end; 2036 2034 } 2037 2035 2038 2036 vma = i915_vma_instance(act, vm, NULL); 2039 2037 if (IS_ERR(vma)) { 2038 + kfree(vma_res); 2040 2039 err = PTR_ERR(vma); 2041 2040 goto end; 2042 2041 } ··· 2052 2035 i915_gem_object_lock(act, NULL); 2053 2036 err = i915_vma_get_pages(vma); 2054 2037 i915_gem_object_unlock(act); 2055 - if (err) 2038 + if (err) { 2039 + kfree(vma_res); 2056 2040 goto end; 2041 + } 2057 2042 2043 + i915_vma_resource_init_from_vma(vma_res, vma); 2058 2044 /* Replace the TLB with target batches */ 2059 2045 for (i = 0; i < count; i++) { 2060 2046 struct i915_request *rq; 2061 2047 u32 *cs = batch + i * 64 / sizeof(*cs); 2062 2048 u64 addr; 2063 2049 2064 - vma->node.start = offset + i * PAGE_SIZE; 2065 - vm->insert_entries(vm, vma, I915_CACHE_NONE, 0); 2050 + vma_res->start = offset + i * PAGE_SIZE; 2051 + vm->insert_entries(vm, vma_res, I915_CACHE_NONE, 0); 2066 2052 2067 - addr = vma->node.start + i * 64; 2053 + addr = vma_res->start + i * 64; 2068 2054 cs[4] = MI_NOOP; 2069 2055 cs[6] = lower_32_bits(addr); 2070 2056 cs[7] = upper_32_bits(addr); ··· 2076 2056 rq = submit_batch(ce, addr); 2077 2057 if (IS_ERR(rq)) { 2078 2058 err = PTR_ERR(rq); 2059 + i915_vma_resource_fini(vma_res); 2060 + kfree(vma_res); 2079 2061 goto end; 2080 2062 } 2081 2063 ··· 2094 2072 } 2095 2073 end_spin(batch, count - 1); 2096 2074 2075 + i915_vma_resource_fini(vma_res); 2076 + kfree(vma_res); 2097 2077 i915_vma_put_pages(vma); 2098 2078 2099 2079 err = context_sync(ce);
+6 -6
drivers/gpu/drm/i915/selftests/mock_gtt.c
··· 33 33 } 34 34 35 35 static void mock_insert_entries(struct i915_address_space *vm, 36 - struct i915_vma *vma, 36 + struct i915_vma_resource *vma_res, 37 37 enum i915_cache_level level, u32 flags) 38 38 { 39 39 } 40 40 41 41 static void mock_bind_ppgtt(struct i915_address_space *vm, 42 42 struct i915_vm_pt_stash *stash, 43 - struct i915_vma *vma, 43 + struct i915_vma_resource *vma_res, 44 44 enum i915_cache_level cache_level, 45 45 u32 flags) 46 46 { 47 47 GEM_BUG_ON(flags & I915_VMA_GLOBAL_BIND); 48 - set_bit(I915_VMA_LOCAL_BIND_BIT, __i915_vma_flags(vma)); 48 + vma_res->bound_flags |= flags; 49 49 } 50 50 51 51 static void mock_unbind_ppgtt(struct i915_address_space *vm, 52 - struct i915_vma *vma) 52 + struct i915_vma_resource *vma_res) 53 53 { 54 54 } 55 55 ··· 93 93 94 94 static void mock_bind_ggtt(struct i915_address_space *vm, 95 95 struct i915_vm_pt_stash *stash, 96 - struct i915_vma *vma, 96 + struct i915_vma_resource *vma_res, 97 97 enum i915_cache_level cache_level, 98 98 u32 flags) 99 99 { 100 100 } 101 101 102 102 static void mock_unbind_ggtt(struct i915_address_space *vm, 103 - struct i915_vma *vma) 103 + struct i915_vma_resource *vma_res) 104 104 { 105 105 } 106 106