From patchwork Thu Sep 7 10:06:10 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: sagar.a.kamble@intel.com X-Patchwork-Id: 9942003 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D95B4602CC for ; Thu, 7 Sep 2017 10:03:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EA10328600 for ; Thu, 7 Sep 2017 10:03:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DEBDD28606; Thu, 7 Sep 2017 10:03:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id EC75328607 for ; Thu, 7 Sep 2017 10:03:13 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 754336E8E7; Thu, 7 Sep 2017 10:03:11 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTPS id 837436E8E6 for ; Thu, 7 Sep 2017 10:03:10 +0000 (UTC) Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 07 Sep 2017 03:03:10 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.42,357,1500966000"; d="scan'208";a="126439750" Received: from sakamble-desktop.iind.intel.com ([10.223.26.118]) by orsmga004.jf.intel.com with ESMTP; 07 Sep 2017 03:03:08 -0700 From: Sagar Arun Kamble To: intel-gfx@lists.freedesktop.org Date: Thu, 7 Sep 2017 15:36:10 +0530 Message-Id: <1504778774-18117-11-git-send-email-sagar.a.kamble@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1504778774-18117-1-git-send-email-sagar.a.kamble@intel.com> References: <1504778774-18117-1-git-send-email-sagar.a.kamble@intel.com> Subject: [Intel-gfx] [PATCH 10/14] drm/i915: Link perf stream structures with Engines X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP To allow opening CS perf streams for other engines, this patch associates exclusive stream with each engine and correspondingly updates the required fields per stream. Signed-off-by: Sagar Arun Kamble --- drivers/gpu/drm/i915/i915_drv.h | 26 +++-- drivers/gpu/drm/i915/i915_perf.c | 168 +++++++++++++++----------------- drivers/gpu/drm/i915/intel_engine_cs.c | 4 + drivers/gpu/drm/i915/intel_ringbuffer.c | 2 + drivers/gpu/drm/i915/intel_ringbuffer.h | 8 ++ 5 files changed, 104 insertions(+), 104 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5c38cf5..8bd8c0a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2068,6 +2068,11 @@ struct i915_perf_stream { */ struct drm_i915_private *dev_priv; + /* + * @engine: Engine to which this stream corresponds. + */ + struct intel_engine_cs *engine; + /** * @sample_flags: Flags representing the `DRM_I915_PERF_PROP_SAMPLE_*` * properties given when opening a stream, representing the contents @@ -2132,6 +2137,10 @@ struct i915_perf_stream { u32 last_ctx_id; u64 last_pid; u32 last_tag; + + u32 specific_ctx_id; + wait_queue_head_t poll_wq; + bool pollin; }; /** @@ -2620,6 +2629,8 @@ struct drm_i915_private { */ struct idr metrics_idr; + struct hrtimer poll_check_timer; + /* * Lock associated with anything below within this structure * except exclusive_stream. @@ -2627,21 +2638,6 @@ struct drm_i915_private { struct mutex lock; struct { - /* - * The stream currently using the OA unit. If accessed - * outside a syscall associated to its file - * descriptor, you need to hold - * dev_priv->drm.struct_mutex. - */ - struct i915_perf_stream *exclusive_stream; - struct srcu_struct srcu; - - u32 specific_ctx_id; - - struct hrtimer poll_check_timer; - wait_queue_head_t poll_wq; - bool pollin; - /** * For rate limiting any notifications of spurious * invalid OA reports diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c index b44d76e..aad8b23 100644 --- a/drivers/gpu/drm/i915/i915_perf.c +++ b/drivers/gpu/drm/i915/i915_perf.c @@ -551,20 +551,20 @@ void i915_perf_emit_sample_capture(struct drm_i915_gem_request *request, u32 tag) { struct drm_i915_private *dev_priv = request->i915; + struct intel_engine_cs *engine = request->engine; struct i915_perf_stream *stream; int idx; if (!dev_priv->perf.initialized) return; - idx = srcu_read_lock(&dev_priv->perf.oa.srcu); - stream = srcu_dereference(dev_priv->perf.oa.exclusive_stream, - &dev_priv->perf.oa.srcu); + idx = srcu_read_lock(&engine->srcu); + stream = srcu_dereference(engine->exclusive_stream, + &engine->srcu); if (stream && stream->enabled && stream->cs_mode) stream->ops->emit_sample_capture(stream, request, preallocate, tag); - - srcu_read_unlock(&dev_priv->perf.oa.srcu, idx); + srcu_read_unlock(&engine->srcu, idx); } /** @@ -663,18 +663,19 @@ static void i915_perf_stream_patch_request(struct i915_perf_stream *stream, void i915_perf_patch_request(struct drm_i915_gem_request *request) { struct drm_i915_private *dev_priv = request->i915; + struct intel_engine_cs *engine = request->engine; struct i915_perf_stream *stream; int idx; if (!dev_priv->perf.initialized) return; - idx = srcu_read_lock(&dev_priv->perf.oa.srcu); - stream = srcu_dereference(dev_priv->perf.oa.exclusive_stream, - &dev_priv->perf.oa.srcu); + idx = srcu_read_lock(&engine->srcu); + stream = srcu_dereference(engine->exclusive_stream, + &engine->srcu); if (stream && stream->enabled && stream->cs_mode) stream->ops->patch_request(stream, request); - srcu_read_unlock(&dev_priv->perf.oa.srcu, idx); + srcu_read_unlock(&engine->srcu, idx); } /** @@ -1198,18 +1199,18 @@ static int gen8_append_oa_reports(struct i915_perf_stream *stream, * switches since it's not-uncommon for periodic samples to * identify a switch before any 'context switch' report. */ - if (!dev_priv->perf.oa.exclusive_stream->ctx || - dev_priv->perf.oa.specific_ctx_id == ctx_id || + if (!stream->ctx || + stream->specific_ctx_id == ctx_id || (dev_priv->perf.oa.oa_buffer.last_ctx_id == - dev_priv->perf.oa.specific_ctx_id) || + stream->specific_ctx_id) || reason & OAREPORT_REASON_CTX_SWITCH) { /* * While filtering for a single context we avoid * leaking the IDs of other contexts. */ - if (dev_priv->perf.oa.exclusive_stream->ctx && - dev_priv->perf.oa.specific_ctx_id != ctx_id) { + if (stream->ctx && + stream->specific_ctx_id != ctx_id) { report32[2] = INVALID_CTX_ID; } @@ -1851,7 +1852,7 @@ static int i915_perf_stream_wait_unlocked(struct i915_perf_stream *stream) } } - return wait_event_interruptible(dev_priv->perf.oa.poll_wq, + return wait_event_interruptible(stream->poll_wq, stream_have_data_unlocked(stream)); } @@ -1870,9 +1871,7 @@ static void i915_perf_stream_poll_wait(struct i915_perf_stream *stream, struct file *file, poll_table *wait) { - struct drm_i915_private *dev_priv = stream->dev_priv; - - poll_wait(file, &dev_priv->perf.oa.poll_wq, wait); + poll_wait(file, &stream->poll_wq, wait); } /** @@ -1920,7 +1919,7 @@ static int oa_get_render_ctx_id(struct i915_perf_stream *stream) struct drm_i915_private *dev_priv = stream->dev_priv; if (i915.enable_execlists) - dev_priv->perf.oa.specific_ctx_id = stream->ctx->hw_id; + stream->specific_ctx_id = stream->ctx->hw_id; else { struct intel_engine_cs *engine = dev_priv->engine[RCS]; struct intel_ring *ring; @@ -1947,7 +1946,7 @@ static int oa_get_render_ctx_id(struct i915_perf_stream *stream) * i915_ggtt_offset() on the fly) considering the difference * with gen8+ and execlists */ - dev_priv->perf.oa.specific_ctx_id = + stream->specific_ctx_id = i915_ggtt_offset(stream->ctx->engine[engine->id].state); } @@ -1966,13 +1965,13 @@ static void oa_put_render_ctx_id(struct i915_perf_stream *stream) struct drm_i915_private *dev_priv = stream->dev_priv; if (i915.enable_execlists) { - dev_priv->perf.oa.specific_ctx_id = INVALID_CTX_ID; + stream->specific_ctx_id = INVALID_CTX_ID; } else { struct intel_engine_cs *engine = dev_priv->engine[RCS]; mutex_lock(&dev_priv->drm.struct_mutex); - dev_priv->perf.oa.specific_ctx_id = INVALID_CTX_ID; + stream->specific_ctx_id = INVALID_CTX_ID; engine->context_unpin(engine, stream->ctx); mutex_unlock(&dev_priv->drm.struct_mutex); @@ -2034,23 +2033,24 @@ static void free_perf_samples(struct i915_perf_stream *stream) static void i915_perf_stream_destroy(struct i915_perf_stream *stream) { struct drm_i915_private *dev_priv = stream->dev_priv; + struct intel_engine_cs *engine = stream->engine; struct i915_perf_stream *engine_stream; int idx; - idx = srcu_read_lock(&dev_priv->perf.oa.srcu); - engine_stream = srcu_dereference(dev_priv->perf.oa.exclusive_stream, - &dev_priv->perf.oa.srcu); + idx = srcu_read_lock(&engine->srcu); + engine_stream = srcu_dereference(engine->exclusive_stream, + &engine->srcu); if (WARN_ON(stream != engine_stream)) return; - srcu_read_unlock(&dev_priv->perf.oa.srcu, idx); + srcu_read_unlock(&engine->srcu, idx); /* * Unset exclusive_stream first, it will be checked while disabling * the metric set on gen8+. */ mutex_lock(&dev_priv->drm.struct_mutex); - rcu_assign_pointer(dev_priv->perf.oa.exclusive_stream, NULL); - synchronize_srcu(&dev_priv->perf.oa.srcu); + rcu_assign_pointer(engine->exclusive_stream, NULL); + synchronize_srcu(&engine->srcu); mutex_unlock(&dev_priv->drm.struct_mutex); if (stream->using_oa) { @@ -2118,11 +2118,6 @@ static void gen7_init_oa_buffer(struct drm_i915_private *dev_priv) * memory... */ memset(dev_priv->perf.oa.oa_buffer.vaddr, 0, OA_BUFFER_SIZE); - - /* Maybe make ->pollin per-stream state if we support multiple - * concurrent streams in the future. - */ - dev_priv->perf.oa.pollin = false; } static void gen8_init_oa_buffer(struct drm_i915_private *dev_priv) @@ -2176,12 +2171,6 @@ static void gen8_init_oa_buffer(struct drm_i915_private *dev_priv) * memory... */ memset(dev_priv->perf.oa.oa_buffer.vaddr, 0, OA_BUFFER_SIZE); - - /* - * Maybe make ->pollin per-stream state if we support multiple - * concurrent streams in the future. - */ - dev_priv->perf.oa.pollin = false; } static int alloc_obj(struct drm_i915_private *dev_priv, @@ -2720,6 +2709,7 @@ static void gen8_disable_metric_set(struct drm_i915_private *dev_priv) static void gen7_oa_enable(struct drm_i915_private *dev_priv) { struct i915_perf_stream *stream; + struct intel_engine_cs *engine = dev_priv->engine[RCS]; int idx; /* @@ -2733,13 +2723,12 @@ static void gen7_oa_enable(struct drm_i915_private *dev_priv) */ gen7_init_oa_buffer(dev_priv); - idx = srcu_read_lock(&dev_priv->perf.oa.srcu); - stream = srcu_dereference(dev_priv->perf.oa.exclusive_stream, - &dev_priv->perf.oa.srcu); + idx = srcu_read_lock(&engine->srcu); + stream = srcu_dereference(engine->exclusive_stream, + &engine->srcu); if (!stream->enabled) { - struct i915_gem_context *ctx = - dev_priv->perf.oa.exclusive_stream->ctx; - u32 ctx_id = dev_priv->perf.oa.specific_ctx_id; + struct i915_gem_context *ctx = stream->ctx; + u32 ctx_id = stream->specific_ctx_id; bool periodic = dev_priv->perf.oa.periodic; u32 period_exponent = dev_priv->perf.oa.period_exponent; u32 report_format = dev_priv->perf.oa.oa_buffer.format; @@ -2754,7 +2743,7 @@ static void gen7_oa_enable(struct drm_i915_private *dev_priv) GEN7_OACONTROL_ENABLE); } else I915_WRITE(GEN7_OACONTROL, 0); - srcu_read_unlock(&dev_priv->perf.oa.srcu, idx); + srcu_read_unlock(&engine->srcu, idx); } static void gen8_oa_enable(struct drm_i915_private *dev_priv) @@ -2799,7 +2788,7 @@ static void i915_perf_stream_enable(struct i915_perf_stream *stream) dev_priv->perf.oa.ops.oa_enable(dev_priv); if (stream->cs_mode || dev_priv->perf.oa.periodic) - hrtimer_start(&dev_priv->perf.oa.poll_check_timer, + hrtimer_start(&dev_priv->perf.poll_check_timer, ns_to_ktime(POLL_PERIOD), HRTIMER_MODE_REL_PINNED); } @@ -2827,7 +2816,7 @@ static void i915_perf_stream_disable(struct i915_perf_stream *stream) struct drm_i915_private *dev_priv = stream->dev_priv; if (stream->cs_mode || dev_priv->perf.oa.periodic) - hrtimer_cancel(&dev_priv->perf.oa.poll_check_timer); + hrtimer_cancel(&dev_priv->perf.poll_check_timer); if (stream->cs_mode) i915_perf_stream_release_samples(stream); @@ -2930,20 +2919,21 @@ static int i915_perf_stream_init(struct i915_perf_stream *stream, return -ENODEV; } + engine = dev_priv->engine[RCS]; /* * To avoid the complexity of having to accurately filter * counter reports and marshal to the appropriate client * we currently only allow exclusive access */ - idx = srcu_read_lock(&dev_priv->perf.oa.srcu); + idx = srcu_read_lock(&engine->srcu); curr_stream = srcu_dereference( - dev_priv->perf.oa.exclusive_stream, - &dev_priv->perf.oa.srcu); + engine->exclusive_stream, + &engine->srcu); if (curr_stream) { DRM_ERROR("Stream already opened\n"); return -EBUSY; } - srcu_read_unlock(&dev_priv->perf.oa.srcu, idx); + srcu_read_unlock(&engine->srcu, idx); if (!props->oa_format) { DRM_DEBUG("OA report format not specified\n"); @@ -2957,8 +2947,8 @@ static int i915_perf_stream_init(struct i915_perf_stream *stream, return -EINVAL; } - engine = dev_priv->engine[RCS]; stream->using_oa = true; + stream->engine = engine; format_size = dev_priv->perf.oa.oa_formats[props->oa_format].size; @@ -3076,17 +3066,19 @@ static int i915_perf_stream_init(struct i915_perf_stream *stream, stream->last_tag = INVALID_TAG; } - idx = srcu_read_lock(&dev_priv->perf.oa.srcu); + engine = dev_priv->engine[props->engine]; + idx = srcu_read_lock(&engine->srcu); curr_stream = srcu_dereference( - dev_priv->perf.oa.exclusive_stream, - &dev_priv->perf.oa.srcu); + engine->exclusive_stream, + &engine->srcu); if (curr_stream) { DRM_ERROR("Stream already opened\n"); ret = -EINVAL; goto err_enable; } - srcu_read_unlock(&dev_priv->perf.oa.srcu, idx); + srcu_read_unlock(&engine->srcu, idx); + stream->engine = engine; ret = alloc_cs_buffer(stream); if (ret) goto err_enable; @@ -3095,6 +3087,8 @@ static int i915_perf_stream_init(struct i915_perf_stream *stream, } stream->ops = &perf_stream_ops; + init_waitqueue_head(&stream->poll_wq); + stream->pollin = false; /* Lock device for exclusive_stream access late because * enable_metric_set() might lock as well on gen8+. @@ -3102,7 +3096,7 @@ static int i915_perf_stream_init(struct i915_perf_stream *stream, ret = i915_mutex_lock_interruptible(&dev_priv->drm); if (ret) goto err_lock; - rcu_assign_pointer(dev_priv->perf.oa.exclusive_stream, stream); + rcu_assign_pointer(engine->exclusive_stream, stream); mutex_unlock(&dev_priv->drm.struct_mutex); return 0; @@ -3136,7 +3130,7 @@ void i915_oa_init_reg_state(struct intel_engine_cs *engine, if (engine->id != RCS) return; - stream = engine->i915->perf.oa.exclusive_stream; + stream = engine->exclusive_stream; if (stream) gen8_update_reg_state_unlocked(ctx, reg_state, stream->oa_config); } @@ -3251,7 +3245,7 @@ static ssize_t i915_perf_read(struct file *file, * before reporting another POLLIN event. */ if (ret >= 0 || ret == -EAGAIN) - dev_priv->perf.oa.pollin = false; + stream->pollin = false; return ret; } @@ -3261,21 +3255,21 @@ static enum hrtimer_restart poll_check_timer_cb(struct hrtimer *hrtimer) struct i915_perf_stream *stream; struct drm_i915_private *dev_priv = container_of(hrtimer, typeof(*dev_priv), - perf.oa.poll_check_timer); + perf.poll_check_timer); int idx; struct intel_engine_cs *engine; enum intel_engine_id id; for_each_engine(engine, dev_priv, id) { - idx = srcu_read_lock(&dev_priv->perf.oa.srcu); - stream = srcu_dereference(dev_priv->perf.oa.exclusive_stream, - &dev_priv->perf.oa.srcu); + idx = srcu_read_lock(&engine->srcu); + stream = srcu_dereference(engine->exclusive_stream, + &engine->srcu); if (stream && stream->enabled && stream_have_data_unlocked(stream)) { - dev_priv->perf.oa.pollin = true; - wake_up(&dev_priv->perf.oa.poll_wq); + stream->pollin = true; + wake_up(&stream->poll_wq); } - srcu_read_unlock(&dev_priv->perf.oa.srcu, idx); + srcu_read_unlock(&engine->srcu, idx); } hrtimer_forward_now(hrtimer, ns_to_ktime(POLL_PERIOD)); @@ -3314,7 +3308,7 @@ static unsigned int i915_perf_poll_locked(struct drm_i915_private *dev_priv, * the hrtimer/oa_poll_check_timer_cb to notify us when there are * samples to read. */ - if (dev_priv->perf.oa.pollin) + if (stream->pollin) events |= POLLIN; return events; @@ -4374,20 +4368,24 @@ int i915_perf_remove_config_ioctl(struct drm_device *dev, void *data, void i915_perf_streams_mark_idle(struct drm_i915_private *dev_priv) { struct i915_perf_stream *stream; + struct intel_engine_cs *engine; + enum intel_engine_id id; int idx; - idx = srcu_read_lock(&dev_priv->perf.oa.srcu); - stream = srcu_dereference(dev_priv->perf.oa.exclusive_stream, - &dev_priv->perf.oa.srcu); - if (stream && stream->enabled && stream->cs_mode) { - struct reservation_object *resv = - stream->cs_buffer.vma->resv; - - reservation_object_lock(resv, NULL); - reservation_object_add_excl_fence(resv, NULL); - reservation_object_unlock(resv); + for_each_engine(engine, dev_priv, id) { + idx = srcu_read_lock(&engine->srcu); + stream = srcu_dereference(engine->exclusive_stream, + &engine->srcu); + if (stream && stream->enabled && stream->cs_mode) { + struct reservation_object *resv = + stream->cs_buffer.vma->resv; + + reservation_object_lock(resv, NULL); + reservation_object_add_excl_fence(resv, NULL); + reservation_object_unlock(resv); + } + srcu_read_unlock(&engine->srcu, idx); } - srcu_read_unlock(&dev_priv->perf.oa.srcu, idx); } /** @@ -4483,19 +4481,13 @@ void i915_perf_init(struct drm_i915_private *dev_priv) } if (dev_priv->perf.oa.timestamp_frequency) { - hrtimer_init(&dev_priv->perf.oa.poll_check_timer, + hrtimer_init(&dev_priv->perf.poll_check_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - dev_priv->perf.oa.poll_check_timer.function = - poll_check_timer_cb; - init_waitqueue_head(&dev_priv->perf.oa.poll_wq); + dev_priv->perf.poll_check_timer.function = poll_check_timer_cb; mutex_init(&dev_priv->perf.lock); spin_lock_init(&dev_priv->perf.oa.oa_buffer.ptr_lock); - /* Perf stream related initialization for Engine */ - rcu_assign_pointer(dev_priv->perf.oa.exclusive_stream, NULL); - init_srcu_struct(&dev_priv->perf.oa.srcu); - oa_sample_rate_hard_limit = dev_priv->perf.oa.timestamp_frequency / 2; dev_priv->perf.sysctl_header = register_sysctl_table(dev_root); @@ -4533,7 +4525,5 @@ void i915_perf_fini(struct drm_i915_private *dev_priv) memset(&dev_priv->perf.oa.ops, 0, sizeof(dev_priv->perf.oa.ops)); - cleanup_srcu_struct(&dev_priv->perf.oa.srcu); - dev_priv->perf.initialized = false; } diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index ae66834..f3199b9 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -317,6 +317,10 @@ int intel_engines_init(struct drm_i915_private *dev_priv) goto cleanup; GEM_BUG_ON(!engine->submit_request); + + /* Perf stream related initialization for Engine */ + rcu_assign_pointer(engine->exclusive_stream, NULL); + init_srcu_struct(&engine->srcu); } return 0; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index cdf084e..501c544 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1622,6 +1622,8 @@ void intel_engine_cleanup(struct intel_engine_cs *engine) intel_engine_cleanup_common(engine); + cleanup_srcu_struct(&engine->srcu); + dev_priv->engine[engine->id] = NULL; kfree(engine); } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 02d8974..2fcfaf4 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -441,6 +441,14 @@ struct intel_engine_cs { * certain bits to encode the command length in the header). */ u32 (*get_cmd_length_mask)(u32 cmd_header); + + /* + * For RCS, This stream can use the OA unit. All accesses guarded by + * SRCU including those in syscall as we can't hold + * dev_priv->drm.struct_mutex in the execbuf path. + */ + struct i915_perf_stream __rcu *exclusive_stream; + struct srcu_struct srcu; }; static inline unsigned int