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

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.comSigned-off-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
parent c43ce123
...@@ -406,21 +406,20 @@ static int __engines_record_defaults(struct intel_gt *gt) ...@@ -406,21 +406,20 @@ static int __engines_record_defaults(struct intel_gt *gt)
/* We must be able to switch to something! */ /* We must be able to switch to something! */
GEM_BUG_ON(!engine->kernel_context); GEM_BUG_ON(!engine->kernel_context);
err = intel_renderstate_init(&so, engine);
if (err)
goto out;
ce = intel_context_create(engine); ce = intel_context_create(engine);
if (IS_ERR(ce)) { if (IS_ERR(ce)) {
err = PTR_ERR(ce); err = PTR_ERR(ce);
goto out; 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)) { if (IS_ERR(rq)) {
err = PTR_ERR(rq); err = PTR_ERR(rq);
intel_context_put(ce); goto err_fini;
goto out;
} }
err = intel_engine_emit_ctx_wa(rq); err = intel_engine_emit_ctx_wa(rq);
...@@ -434,10 +433,14 @@ static int __engines_record_defaults(struct intel_gt *gt) ...@@ -434,10 +433,14 @@ static int __engines_record_defaults(struct intel_gt *gt)
err_rq: err_rq:
requests[id] = i915_request_get(rq); requests[id] = i915_request_get(rq);
i915_request_add(rq); i915_request_add(rq);
intel_renderstate_fini(&so); err_fini:
if (err) intel_renderstate_fini(&so, ce);
err:
if (err) {
intel_context_put(ce);
goto out; goto out;
} }
}
/* Flush the default context image to memory, and enable powersaving. */ /* Flush the default context image to memory, and enable powersaving. */
if (intel_gt_wait_for_idle(gt, I915_GEM_IDLE_TIMEOUT) == -ETIME) { if (intel_gt_wait_for_idle(gt, I915_GEM_IDLE_TIMEOUT) == -ETIME) {
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "i915_drv.h" #include "i915_drv.h"
#include "intel_renderstate.h" #include "intel_renderstate.h"
#include "gt/intel_context.h"
#include "intel_ring.h" #include "intel_ring.h"
static const struct intel_renderstate_rodata * static const struct intel_renderstate_rodata *
...@@ -157,17 +158,16 @@ static int render_state_setup(struct intel_renderstate *so, ...@@ -157,17 +158,16 @@ static int render_state_setup(struct intel_renderstate *so,
#undef OUT_BATCH #undef OUT_BATCH
int intel_renderstate_init(struct intel_renderstate *so, 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; int err;
memset(so, 0, sizeof(*so)); memset(so, 0, sizeof(*so));
so->rodata = render_state_get_rodata(engine); so->rodata = render_state_get_rodata(engine);
if (!so->rodata) if (so->rodata) {
return 0;
if (so->rodata->batch_items * 4 > PAGE_SIZE) if (so->rodata->batch_items * 4 > PAGE_SIZE)
return -EINVAL; return -EINVAL;
...@@ -180,10 +180,25 @@ int intel_renderstate_init(struct intel_renderstate *so, ...@@ -180,10 +180,25 @@ int intel_renderstate_init(struct intel_renderstate *so,
err = PTR_ERR(so->vma); err = PTR_ERR(so->vma);
goto err_obj; 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); err = i915_vma_pin(so->vma, 0, 0, PIN_GLOBAL | PIN_HIGH);
if (err) if (err)
goto err_obj; goto err_context;
err = render_state_setup(so, engine->i915); err = render_state_setup(so, engine->i915);
if (err) if (err)
...@@ -193,7 +208,17 @@ int intel_renderstate_init(struct intel_renderstate *so, ...@@ -193,7 +208,17 @@ int intel_renderstate_init(struct intel_renderstate *so,
err_unpin: err_unpin:
i915_vma_unpin(so->vma); 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: err_obj:
if (obj)
i915_gem_object_put(obj); i915_gem_object_put(obj);
so->vma = NULL; so->vma = NULL;
return err; return err;
...@@ -208,11 +233,9 @@ int intel_renderstate_emit(struct intel_renderstate *so, ...@@ -208,11 +233,9 @@ int intel_renderstate_emit(struct intel_renderstate *so,
if (!so->vma) if (!so->vma)
return 0; return 0;
i915_vma_lock(so->vma);
err = i915_request_await_object(rq, so->vma->obj, false); err = i915_request_await_object(rq, so->vma->obj, false);
if (err == 0) if (err == 0)
err = i915_vma_move_to_active(so->vma, rq, 0); err = i915_vma_move_to_active(so->vma, rq, 0);
i915_vma_unlock(so->vma);
if (err) if (err)
return err; return err;
...@@ -233,7 +256,17 @@ int intel_renderstate_emit(struct intel_renderstate *so, ...@@ -233,7 +256,17 @@ int intel_renderstate_emit(struct intel_renderstate *so,
return 0; 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);
} }
...@@ -25,9 +25,10 @@ ...@@ -25,9 +25,10 @@
#define _INTEL_RENDERSTATE_H_ #define _INTEL_RENDERSTATE_H_
#include <linux/types.h> #include <linux/types.h>
#include "i915_gem.h"
struct i915_request; struct i915_request;
struct intel_engine_cs; struct intel_context;
struct i915_vma; struct i915_vma;
struct intel_renderstate_rodata { struct intel_renderstate_rodata {
...@@ -49,6 +50,7 @@ extern const struct intel_renderstate_rodata gen8_null_state; ...@@ -49,6 +50,7 @@ extern const struct intel_renderstate_rodata gen8_null_state;
extern const struct intel_renderstate_rodata gen9_null_state; extern const struct intel_renderstate_rodata gen9_null_state;
struct intel_renderstate { struct intel_renderstate {
struct i915_gem_ww_ctx ww;
const struct intel_renderstate_rodata *rodata; const struct intel_renderstate_rodata *rodata;
struct i915_vma *vma; struct i915_vma *vma;
u32 batch_offset; u32 batch_offset;
...@@ -58,9 +60,10 @@ struct intel_renderstate { ...@@ -58,9 +60,10 @@ struct intel_renderstate {
}; };
int intel_renderstate_init(struct intel_renderstate *so, 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, int intel_renderstate_emit(struct intel_renderstate *so,
struct i915_request *rq); 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_ */ #endif /* _INTEL_RENDERSTATE_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment