Commit bfdf8b1d authored by Maarten Lankhorst's avatar Maarten Lankhorst Committed by Joonas Lahtinen
Browse files

drm/i915: Use ww locking in intel_renderstate.



We want to start using ww locking in intel_context_pin, for this
we need to lock multiple objects, and the single i915_gem_object_lock
is not enough.

Convert to using ww-waiting, and make sure we always pin intel_context_state,
even if we don't have a renderstate object.

Signed-off-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: default avatarThomas Hellström <thomas.hellstrom@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200819140904.1708856-10-maarten.lankhorst@linux.intel.com


Signed-off-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
parent c43ce123
Loading
Loading
Loading
Loading
+12 −9
Original line number Diff line number Diff line
@@ -406,21 +406,20 @@ static int __engines_record_defaults(struct intel_gt *gt)
		/* We must be able to switch to something! */
		GEM_BUG_ON(!engine->kernel_context);

		err = intel_renderstate_init(&so, engine);
		if (err)
			goto out;

		ce = intel_context_create(engine);
		if (IS_ERR(ce)) {
			err = PTR_ERR(ce);
			goto out;
		}

		rq = intel_context_create_request(ce);
		err = intel_renderstate_init(&so, ce);
		if (err)
			goto err;

		rq = i915_request_create(ce);
		if (IS_ERR(rq)) {
			err = PTR_ERR(rq);
			intel_context_put(ce);
			goto out;
			goto err_fini;
		}

		err = intel_engine_emit_ctx_wa(rq);
@@ -434,10 +433,14 @@ static int __engines_record_defaults(struct intel_gt *gt)
err_rq:
		requests[id] = i915_request_get(rq);
		i915_request_add(rq);
		intel_renderstate_fini(&so);
		if (err)
err_fini:
		intel_renderstate_fini(&so, ce);
err:
		if (err) {
			intel_context_put(ce);
			goto out;
		}
	}

	/* Flush the default context image to memory, and enable powersaving. */
	if (intel_gt_wait_for_idle(gt, I915_GEM_IDLE_TIMEOUT) == -ETIME) {
+53 −20
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@

#include "i915_drv.h"
#include "intel_renderstate.h"
#include "gt/intel_context.h"
#include "intel_ring.h"

static const struct intel_renderstate_rodata *
@@ -157,17 +158,16 @@ static int render_state_setup(struct intel_renderstate *so,
#undef OUT_BATCH

int intel_renderstate_init(struct intel_renderstate *so,
			   struct intel_engine_cs *engine)
			   struct intel_context *ce)
{
	struct drm_i915_gem_object *obj;
	struct intel_engine_cs *engine = ce->engine;
	struct drm_i915_gem_object *obj = NULL;
	int err;

	memset(so, 0, sizeof(*so));

	so->rodata = render_state_get_rodata(engine);
	if (!so->rodata)
		return 0;

	if (so->rodata) {
		if (so->rodata->batch_items * 4 > PAGE_SIZE)
			return -EINVAL;

@@ -180,10 +180,25 @@ int intel_renderstate_init(struct intel_renderstate *so,
			err = PTR_ERR(so->vma);
			goto err_obj;
		}
	}

	i915_gem_ww_ctx_init(&so->ww, true);
retry:
	err = intel_context_pin(ce);
	if (err)
		goto err_fini;

	/* return early if there's nothing to setup */
	if (!err && !so->rodata)
		return 0;

	err = i915_gem_object_lock(so->vma->obj, &so->ww);
	if (err)
		goto err_context;

	err = i915_vma_pin(so->vma, 0, 0, PIN_GLOBAL | PIN_HIGH);
	if (err)
		goto err_obj;
		goto err_context;

	err = render_state_setup(so, engine->i915);
	if (err)
@@ -193,7 +208,17 @@ int intel_renderstate_init(struct intel_renderstate *so,

err_unpin:
	i915_vma_unpin(so->vma);
err_context:
	intel_context_unpin(ce);
err_fini:
	if (err == -EDEADLK) {
		err = i915_gem_ww_ctx_backoff(&so->ww);
		if (!err)
			goto retry;
	}
	i915_gem_ww_ctx_fini(&so->ww);
err_obj:
	if (obj)
		i915_gem_object_put(obj);
	so->vma = NULL;
	return err;
@@ -208,11 +233,9 @@ int intel_renderstate_emit(struct intel_renderstate *so,
	if (!so->vma)
		return 0;

	i915_vma_lock(so->vma);
	err = i915_request_await_object(rq, so->vma->obj, false);
	if (err == 0)
		err = i915_vma_move_to_active(so->vma, rq, 0);
	i915_vma_unlock(so->vma);
	if (err)
		return err;

@@ -233,7 +256,17 @@ int intel_renderstate_emit(struct intel_renderstate *so,
	return 0;
}

void intel_renderstate_fini(struct intel_renderstate *so)
void intel_renderstate_fini(struct intel_renderstate *so,
			    struct intel_context *ce)
{
	i915_vma_unpin_and_release(&so->vma, 0);
	if (so->vma) {
		i915_vma_unpin(so->vma);
		i915_vma_close(so->vma);
	}

	intel_context_unpin(ce);
	i915_gem_ww_ctx_fini(&so->ww);

	if (so->vma)
		i915_gem_object_put(so->vma->obj);
}
+6 −3
Original line number Diff line number Diff line
@@ -25,9 +25,10 @@
#define _INTEL_RENDERSTATE_H_

#include <linux/types.h>
#include "i915_gem.h"

struct i915_request;
struct intel_engine_cs;
struct intel_context;
struct i915_vma;

struct intel_renderstate_rodata {
@@ -49,6 +50,7 @@ extern const struct intel_renderstate_rodata gen8_null_state;
extern const struct intel_renderstate_rodata gen9_null_state;

struct intel_renderstate {
	struct i915_gem_ww_ctx ww;
	const struct intel_renderstate_rodata *rodata;
	struct i915_vma *vma;
	u32 batch_offset;
@@ -58,9 +60,10 @@ struct intel_renderstate {
};

int intel_renderstate_init(struct intel_renderstate *so,
			   struct intel_engine_cs *engine);
			   struct intel_context *ce);
int intel_renderstate_emit(struct intel_renderstate *so,
			   struct i915_request *rq);
void intel_renderstate_fini(struct intel_renderstate *so);
void intel_renderstate_fini(struct intel_renderstate *so,
			    struct intel_context *ce);

#endif /* _INTEL_RENDERSTATE_H_ */