[Intel-gfx] [PATCH v5 09/10] drm/i915/perf: execute OA configuration from command stream
Chris Wilson
chris at chris-wilson.co.uk
Thu Jun 27 10:02:25 UTC 2019
Quoting Lionel Landwerlin (2019-06-27 09:00:44)
> We can't run into issues with doing writing the global OA/NOA
> registers configuration from CPU so far, but HW engineers actually
> recommend doing this from the command streamer.
>
> Since we have a command buffer prepared for the execbuffer side of
> things, we can reuse that approach here too.
>
> Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
> ---
> drivers/gpu/drm/i915/i915_perf.c | 203 +++++++++++++++----------------
> 1 file changed, 100 insertions(+), 103 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
> index bf4f5fee6764..7e636463e1f5 100644
> --- a/drivers/gpu/drm/i915/i915_perf.c
> +++ b/drivers/gpu/drm/i915/i915_perf.c
> @@ -389,6 +389,19 @@ void i915_oa_config_release(struct kref *ref)
> kfree(oa_config);
> }
>
> +static void i915_oa_config_dispose_buffers(struct drm_i915_private *i915)
> +{
> + struct i915_oa_config *oa_config, *next;
> +
> + mutex_lock(&i915->perf.metrics_lock);
> + list_for_each_entry_safe(oa_config, next, &i915->perf.metrics_buffers, vma_link) {
> + list_del(&oa_config->vma_link);
> + i915_gem_object_put(oa_config->obj);
> + oa_config->obj = NULL;
> + }
> + mutex_unlock(&i915->perf.metrics_lock);
> +}
> +
> static u32 *write_cs_mi_lri(u32 *cs, const struct i915_oa_reg *reg_data, u32 n_regs)
> {
> u32 i;
> @@ -1813,67 +1826,86 @@ static int alloc_noa_wait(struct drm_i915_private *i915)
> return ret;
> }
>
> -static void config_oa_regs(struct drm_i915_private *dev_priv,
> - const struct i915_oa_reg *regs,
> - u32 n_regs)
> +static int config_oa_regs(struct drm_i915_private *i915,
> + struct i915_oa_config *oa_config)
> {
> - u32 i;
> + struct i915_request *rq;
> + struct i915_vma *vma;
> + long timeout;
> + u32 *cs;
> + int err;
>
> - for (i = 0; i < n_regs; i++) {
> - const struct i915_oa_reg *reg = regs + i;
> + rq = i915_request_create(i915->engine[RCS0]->kernel_context);
> + if (IS_ERR(rq))
> + return PTR_ERR(rq);
>
> - I915_WRITE(reg->addr, reg->value);
> + err = i915_active_request_set(&i915->engine[RCS0]->last_oa_config,
> + rq);
This will need an explicit mutex as it is not serialised by any single
timeline.
i915->perf.metrics_lock viable? Needs to be taken here and in execbuf.
> + if (err) {
> + i915_request_add(rq);
> + return err;
> + }
> +
> + vma = i915_vma_instance(oa_config->obj, &i915->ggtt.vm, NULL);
> + if (unlikely(IS_ERR(vma))) {
> + i915_request_add(rq);
> + return PTR_ERR(vma);
> + }
> +
> + err = i915_vma_pin(vma, 0, 0, PIN_GLOBAL);
> + if (err) {
> + i915_request_add(rq);
> + return err;
> }
This time there is no excuse for not pinning outside of the
timeline->mutex.
> +
> + err = i915_vma_move_to_active(vma, rq, 0);
> + if (err) {
> + i915_vma_unpin(vma);
> + i915_request_add(rq);
> + return err;
> + }
> +
> + cs = intel_ring_begin(rq, INTEL_GEN(i915) >= 8 ? 4 : 2);
> + if (IS_ERR(cs)) {
> + i915_vma_unpin(vma);
> + i915_request_add(rq);
> + return PTR_ERR(cs);
> + }
> +
> + if (INTEL_GEN(i915) > 8) {
> + *cs++ = MI_BATCH_BUFFER_START_GEN8;
> + *cs++ = lower_32_bits(vma->node.start);
> + *cs++ = upper_32_bits(vma->node.start);
> + *cs++ = MI_NOOP;
> + } else {
> + *cs++ = MI_BATCH_BUFFER_START;
> + *cs++ = vma->node.start;
> + }
> +
> + intel_ring_advance(rq, cs);
> +
> + i915_vma_unpin(vma);
> +
> + i915_request_add(rq);
> +
> + i915_request_get(rq);
Strictly, before the add, as the add is the xfer of the ref.
> + timeout = i915_request_wait(rq, I915_WAIT_INTERRUPTIBLE | I915_WAIT_LOCKED,
> + MAX_SCHEDULE_TIMEOUT);
> + i915_request_put(rq);
> +
> + return timeout < 0 ? err : 0;
Report err, but timeline carries the errno?
-Chris
More information about the Intel-gfx
mailing list