err = i915_vma_pin(vma, 0, 0, PIN_USER); if (err) goto out;
/* Pin va at random but aligned offset after vma */
addr = round_up(vma->node.start + vma->node.size, align); /* MI_CONDITIONAL_BATCH_BUFFER_END limits address to 48b */
addr = igt_random_offset(prng, addr, min(ce->vm->total, BIT_ULL(48)),
va->size, align);
err = i915_vma_pin(va, 0, 0, addr | PIN_OFFSET_FIXED | PIN_USER); if (err) {
pr_err("Cannot pin at %llx+%llx\n", addr, va->size); goto out;
}
GEM_BUG_ON(i915_vma_offset(va) != addr); if (vb != va) {
vb_node = vb->node;
vb->node = va->node; /* overwrites the _same_ PTE */
}
/* * Now choose random dword at the 1st pinned page. * * SZ_64K pages on dg1 require that the whole PT be marked * containing 64KiB entries. So we make sure that vma * covers the whole PT, despite being randomly aligned to 64KiB * and restrict our sampling to the 2MiB PT within where * we know that we will be using 64KiB pages.
*/ if (align == SZ_64K)
addr = round_up(addr, SZ_2M);
addr = igt_random_offset(prng, addr, addr + align, 8, 8);
cs = i915_gem_object_pin_map_unlocked(batch, I915_MAP_WC);
*cs++ = MI_NOOP; /* for later termination */ /* * Sample the target to see if we spot the updated backing store. * Gen8 VCS compares immediate value with bitwise-and of two * consecutive DWORDS pointed by addr, other gen/engines compare value * with DWORD pointed by addr. Moreover we want to exercise DWORD size * invalidations. To fulfill all these requirements below values * have been chosen.
*/
*cs++ = MI_CONDITIONAL_BATCH_BUFFER_END | MI_DO_COMPARE | 2;
*cs++ = 0; /* break if *addr == 0 */
*cs++ = lower_32_bits(addr);
*cs++ = upper_32_bits(addr);
vma_set_qw(va, addr, -1);
vma_set_qw(vb, addr, 0);
/* Keep sampling until we get bored */
*cs++ = MI_BATCH_BUFFER_START | BIT(8) | 1;
*cs++ = lower_32_bits(i915_vma_offset(vma));
*cs++ = upper_32_bits(i915_vma_offset(vma));
/* * Short sleep to sanitycheck the batch is spinning before we begin. * FIXME: Why is GSC so slow?
*/ if (ce->engine->class == OTHER_CLASS)
msleep(200); else
usleep_range(10000, 20000);
/* Flip the PTE between A and B */ if (i915_gem_object_is_lmem(vb->obj))
pte_flags |= PTE_LM;
ce->vm->insert_entries(ce->vm, &vb_res, pat_index, pte_flags);
/* Flush the PTE update to concurrent HW */
tlbinv(ce->vm, addr & -length, length);
if (wait_for(i915_request_completed(rq), HZ / 2)) {
pr_err("%s: Request did not complete; the COND_BBE did not read the updated PTE\n",
ce->engine->name);
err = -EINVAL;
}
} else {
pr_err("Spinner ended unexpectedly\n");
err = -EIO;
}
i915_request_put(rq);
/* * Allocation of largest possible page size allows to test all types * of pages. To succeed with both allocations, especially in case of Small * BAR, try to allocate no more than quarter of mappable memory.
*/ if (mr && size > resource_size(&mr->io) / 4)
size = resource_size(&mr->io) / 4;
staticstruct drm_i915_gem_object *create_smem(struct intel_gt *gt)
{ /* * SZ_64K pages require covering the whole 2M PT (gen8 to tgl/dg1). * While that does not require the whole 2M block to be contiguous * it is easier to make it so, since we need that for SZ_2M pagees. * Since we randomly offset the start of the vma, we need a 4M object * so that there is a 2M range within it is suitable for SZ_64K PTE.
*/ return i915_gem_object_create_internal(gt->i915, SZ_4M);
}
/* * Check that the TLB invalidate is able to revoke an active * page. We load a page into a spinning COND_BBE loop and then * remap that page to a new physical address. The old address, and * so the loop keeps spinning, is retained in the TLB cache until * we issue an invalidate.
*/
A = create_fn(gt); if (IS_ERR(A)) return PTR_ERR(A);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.