Mock testing to ensure we can create and lookup partial VMA. Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/selftests/i915_vma.c | 179 ++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c index 95c5db2b0881..7511f383868c 100644 --- a/drivers/gpu/drm/i915/selftests/i915_vma.c +++ b/drivers/gpu/drm/i915/selftests/i915_vma.c @@ -416,12 +416,191 @@ static int igt_vma_rotate(void *arg) return err; } +static bool assert_partial(struct drm_i915_gem_object *obj, + struct i915_vma *vma, + unsigned long offset, + unsigned long size) +{ + struct sgt_iter sgt; + dma_addr_t dma; + + for_each_sgt_dma(dma, sgt, vma->pages) { + dma_addr_t src; + + if (!size) { + pr_err("Partial scattergather list too long\n"); + return false; + } + + src = i915_gem_object_get_dma_address(obj, offset); + if (src != dma) { + pr_err("DMA mismatch for partial page offset %lu\n", + offset); + return false; + } + + offset++; + size--; + } + + return true; +} + +static int igt_vma_partial(void *arg) +{ + struct drm_i915_private *i915 = arg; + const unsigned int npages = 1021; /* prime! */ + struct drm_i915_gem_object *obj; + unsigned int sz, offset, loop; + struct i915_vma *vma; + int err = -ENOMEM; + + obj = i915_gem_object_create_internal(i915, npages*PAGE_SIZE); + if (IS_ERR(obj)) + goto err; + + for (loop = 0; loop <= 1; loop++) { /* exercise both create/lookup */ + unsigned int count, nvma; + + nvma = loop; + for_each_prime_number_from(sz, 1, npages) { + for_each_prime_number_from(offset, 0, npages - sz) { + struct i915_ggtt_view view; + + view.type = I915_GGTT_VIEW_PARTIAL; + view.partial.offset_size = + offset << INTEL_PARTIAL_SIZE_BITS | (sz - 1); + + if (sz == npages) + view.type = I915_GGTT_VIEW_NORMAL; + + vma = i915_gem_obj_lookup_or_create_vma(obj, &i915->ggtt.base, &view); + if (IS_ERR(vma)) { + err = PTR_ERR(vma); + goto err_object; + } + + if (!i915_vma_is_ggtt(vma)) { + pr_err("VMA is not in the GGTT!\n"); + err = -EINVAL; + goto err_object; + } + + err = i915_vma_pin(vma, 0, 0, PIN_GLOBAL); + if (err) + goto err_object; + + if (vma->size != sz*PAGE_SIZE) { + pr_err("VMA is wrong size, expected %lu, found %llu\n", + sz*PAGE_SIZE, vma->size); + err = -EINVAL; + goto err_object; + } + + if (vma->node.size < vma->size) { + pr_err("VMA binding too small, expected %llu, found %llu\n", + vma->size, vma->node.size); + err = -EINVAL; + goto err_object; + } + + if (view.type != I915_GGTT_VIEW_NORMAL) { + if (memcmp(&vma->ggtt_view, &view, sizeof(view))) { + pr_err("VMA mismatch upon creation!\n"); + err = -EINVAL; + goto err_object; + } + + if (vma->pages == obj->mm.pages) { + pr_err("VMA using unrotated object pages!\n"); + err = -EINVAL; + goto err_object; + } + } + + if (!assert_partial(obj, vma, offset, sz)) { + pr_err("Inconsistent partial pages for (offset=%d, size=%d)\n", offset, sz); + err = -EINVAL; + goto err_object; + } + + i915_vma_unpin(vma); + nvma++; + } + } + + count = loop; + list_for_each_entry(vma, &obj->vma_list, obj_link) + count++; + if (count != nvma) { + pr_err("All partial vma were not recorded on the obj->vma_list: found %u, expected %u\n", + count, nvma); + err = -EINVAL; + goto err_object; + } + + /* Create a mapping for the entire object, just for extra fun */ + vma = i915_gem_obj_lookup_or_create_vma(obj, + &i915->ggtt.base, + NULL); + if (IS_ERR(vma)) { + err = PTR_ERR(vma); + goto err_object; + } + + if (!i915_vma_is_ggtt(vma)) { + pr_err("VMA is not in the GGTT!\n"); + err = -EINVAL; + goto err_object; + } + + err = i915_vma_pin(vma, 0, 0, PIN_GLOBAL); + if (err) + goto err_object; + + if (vma->size != obj->base.size) { + pr_err("VMA is wrong size, expected %lu, found %llu\n", + sz*PAGE_SIZE, vma->size); + err = -EINVAL; + goto err_object; + } + + if (vma->node.size < vma->size) { + pr_err("VMA binding too small, expected %llu, found %llu\n", + vma->size, vma->node.size); + err = -EINVAL; + goto err_object; + } + + if (vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL) { + pr_err("Not the normal ggtt view! Found %d\n", + vma->ggtt_view.type); + err = -EINVAL; + goto err_object; + } + + if (vma->pages != obj->mm.pages) { + pr_err("VMA not using object pages!\n"); + err = -EINVAL; + goto err_object; + } + + i915_vma_unpin(vma); + } + +err_object: + i915_gem_object_put(obj); +err: + return err; +} + int i915_vma_mock_selftests(void) { static const struct i915_subtest tests[] = { SUBTEST(igt_vma_create), SUBTEST(igt_vma_pin1), SUBTEST(igt_vma_rotate), + SUBTEST(igt_vma_partial), }; struct drm_i915_private *i915; int err; -- 2.11.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx