Skip to content

Commit

Permalink
drm/i915: Serialise with engine-pm around requests on the kernel_context
Browse files Browse the repository at this point in the history
As the engine->kernel_context is used within the engine-pm barrier, we
have to be careful when emitting requests outside of the barrier, as the
strict timeline locking rules do not apply. Instead, we must ensure the
engine_park() cannot be entered as we build the request, which is
simplest by taking an explicit engine-pm wakeref around the request
construction.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191125105858.1718307-1-chris@chris-wilson.co.uk
  • Loading branch information
Chris Wilson committed Nov 25, 2019
1 parent da0ef77 commit de5825b
Show file tree
Hide file tree
Showing 19 changed files with 119 additions and 33 deletions.
3 changes: 2 additions & 1 deletion drivers/gpu/drm/i915/gem/i915_gem_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
#include <drm/i915_drm.h>

#include "gt/intel_engine_heartbeat.h"
#include "gt/intel_engine_pm.h"
#include "gt/intel_engine_user.h"
#include "gt/intel_lrc_reg.h"
#include "gt/intel_ring.h"
Expand Down Expand Up @@ -1265,7 +1266,7 @@ gen8_modify_rpcs(struct intel_context *ce, struct intel_sseu sseu)
if (!intel_context_is_pinned(ce))
return 0;

rq = i915_request_create(ce->engine->kernel_context);
rq = intel_engine_create_kernel_request(ce->engine);
if (IS_ERR(rq))
return PTR_ERR(rq);

Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ static int __igt_client_fill(struct intel_engine_cs *engine)

prandom_seed_state(&prng, i915_selftest.random_seed);

intel_engine_pm_get(engine);
do {
const u32 max_block_size = S16_MAX * PAGE_SIZE;
u32 sz = min_t(u64, ce->vm->total >> 4, prandom_u32_state(&prng));
Expand Down Expand Up @@ -99,6 +100,7 @@ static int __igt_client_fill(struct intel_engine_cs *engine)
err_flush:
if (err == -ENOMEM)
err = 0;
intel_engine_pm_put(engine);

return err;
}
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <linux/prime_numbers.h>

#include "gt/intel_engine_pm.h"
#include "gt/intel_gt.h"
#include "gt/intel_gt_pm.h"
#include "gt/intel_ring.h"
Expand Down Expand Up @@ -200,7 +201,7 @@ static int gpu_set(struct context *ctx, unsigned long offset, u32 v)
if (IS_ERR(vma))
return PTR_ERR(vma);

rq = i915_request_create(ctx->engine->kernel_context);
rq = intel_engine_create_kernel_request(ctx->engine);
if (IS_ERR(rq)) {
i915_vma_unpin(vma);
return PTR_ERR(rq);
Expand Down
7 changes: 6 additions & 1 deletion drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <linux/prime_numbers.h>

#include "gem/i915_gem_pm.h"
#include "gt/intel_engine_pm.h"
#include "gt/intel_gt.h"
#include "gt/intel_gt_requests.h"
#include "gt/intel_reset.h"
Expand Down Expand Up @@ -1190,9 +1191,11 @@ __sseu_test(const char *name,
struct igt_spinner *spin = NULL;
int ret;

intel_engine_pm_get(ce->engine);

ret = __sseu_prepare(name, flags, ce, &spin);
if (ret)
return ret;
goto out_pm;

ret = intel_context_reconfigure_sseu(ce, sseu);
if (ret)
Expand All @@ -1207,6 +1210,8 @@ __sseu_test(const char *name,
igt_spinner_fini(spin);
kfree(spin);
}
out_pm:
intel_engine_pm_put(ce->engine);
return ret;
}

Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <linux/prime_numbers.h>

#include "gt/intel_engine_pm.h"
#include "gt/intel_gt.h"
#include "gt/intel_gt_pm.h"
#include "huge_gem_object.h"
Expand Down Expand Up @@ -536,7 +537,7 @@ static int make_obj_busy(struct drm_i915_gem_object *obj)
if (err)
return err;

rq = i915_request_create(engine->kernel_context);
rq = intel_engine_create_kernel_request(engine);
if (IS_ERR(rq)) {
i915_vma_unpin(vma);
return PTR_ERR(rq);
Expand Down
18 changes: 13 additions & 5 deletions drivers/gpu/drm/i915/gem/selftests/i915_gem_object_blt.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ static int __perf_fill_blt(struct drm_i915_gem_object *obj)
if (!engine)
return 0;

intel_engine_pm_get(engine);
for (pass = 0; pass < ARRAY_SIZE(t); pass++) {
struct intel_context *ce = engine->kernel_context;
ktime_t t0, t1;
Expand All @@ -49,17 +50,20 @@ static int __perf_fill_blt(struct drm_i915_gem_object *obj)

err = i915_gem_object_fill_blt(obj, ce, 0);
if (err)
return err;
break;

err = i915_gem_object_wait(obj,
I915_WAIT_ALL,
MAX_SCHEDULE_TIMEOUT);
if (err)
return err;
break;

t1 = ktime_get();
t[pass] = ktime_sub(t1, t0);
}
intel_engine_pm_put(engine);
if (err)
return err;

sort(t, ARRAY_SIZE(t), sizeof(*t), wrap_ktime_compare, NULL);
pr_info("%s: blt %zd KiB fill: %lld MiB/s\n",
Expand Down Expand Up @@ -109,33 +113,37 @@ static int __perf_copy_blt(struct drm_i915_gem_object *src,
struct intel_engine_cs *engine;
ktime_t t[5];
int pass;
int err = 0;

engine = intel_engine_lookup_user(i915,
I915_ENGINE_CLASS_COPY,
inst++);
if (!engine)
return 0;

intel_engine_pm_get(engine);
for (pass = 0; pass < ARRAY_SIZE(t); pass++) {
struct intel_context *ce = engine->kernel_context;
ktime_t t0, t1;
int err;

t0 = ktime_get();

err = i915_gem_object_copy_blt(src, dst, ce);
if (err)
return err;
break;

err = i915_gem_object_wait(dst,
I915_WAIT_ALL,
MAX_SCHEDULE_TIMEOUT);
if (err)
return err;
break;

t1 = ktime_get();
t[pass] = ktime_sub(t1, t0);
}
intel_engine_pm_put(engine);
if (err)
return err;

sort(t, ARRAY_SIZE(t), sizeof(*t), wrap_ktime_compare, NULL);
pr_info("%s: blt %zd KiB copy: %lld MiB/s\n",
Expand Down
14 changes: 11 additions & 3 deletions drivers/gpu/drm/i915/gt/intel_engine_heartbeat.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,18 +215,26 @@ int intel_engine_pulse(struct intel_engine_cs *engine)
int intel_engine_flush_barriers(struct intel_engine_cs *engine)
{
struct i915_request *rq;
int err = 0;

if (llist_empty(&engine->barrier_tasks))
return 0;

if (!intel_engine_pm_get_if_awake(engine))
return 0;

rq = i915_request_create(engine->kernel_context);
if (IS_ERR(rq))
return PTR_ERR(rq);
if (IS_ERR(rq)) {
err = PTR_ERR(rq);
goto out_rpm;
}

idle_pulse(engine, rq);
i915_request_add(rq);

return 0;
out_rpm:
intel_engine_pm_put(engine);
return err;
}

#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
Expand Down
21 changes: 21 additions & 0 deletions drivers/gpu/drm/i915/gt/intel_engine_pm.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#ifndef INTEL_ENGINE_PM_H
#define INTEL_ENGINE_PM_H

#include "i915_request.h"
#include "intel_engine_types.h"
#include "intel_wakeref.h"

Expand Down Expand Up @@ -41,6 +42,26 @@ static inline void intel_engine_pm_flush(struct intel_engine_cs *engine)
intel_wakeref_unlock_wait(&engine->wakeref);
}

static inline struct i915_request *
intel_engine_create_kernel_request(struct intel_engine_cs *engine)
{
struct i915_request *rq;

/*
* The engine->kernel_context is special as it is used inside
* the engine-pm barrier (see __engine_park()), circumventing
* the usual mutexes and relying on the engine-pm barrier
* instead. So whenever we use the engine->kernel_context
* outside of the barrier, we must manually handle the
* engine wakeref to serialise with the use inside.
*/
intel_engine_pm_get(engine);
rq = i915_request_create(engine->kernel_context);
intel_engine_pm_put(engine);

return rq;
}

void intel_engine_init__pm(struct intel_engine_cs *engine);

#endif /* INTEL_ENGINE_PM_H */
3 changes: 3 additions & 0 deletions drivers/gpu/drm/i915/gt/intel_workarounds.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "i915_drv.h"
#include "intel_context.h"
#include "intel_engine_pm.h"
#include "intel_gt.h"
#include "intel_ring.h"
#include "intel_workarounds.h"
Expand Down Expand Up @@ -1582,7 +1583,9 @@ static int engine_wa_list_verify(struct intel_context *ce,
if (IS_ERR(vma))
return PTR_ERR(vma);

intel_engine_pm_get(ce->engine);
rq = intel_context_create_request(ce);
intel_engine_pm_put(ce->engine);
if (IS_ERR(rq)) {
err = PTR_ERR(rq);
goto err_vma;
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/gt/selftest_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ static int __live_context_size(struct intel_engine_cs *engine,
goto err_unpin;

/* Force the context switch */
rq = i915_request_create(engine->kernel_context);
rq = intel_engine_create_kernel_request(engine);
if (IS_ERR(rq)) {
err = PTR_ERR(rq);
goto err_unpin;
Expand Down
12 changes: 12 additions & 0 deletions drivers/gpu/drm/i915/gt/selftest_engine_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,18 @@ static int perf_mi_bb_start(void *arg)
u32 cycles[COUNT];
int i;

intel_engine_pm_get(engine);

batch = create_empty_batch(ce);
if (IS_ERR(batch)) {
err = PTR_ERR(batch);
intel_engine_pm_put(engine);
break;
}

err = i915_vma_sync(batch);
if (err) {
intel_engine_pm_put(engine);
i915_vma_put(batch);
break;
}
Expand Down Expand Up @@ -180,6 +184,7 @@ static int perf_mi_bb_start(void *arg)
cycles[i] = rq->hwsp_seqno[3] - rq->hwsp_seqno[2];
}
i915_vma_put(batch);
intel_engine_pm_put(engine);
if (err)
break;

Expand Down Expand Up @@ -251,29 +256,35 @@ static int perf_mi_noop(void *arg)
u32 cycles[COUNT];
int i;

intel_engine_pm_get(engine);

base = create_empty_batch(ce);
if (IS_ERR(base)) {
err = PTR_ERR(base);
intel_engine_pm_put(engine);
break;
}

err = i915_vma_sync(base);
if (err) {
i915_vma_put(base);
intel_engine_pm_put(engine);
break;
}

nop = create_nop_batch(ce);
if (IS_ERR(nop)) {
err = PTR_ERR(nop);
i915_vma_put(base);
intel_engine_pm_put(engine);
break;
}

err = i915_vma_sync(nop);
if (err) {
i915_vma_put(nop);
i915_vma_put(base);
intel_engine_pm_put(engine);
break;
}

Expand Down Expand Up @@ -327,6 +338,7 @@ static int perf_mi_noop(void *arg)
}
i915_vma_put(nop);
i915_vma_put(base);
intel_engine_pm_put(engine);
if (err)
break;

Expand Down
6 changes: 3 additions & 3 deletions drivers/gpu/drm/i915/gt/selftest_lrc.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ release_queue(struct intel_engine_cs *engine,
struct i915_request *rq;
u32 *cs;

rq = i915_request_create(engine->kernel_context);
rq = intel_engine_create_kernel_request(engine);
if (IS_ERR(rq))
return PTR_ERR(rq);

Expand Down Expand Up @@ -497,7 +497,7 @@ static struct i915_request *nop_request(struct intel_engine_cs *engine)
{
struct i915_request *rq;

rq = i915_request_create(engine->kernel_context);
rq = intel_engine_create_kernel_request(engine);
if (IS_ERR(rq))
return rq;

Expand Down Expand Up @@ -3698,7 +3698,7 @@ static int gpr_make_dirty(struct intel_engine_cs *engine)
u32 *cs;
int n;

rq = i915_request_create(engine->kernel_context);
rq = intel_engine_create_kernel_request(engine);
if (IS_ERR(rq))
return PTR_ERR(rq);

Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/gt/selftest_mocs.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,9 @@ static int live_mocs_kernel(void *arg)
return err;

for_each_engine(engine, gt, id) {
intel_engine_pm_get(engine);
err = check_mocs_engine(&mocs, engine->kernel_context);
intel_engine_pm_put(engine);
if (err)
break;
}
Expand Down
6 changes: 2 additions & 4 deletions drivers/gpu/drm/i915/gt/selftest_timeline.c
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ tl_write(struct intel_timeline *tl, struct intel_engine_cs *engine, u32 value)
goto out;
}

rq = i915_request_create(engine->kernel_context);
rq = intel_engine_create_kernel_request(engine);
if (IS_ERR(rq))
goto out_unpin;

Expand Down Expand Up @@ -675,9 +675,7 @@ static int live_hwsp_wrap(void *arg)
if (!intel_engine_can_store_dword(engine))
continue;

intel_engine_pm_get(engine);
rq = i915_request_create(engine->kernel_context);
intel_engine_pm_put(engine);
rq = intel_engine_create_kernel_request(engine);
if (IS_ERR(rq)) {
err = PTR_ERR(rq);
goto out;
Expand Down
Loading

0 comments on commit de5825b

Please sign in to comment.