[Intel-gfx] [PATCH 16/21] drm/i915/selftests: huge page tests
Matthew Auld
matthew.william.auld at gmail.com
Thu Jul 6 11:05:55 UTC 2017
On 3 July 2017 at 15:48, Chris Wilson <chris at chris-wilson.co.uk> wrote:
> Quoting Matthew Auld (2017-07-03 15:14:58)
>> +static struct i915_vma *
>> +gpu_write_dw(struct i915_vma *vma, u64 offset, u32 value)
>> +{
>> + struct drm_i915_private *i915 = to_i915(vma->obj->base.dev);
>> + struct drm_i915_gem_object *obj;
>> + struct i915_vma *batch;
>> + unsigned int size;
>> + u32 *cmd;
>> + int err;
>> +
>> + GEM_BUG_ON(INTEL_GEN(i915) < 8);
>
> Didn't you enable large pages for snb and earlier?
So run the huge_write test regardless of the supported gtt page sizes?
>
>> +static int gpu_write(struct i915_vma *vma,
>> + struct i915_gem_context *ctx,
>> + unsigned long offset,
>> + u32 value)
>> +{
>> + struct drm_i915_private *i915 = to_i915(vma->obj->base.dev);
>> + struct drm_i915_gem_request *rq;
>> + struct i915_vma *batch;
>> + int flags = 0;
>> + int err;
>> +
>> + batch = gpu_write_dw(vma, offset, value);
>> + if (IS_ERR(batch))
>> + return PTR_ERR(batch);
>> +
>> + rq = i915_gem_request_alloc(i915->engine[RCS], ctx);
>> + if (IS_ERR(rq)) {
>> + err = PTR_ERR(rq);
>> + goto err_batch;
>> + }
>> +
>> + err = rq->engine->emit_flush(rq, EMIT_INVALIDATE);
>> + if (err)
>> + goto err_request;
>> +
>> + err = i915_switch_context(rq);
>> + if (err)
>> + goto err_request;
>> +
>> + err = rq->engine->emit_bb_start(rq,
>> + batch->node.start, batch->node.size,
>> + flags);
>> + if (err)
>> + goto err_request;
>> +
>> + i915_vma_move_to_active(batch, rq, 0);
>> + i915_gem_object_set_active_reference(batch->obj);
>> + i915_vma_unpin(batch);
>> + i915_vma_close(batch);
>> +
>> + i915_vma_move_to_active(vma, rq, 0);
>> +
>> + reservation_object_lock(vma->obj->resv, NULL);
>
> vma->resv
>
>> + reservation_object_add_excl_fence(vma->obj->resv, &rq->fence);
>> + reservation_object_unlock(vma->obj->resv);
>> +
>> + __i915_add_request(rq, true);
>> +
>> + return 0;
>> +
>> +err_request:
>> + __i915_add_request(rq, false);
>> +err_batch:
>> + i915_vma_unpin(batch);
>
> Leaking batch. Just tie the lifetime of the batch to the request
> immediately after allocating the request.
>
>> +
>> + return err;
>> +}
>> +
>> +static inline int igt_can_allocate_thp(struct drm_i915_private *i915)
>> +{
>> + return HAS_PAGE_SIZE(i915, I915_GTT_PAGE_SIZE_2M) &&
>> + has_transparent_hugepage();
>> +}
>> +
>> +static int igt_ppgtt_write_huge(void *arg)
>> +{
>> + struct i915_hw_ppgtt *ppgtt = arg;
>> + struct drm_i915_private *i915 = ppgtt->base.i915;
>> + struct drm_i915_gem_object *obj;
>> + const unsigned int page_sizes[] = {
>> + I915_GTT_PAGE_SIZE_64K,
>> + I915_GTT_PAGE_SIZE_2M,
>> + };
>> + struct i915_vma *vma;
>> + int err = 0;
>> + int i;
>> +
>> + if (!igt_can_allocate_thp(i915))
>> + return 0;
>> +
>> + /* Sanity check that the HW uses huge-pages correctly */
>> +
>> + ppgtt = i915->kernel_context->ppgtt;
>> +
>> + obj = i915_gem_object_create(i915, I915_GTT_PAGE_SIZE_2M);
>> + if (IS_ERR(obj))
>> + return PTR_ERR(obj);
>
> 2M is MAX_ORDER, so you don't need thp for this and can just use
> i915_gem_object_create_internal() (or both, once to test without relying
> on thp, perhaps more common, then once to test thp shmemfs).
>
>> + err = i915_gem_object_pin_pages(obj);
>> + if (err)
>> + goto out_put;
>> +
>> + GEM_BUG_ON(!obj->mm.page_sizes.sg);
>> +
>> + if (obj->mm.page_sizes.sg < I915_GTT_PAGE_SIZE_2M) {
>> + pr_err("Failed to allocate huge pages\n");
>> + err = -EINVAL;
>
> Failure? Or just unable to test? Nothing forces the kernel to give you
> contiguous space.
>
>> + goto out_unpin;
>> + }
>> +
>> + vma = i915_vma_instance(obj, &ppgtt->base, NULL);
>> + if (IS_ERR(vma)) {
>> + err = PTR_ERR(vma);
>> + goto out_unpin;
>> + }
>> +
>> + for (i = 0; i < ARRAY_SIZE(page_sizes); ++i) {
>> + unsigned int page_size = page_sizes[i];
>> + u32 *map;
>> +
>> + if (!HAS_PAGE_SIZE(i915, page_size))
>> + continue;
>> +
>> + /* Force the page size */
>> + obj->mm.page_sizes.sg = page_size;
>> +
>> + err = i915_gem_object_set_to_gtt_domain(obj, true);
>> + if (err)
>> + goto out_close;
>
> Gets in the way of the important details, make it coherent and get rid
> of this.
Just make it coherent?
>
>> + err = i915_vma_pin(vma, 0, 0, PIN_USER);
>> + if (err)
>> + goto out_close;
>
> Move the unbind above this:
>
> /* Force the page size */
> i915_vma_unbind(vma);
>
> obj->m.page_sizes.sg = page_size;
>
> i915_vma_pin(vma);
> GEM_BUG_ON(vma->page_sizes.sg != page_size);
>
>> +
>> + GEM_BUG_ON(obj->mm.page_sizes.gtt);
>> + GEM_BUG_ON(vma->page_sizes.sg != page_size);
>> + GEM_BUG_ON(!vma->page_sizes.phys);
>> +
>> + GEM_BUG_ON(vma->page_sizes.gtt != page_size);
>> + GEM_BUG_ON(!IS_ALIGNED(vma->node.start, I915_GTT_PAGE_SIZE_2M));
>> + GEM_BUG_ON(!IS_ALIGNED(vma->node.size, I915_GTT_PAGE_SIZE_2M));
>> +
>> + err = gpu_write(vma, i915->kernel_context, 0, page_size);
>> + if (err) {
>> + i915_vma_unpin(vma);
>> + goto out_close;
>> + }
>> +
>> + err = i915_gem_object_set_to_cpu_domain(obj, false);
>> + if (err) {
>> + i915_vma_unpin(vma);
>> + goto out_close;
>> + }
>
> Again, this is getting in the way of the important details.
>
>> + i915_vma_unpin(vma);
>> + err = i915_vma_unbind(vma);
>> + if (err)
>> + goto out_close;
>> +
>> + map = i915_gem_object_pin_map(obj, I915_MAP_WB);
>> + if (IS_ERR(map)) {
>> + err = PTR_ERR(map);
>> + goto out_close;
>> + }
>
> Do we need to test different PTE bits?
So WB vs WC? Or are you talking about the gtt PTEs?
>
> If you don't make this coherent, use
>
> map = pin_map(obj);
> set_to_cpu_domain(obj);
>
> for_each_page()
> test
>
> set_to_gtt_domain(obj);
> unpin_map(obj);
>
>> +
>> + GEM_BUG_ON(map[0] != page_size);
>
> This is the essential test being performed. Check it, and report an
> error properly. Check every page at different offsets!
>
>> +
>> + i915_gem_object_unpin_map(obj);
>> + }
>> +
>> +out_close:
>> + i915_vma_close(vma);
>> +out_unpin:
>> + i915_gem_object_unpin_pages(obj);
>> +out_put:
>> + i915_gem_object_put(obj);
>> +
>> + return err;
>> +}
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
More information about the Intel-gfx
mailing list