[PATCH v6 5/6] drm/i915: Asynchronous migration selftest
Thomas Hellström
thomas.hellstrom at linux.intel.com
Mon Jan 10 14:36:44 UTC 2022
On 1/10/22 14:59, Matthew Auld wrote:
> On 07/01/2022 14:23, Thomas Hellström wrote:
>> Add a selftest to exercise asynchronous migration and -unbining.
>> Extend the gem_migrate selftest to perform the migrations while
>> depending on a spinner and a bound vma set up on the migrated
>> buffer object.
>>
>> Signed-off-by: Thomas Hellström <thomas.hellstrom at linux.intel.com>
>> ---
>> drivers/gpu/drm/i915/gem/i915_gem_object.c | 12 ++
>> drivers/gpu/drm/i915/gem/i915_gem_object.h | 3 +
>> .../drm/i915/gem/selftests/i915_gem_migrate.c | 192 ++++++++++++++++--
>> 3 files changed, 192 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c
>> b/drivers/gpu/drm/i915/gem/i915_gem_object.c
>> index d87b508b59b1..1a9e1f940a7d 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
>> @@ -756,6 +756,18 @@ i915_gem_object_get_moving_fence(struct
>> drm_i915_gem_object *obj)
>> return dma_fence_get(i915_gem_to_ttm(obj)->moving);
>> }
>> +void i915_gem_object_set_moving_fence(struct drm_i915_gem_object
>> *obj,
>> + struct dma_fence *fence)
>> +{
>> + struct dma_fence **moving = &i915_gem_to_ttm(obj)->moving;
>> +
>> + if (*moving == fence)
>> + return;
>> +
>> + dma_fence_put(*moving);
>> + *moving = dma_fence_get(fence);
>> +}
>> +
>> /**
>> * i915_gem_object_wait_moving_fence - Wait for the object's moving
>> fence if any
>> * @obj: The object whose moving fence to wait for.
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h
>> b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>> index f66d46882ea7..1d17ffff8236 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>> @@ -524,6 +524,9 @@ i915_gem_object_finish_access(struct
>> drm_i915_gem_object *obj)
>> struct dma_fence *
>> i915_gem_object_get_moving_fence(struct drm_i915_gem_object *obj);
>> +void i915_gem_object_set_moving_fence(struct drm_i915_gem_object
>> *obj,
>> + struct dma_fence *fence);
>> +
>> int i915_gem_object_wait_moving_fence(struct drm_i915_gem_object *obj,
>> bool intr);
>> diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c
>> b/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c
>> index ecb691c81d1e..d534141b2cf7 100644
>> --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c
>> +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c
>> @@ -4,8 +4,13 @@
>> */
>> #include "gt/intel_migrate.h"
>> +#include "gt/intel_gpu_commands.h"
>> #include "gem/i915_gem_ttm_move.h"
>> +#include "i915_deps.h"
>> +
>> +#include "selftests/igt_spinner.h"
>> +
>> static int igt_fill_check_buffer(struct drm_i915_gem_object *obj,
>> bool fill)
>> {
>> @@ -101,7 +106,8 @@ static int igt_same_create_migrate(void *arg)
>> }
>> static int lmem_pages_migrate_one(struct i915_gem_ww_ctx *ww,
>> - struct drm_i915_gem_object *obj)
>> + struct drm_i915_gem_object *obj,
>> + struct i915_vma *vma)
>> {
>> int err;
>> @@ -109,6 +115,24 @@ static int lmem_pages_migrate_one(struct
>> i915_gem_ww_ctx *ww,
>> if (err)
>> return err;
>> + if (vma) {
>> + err = i915_vma_pin_ww(vma, ww, obj->base.size, 0,
>> + 0UL | PIN_OFFSET_FIXED |
>> + PIN_USER);
>> + if (err) {
>> + if (err != -EINTR && err != ERESTARTSYS &&
>> + err != -EDEADLK)
>> + pr_err("Failed to pin vma.\n");
>> + return err;
>> + }
>> +
>> + i915_vma_unpin(vma);
>> + }
>> +
>> + /*
>> + * Migration will implicitly unbind (asynchronously) any bound
>> + * vmas.
>> + */
>> if (i915_gem_object_is_lmem(obj)) {
>> err = i915_gem_object_migrate(obj, ww, INTEL_REGION_SMEM);
>> if (err) {
>> @@ -149,11 +173,15 @@ static int lmem_pages_migrate_one(struct
>> i915_gem_ww_ctx *ww,
>> return err;
>> }
>> -static int igt_lmem_pages_migrate(void *arg)
>> +static int __igt_lmem_pages_migrate(struct intel_gt *gt,
>> + struct i915_address_space *vm,
>> + struct i915_deps *deps,
>> + struct igt_spinner *spin,
>> + struct dma_fence *spin_fence)
>> {
>> - struct intel_gt *gt = arg;
>> struct drm_i915_private *i915 = gt->i915;
>> struct drm_i915_gem_object *obj;
>> + struct i915_vma *vma = NULL;
>> struct i915_gem_ww_ctx ww;
>> struct i915_request *rq;
>> int err;
>> @@ -165,6 +193,14 @@ static int igt_lmem_pages_migrate(void *arg)
>> if (IS_ERR(obj))
>> return PTR_ERR(obj);
>> + if (vm) {
>> + vma = i915_vma_instance(obj, vm, NULL);
>> + if (IS_ERR(vma)) {
>> + err = PTR_ERR(vma);
>> + goto out_put;
>> + }
>> + }
>> +
>> /* Initial GPU fill, sync, CPU initialization. */
>> for_i915_gem_ww(&ww, err, true) {
>> err = i915_gem_object_lock(obj, &ww);
>> @@ -175,25 +211,23 @@ static int igt_lmem_pages_migrate(void *arg)
>> if (err)
>> continue;
>> - err = intel_migrate_clear(>->migrate, &ww, NULL,
>> + err = intel_migrate_clear(>->migrate, &ww, deps,
>> obj->mm.pages->sgl, obj->cache_level,
>> i915_gem_object_is_lmem(obj),
>> 0xdeadbeaf, &rq);
>> if (rq) {
>> dma_resv_add_excl_fence(obj->base.resv, &rq->fence);
>> + i915_gem_object_set_moving_fence(obj, &rq->fence);
>> i915_request_put(rq);
>> }
>> if (err)
>> continue;
>> - err = i915_gem_object_wait(obj, I915_WAIT_INTERRUPTIBLE,
>> - 5 * HZ);
>> - if (err)
>> - continue;
>> -
>> - err = igt_fill_check_buffer(obj, true);
>> - if (err)
>> - continue;
>> + if (!vma) {
>> + err = igt_fill_check_buffer(obj, true);
>> + if (err)
>> + continue;
>
> Don't we need some kind of sync in here?
Thanks for reviewing!
That sync is taken care of by the moving fence which is waited for when
we first map the buffer.
>
> Otherwise,
> Reviewed-by: Matthew Auld <matthew.auld at intel.com>
>
/Thomas
More information about the dri-devel
mailing list