Skip to content

Commit

Permalink
drm/i915: Use the vma resource as argument for gtt binding / unbinding
Browse files Browse the repository at this point in the history
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

Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
  • Loading branch information
Thomas Hellström authored and intel-lab-lkp committed Dec 17, 2021
1 parent 38d1247 commit c107a1d
Show file tree
Hide file tree
Showing 21 changed files with 307 additions and 206 deletions.
27 changes: 15 additions & 12 deletions drivers/gpu/drm/i915/display/intel_dpt.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ static void dpt_insert_page(struct i915_address_space *vm,
}

static void dpt_insert_entries(struct i915_address_space *vm,
struct i915_vma *vma,
struct i915_vma_resource *vma_res,
enum i915_cache_level level,
u32 flags)
{
Expand All @@ -64,8 +64,8 @@ static void dpt_insert_entries(struct i915_address_space *vm,
* not to allow the user to override access to a read only page.
*/

i = vma->node.start / I915_GTT_PAGE_SIZE;
for_each_sgt_daddr(addr, sgt_iter, vma->pages)
i = vma_res->start / I915_GTT_PAGE_SIZE;
for_each_sgt_daddr(addr, sgt_iter, vma_res->bi.pages)
gen8_set_pte(&base[i++], pte_encode | addr);
}

Expand All @@ -76,35 +76,38 @@ static void dpt_clear_range(struct i915_address_space *vm,

static void dpt_bind_vma(struct i915_address_space *vm,
struct i915_vm_pt_stash *stash,
struct i915_vma *vma,
struct i915_vma_resource *vma_res,
enum i915_cache_level cache_level,
u32 flags)
{
struct drm_i915_gem_object *obj = vma->obj;
u32 pte_flags;

if (vma_res->bound_flags)
return;

/* Applicable to VLV (gen8+ do not support RO in the GGTT) */
pte_flags = 0;
if (vma->vm->has_read_only && i915_gem_object_is_readonly(obj))
if (vm->has_read_only && vma_res->bi.readonly)
pte_flags |= PTE_READ_ONLY;
if (i915_gem_object_is_lmem(obj))
if (vma_res->bi.lmem)
pte_flags |= PTE_LM;

vma->vm->insert_entries(vma->vm, vma, cache_level, pte_flags);
vm->insert_entries(vm, vma_res, cache_level, pte_flags);

vma->page_sizes.gtt = I915_GTT_PAGE_SIZE;
vma_res->page_sizes_gtt = I915_GTT_PAGE_SIZE;

/*
* Without aliasing PPGTT there's no difference between
* GLOBAL/LOCAL_BIND, it's all the same ptes. Hence unconditionally
* upgrade to both bound if we bind either to avoid double-binding.
*/
atomic_or(I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND, &vma->flags);
vma_res->bound_flags = I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND;
}

static void dpt_unbind_vma(struct i915_address_space *vm, struct i915_vma *vma)
static void dpt_unbind_vma(struct i915_address_space *vm,
struct i915_vma_resource *vma_res)
{
vm->clear_range(vm, vma->node.start, vma->size);
vm->clear_range(vm, vma_res->start, vma_res->vma_size);
}

static void dpt_cleanup(struct i915_address_space *vm)
Expand Down
27 changes: 2 additions & 25 deletions drivers/gpu/drm/i915/gem/i915_gem_object_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "i915_active.h"
#include "i915_selftest.h"
#include "i915_vma_resource.h"

struct drm_i915_gem_object;
struct intel_fronbuffer;
Expand Down Expand Up @@ -549,31 +550,7 @@ struct drm_i915_gem_object {
struct sg_table *pages;
void *mapping;

struct i915_page_sizes {
/**
* The sg mask of the pages sg_table. i.e the mask of
* of the lengths for each sg entry.
*/
unsigned int phys;

/**
* The gtt page sizes we are allowed to use given the
* sg mask and the supported page sizes. This will
* express the smallest unit we can use for the whole
* object, as well as the larger sizes we may be able
* to use opportunistically.
*/
unsigned int sg;

/**
* The actual gtt page size usage. Since we can have
* multiple vma associated with this object we need to
* prevent any trampling of state, hence a copy of this
* struct also lives in each vma, therefore the gtt
* value here should only be read/write through the vma.
*/
unsigned int gtt;
} page_sizes;
struct i915_page_sizes page_sizes;

I915_SELFTEST_DECLARE(unsigned int page_mask);

Expand Down
37 changes: 16 additions & 21 deletions drivers/gpu/drm/i915/gem/selftests/huge_pages.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,9 +370,9 @@ static int igt_check_page_sizes(struct i915_vma *vma)
err = -EINVAL;
}

if (!HAS_PAGE_SIZES(i915, vma->page_sizes.gtt)) {
if (!HAS_PAGE_SIZES(i915, vma->resource->page_sizes_gtt)) {
pr_err("unsupported page_sizes.gtt=%u, supported=%u\n",
vma->page_sizes.gtt & ~supported, supported);
vma->resource->page_sizes_gtt & ~supported, supported);
err = -EINVAL;
}

Expand Down Expand Up @@ -403,15 +403,9 @@ static int igt_check_page_sizes(struct i915_vma *vma)
if (i915_gem_object_is_lmem(obj) &&
IS_ALIGNED(vma->node.start, SZ_2M) &&
vma->page_sizes.sg & SZ_2M &&
vma->page_sizes.gtt < SZ_2M) {
vma->resource->page_sizes_gtt < SZ_2M) {
pr_err("gtt pages mismatch for LMEM, expected 2M GTT pages, sg(%u), gtt(%u)\n",
vma->page_sizes.sg, vma->page_sizes.gtt);
err = -EINVAL;
}

if (obj->mm.page_sizes.gtt) {
pr_err("obj->page_sizes.gtt(%u) should never be set\n",
obj->mm.page_sizes.gtt);
vma->page_sizes.sg, vma->resource->page_sizes_gtt);
err = -EINVAL;
}

Expand Down Expand Up @@ -547,9 +541,9 @@ static int igt_mock_memory_region_huge_pages(void *arg)
goto out_unpin;
}

if (vma->page_sizes.gtt != page_size) {
if (vma->resource->page_sizes_gtt != page_size) {
pr_err("%s page_sizes.gtt=%u, expected=%u\n",
__func__, vma->page_sizes.gtt,
__func__, vma->resource->page_sizes_gtt,
page_size);
err = -EINVAL;
goto out_unpin;
Expand Down Expand Up @@ -630,9 +624,9 @@ static int igt_mock_ppgtt_misaligned_dma(void *arg)

err = igt_check_page_sizes(vma);

if (vma->page_sizes.gtt != page_size) {
if (vma->resource->page_sizes_gtt != page_size) {
pr_err("page_sizes.gtt=%u, expected %u\n",
vma->page_sizes.gtt, page_size);
vma->resource->page_sizes_gtt, page_size);
err = -EINVAL;
}

Expand All @@ -657,9 +651,10 @@ static int igt_mock_ppgtt_misaligned_dma(void *arg)

err = igt_check_page_sizes(vma);

if (vma->page_sizes.gtt != I915_GTT_PAGE_SIZE_4K) {
if (vma->resource->page_sizes_gtt != I915_GTT_PAGE_SIZE_4K) {
pr_err("page_sizes.gtt=%u, expected %llu\n",
vma->page_sizes.gtt, I915_GTT_PAGE_SIZE_4K);
vma->resource->page_sizes_gtt,
I915_GTT_PAGE_SIZE_4K);
err = -EINVAL;
}

Expand Down Expand Up @@ -805,9 +800,9 @@ static int igt_mock_ppgtt_huge_fill(void *arg)
}
}

if (vma->page_sizes.gtt != expected_gtt) {
if (vma->resource->page_sizes_gtt != expected_gtt) {
pr_err("gtt=%u, expected=%u, size=%zd, single=%s\n",
vma->page_sizes.gtt, expected_gtt,
vma->resource->page_sizes_gtt, expected_gtt,
obj->base.size, yesno(!!single));
err = -EINVAL;
break;
Expand Down Expand Up @@ -961,10 +956,10 @@ static int igt_mock_ppgtt_64K(void *arg)
}
}

if (vma->page_sizes.gtt != expected_gtt) {
if (vma->resource->page_sizes_gtt != expected_gtt) {
pr_err("gtt=%u, expected=%u, i=%d, single=%s\n",
vma->page_sizes.gtt, expected_gtt, i,
yesno(!!single));
vma->resource->page_sizes_gtt,
expected_gtt, i, yesno(!!single));
err = -EINVAL;
goto out_vma_unpin;
}
Expand Down
19 changes: 10 additions & 9 deletions drivers/gpu/drm/i915/gt/gen6_ppgtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,17 +104,17 @@ static void gen6_ppgtt_clear_range(struct i915_address_space *vm,
}

static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
struct i915_vma *vma,
struct i915_vma_resource *vma_res,
enum i915_cache_level cache_level,
u32 flags)
{
struct i915_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
struct i915_page_directory * const pd = ppgtt->pd;
unsigned int first_entry = vma->node.start / I915_GTT_PAGE_SIZE;
unsigned int first_entry = vma_res->start / I915_GTT_PAGE_SIZE;
unsigned int act_pt = first_entry / GEN6_PTES;
unsigned int act_pte = first_entry % GEN6_PTES;
const u32 pte_encode = vm->pte_encode(0, cache_level, flags);
struct sgt_dma iter = sgt_dma(vma);
struct sgt_dma iter = sgt_dma(vma_res);
gen6_pte_t *vaddr;

GEM_BUG_ON(!pd->entry[act_pt]);
Expand All @@ -140,7 +140,7 @@ static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
}
} while (1);

vma->page_sizes.gtt = I915_GTT_PAGE_SIZE;
vma_res->page_sizes_gtt = I915_GTT_PAGE_SIZE;
}

static void gen6_flush_pd(struct gen6_ppgtt *ppgtt, u64 start, u64 end)
Expand Down Expand Up @@ -284,23 +284,24 @@ static void pd_vma_clear_pages(struct i915_vma *vma)

static void pd_vma_bind(struct i915_address_space *vm,
struct i915_vm_pt_stash *stash,
struct i915_vma *vma,
struct i915_vma_resource *vma_res,
enum i915_cache_level cache_level,
u32 unused)
{
struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
struct gen6_ppgtt *ppgtt = vma->private;
u32 ggtt_offset = i915_ggtt_offset(vma) / I915_GTT_PAGE_SIZE;
struct gen6_ppgtt *ppgtt = vma_res->private;
u32 ggtt_offset = vma_res->start / I915_GTT_PAGE_SIZE;

ppgtt->pp_dir = ggtt_offset * sizeof(gen6_pte_t) << 10;
ppgtt->pd_addr = (gen6_pte_t __iomem *)ggtt->gsm + ggtt_offset;

gen6_flush_pd(ppgtt, 0, ppgtt->base.vm.total);
}

static void pd_vma_unbind(struct i915_address_space *vm, struct i915_vma *vma)
static void pd_vma_unbind(struct i915_address_space *vm,
struct i915_vma_resource *vma_res)
{
struct gen6_ppgtt *ppgtt = vma->private;
struct gen6_ppgtt *ppgtt = vma_res->private;
struct i915_page_directory * const pd = ppgtt->base.pd;
struct i915_page_table *pt;
unsigned int pde;
Expand Down
37 changes: 19 additions & 18 deletions drivers/gpu/drm/i915/gt/gen8_ppgtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,20 +453,21 @@ gen8_ppgtt_insert_pte(struct i915_ppgtt *ppgtt,
return idx;
}

static void gen8_ppgtt_insert_huge(struct i915_vma *vma,
static void gen8_ppgtt_insert_huge(struct i915_address_space *vm,
struct i915_vma_resource *vma_res,
struct sgt_dma *iter,
enum i915_cache_level cache_level,
u32 flags)
{
const gen8_pte_t pte_encode = gen8_pte_encode(0, cache_level, flags);
unsigned int rem = sg_dma_len(iter->sg);
u64 start = vma->node.start;
u64 start = vma_res->start;

GEM_BUG_ON(!i915_vm_is_4lvl(vma->vm));
GEM_BUG_ON(!i915_vm_is_4lvl(vm));

do {
struct i915_page_directory * const pdp =
gen8_pdp_for_page_address(vma->vm, start);
gen8_pdp_for_page_address(vm, start);
struct i915_page_directory * const pd =
i915_pd_entry(pdp, __gen8_pte_index(start, 2));
gen8_pte_t encode = pte_encode;
Expand All @@ -475,7 +476,7 @@ static void gen8_ppgtt_insert_huge(struct i915_vma *vma,
gen8_pte_t *vaddr;
u16 index;

if (vma->page_sizes.sg & I915_GTT_PAGE_SIZE_2M &&
if (vma_res->bi.page_sizes.sg & I915_GTT_PAGE_SIZE_2M &&
IS_ALIGNED(iter->dma, I915_GTT_PAGE_SIZE_2M) &&
rem >= I915_GTT_PAGE_SIZE_2M &&
!__gen8_pte_index(start, 0)) {
Expand All @@ -492,7 +493,7 @@ static void gen8_ppgtt_insert_huge(struct i915_vma *vma,
page_size = I915_GTT_PAGE_SIZE;

if (!index &&
vma->page_sizes.sg & I915_GTT_PAGE_SIZE_64K &&
vma_res->bi.page_sizes.sg & I915_GTT_PAGE_SIZE_64K &&
IS_ALIGNED(iter->dma, I915_GTT_PAGE_SIZE_64K) &&
(IS_ALIGNED(rem, I915_GTT_PAGE_SIZE_64K) ||
rem >= (I915_PDES - index) * I915_GTT_PAGE_SIZE))
Expand Down Expand Up @@ -541,9 +542,9 @@ static void gen8_ppgtt_insert_huge(struct i915_vma *vma,
*/
if (maybe_64K != -1 &&
(index == I915_PDES ||
(i915_vm_has_scratch_64K(vma->vm) &&
!iter->sg && IS_ALIGNED(vma->node.start +
vma->node.size,
(i915_vm_has_scratch_64K(vm) &&
!iter->sg && IS_ALIGNED(vma_res->start +
vma_res->node_size,
I915_GTT_PAGE_SIZE_2M)))) {
vaddr = px_vaddr(pd);
vaddr[maybe_64K] |= GEN8_PDE_IPS_64K;
Expand All @@ -559,10 +560,10 @@ static void gen8_ppgtt_insert_huge(struct i915_vma *vma,
* instead - which we detect as missing results during
* selftests.
*/
if (I915_SELFTEST_ONLY(vma->vm->scrub_64K)) {
if (I915_SELFTEST_ONLY(vm->scrub_64K)) {
u16 i;

encode = vma->vm->scratch[0]->encode;
encode = vm->scratch[0]->encode;
vaddr = px_vaddr(i915_pt_entry(pd, maybe_64K));

for (i = 1; i < index; i += 16)
Expand All @@ -572,22 +573,22 @@ static void gen8_ppgtt_insert_huge(struct i915_vma *vma,
}
}

vma->page_sizes.gtt |= page_size;
vma_res->page_sizes_gtt |= page_size;
} while (iter->sg && sg_dma_len(iter->sg));
}

static void gen8_ppgtt_insert(struct i915_address_space *vm,
struct i915_vma *vma,
struct i915_vma_resource *vma_res,
enum i915_cache_level cache_level,
u32 flags)
{
struct i915_ppgtt * const ppgtt = i915_vm_to_ppgtt(vm);
struct sgt_dma iter = sgt_dma(vma);
struct sgt_dma iter = sgt_dma(vma_res);

if (vma->page_sizes.sg > I915_GTT_PAGE_SIZE) {
gen8_ppgtt_insert_huge(vma, &iter, cache_level, flags);
if (vma_res->bi.page_sizes.sg > I915_GTT_PAGE_SIZE) {
gen8_ppgtt_insert_huge(vm, vma_res, &iter, cache_level, flags);
} else {
u64 idx = vma->node.start >> GEN8_PTE_SHIFT;
u64 idx = vma_res->start >> GEN8_PTE_SHIFT;

do {
struct i915_page_directory * const pdp =
Expand All @@ -597,7 +598,7 @@ static void gen8_ppgtt_insert(struct i915_address_space *vm,
cache_level, flags);
} while (idx);

vma->page_sizes.gtt = I915_GTT_PAGE_SIZE;
vma_res->page_sizes_gtt = I915_GTT_PAGE_SIZE;
}
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/i915/gt/intel_engine_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1718,8 +1718,8 @@ static void print_request_ring(struct drm_printer *m, struct i915_request *rq)
drm_printf(m,
"[head %04x, postfix %04x, tail %04x, batch 0x%08x_%08x]:\n",
rq->head, rq->postfix, rq->tail,
vsnap ? upper_32_bits(vsnap->gtt_offset) : ~0u,
vsnap ? lower_32_bits(vsnap->gtt_offset) : ~0u);
vsnap ? upper_32_bits(vsnap->vma_resource->start) : ~0u,
vsnap ? lower_32_bits(vsnap->vma_resource->start) : ~0u);

size = rq->tail - rq->head;
if (rq->tail < rq->head)
Expand Down

0 comments on commit c107a1d

Please sign in to comment.