]> git.baikalelectronics.ru Git - kernel.git/commitdiff
drm/i915/perf: allow holding preemption on filtered ctx
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>
Mon, 14 Oct 2019 20:14:04 +0000 (21:14 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Mon, 14 Oct 2019 20:30:28 +0000 (21:30 +0100)
We would like to make use of perf in Vulkan. The Vulkan API is much
lower level than OpenGL, with applications directly exposed to the
concept of command buffers (pretty much equivalent to our batch
buffers). In Vulkan, queries are always limited in scope to a command
buffer. In OpenGL, the lack of command buffer concept meant that
queries' duration could span multiple command buffers.

With that restriction gone in Vulkan, we would like to simplify
measuring performance just by measuring the deltas between the counter
snapshots written by 2 MI_RECORD_PERF_COUNT commands, rather than the
more complex scheme we currently have in the GL driver, using 2
MI_RECORD_PERF_COUNT commands and doing some post processing on the
stream of OA reports, coming from the global OA buffer, to remove any
unrelated deltas in between the 2 MI_RECORD_PERF_COUNT.

Disabling preemption only apply to a single context with which want to
query performance counters for and is considered a privileged
operation, by default protected by CAP_SYS_ADMIN. It is possible to
enable it for a normal user by disabling the paranoid stream setting.

v2: Store preemption setting in intel_context (Chris)

v3: Use priorities to avoid preemption rather than the HW mechanism

v4: Just modify the port priority reporting function

v5: Add nopreempt flag on gem context and always flag requests
    appropriately, regarless of OA reconfiguration.

Link: https://gitlab.freedesktop.org/mesa/mesa/merge_requests/932
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20191014201404.22468-4-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/gem/i915_gem_context.h
drivers/gpu/drm/i915/gem/i915_gem_context_types.h
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_perf.c
drivers/gpu/drm/i915/i915_perf_types.h
include/uapi/drm/i915_drm.h

index 9234586830d181dcf094f9d6a86914d94e503409..cfe80590f0ed7b75ba73ec2fcd0d316ab04ba75b 100644 (file)
@@ -114,6 +114,24 @@ i915_gem_context_clear_user_engines(struct i915_gem_context *ctx)
        clear_bit(CONTEXT_USER_ENGINES, &ctx->flags);
 }
 
+static inline bool
+i915_gem_context_nopreempt(const struct i915_gem_context *ctx)
+{
+       return test_bit(CONTEXT_NOPREEMPT, &ctx->flags);
+}
+
+static inline void
+i915_gem_context_set_nopreempt(struct i915_gem_context *ctx)
+{
+       set_bit(CONTEXT_NOPREEMPT, &ctx->flags);
+}
+
+static inline void
+i915_gem_context_clear_nopreempt(struct i915_gem_context *ctx)
+{
+       clear_bit(CONTEXT_NOPREEMPT, &ctx->flags);
+}
+
 static inline bool i915_gem_context_is_kernel(struct i915_gem_context *ctx)
 {
        return !ctx->file_priv;
index ab8e1367dfc811029b9d98af9ed2c7947b46d57c..fe97b8ba4fda21c3ed281f7b02abfc76a594d65d 100644 (file)
@@ -146,6 +146,7 @@ struct i915_gem_context {
 #define CONTEXT_CLOSED                 1
 #define CONTEXT_FORCE_SINGLE_SUBMISSION        2
 #define CONTEXT_USER_ENGINES           3
+#define CONTEXT_NOPREEMPT              4
 
        struct mutex mutex;
 
index 580c15e74a0a692ca848c68d488ba5d9fdd53fd9..98cd92320afbbdb4df1e4a2b9b150625dd514ad7 100644 (file)
@@ -2079,6 +2079,9 @@ static int eb_submit(struct i915_execbuffer *eb)
        if (err)
                return err;
 
+       if (i915_gem_context_nopreempt(eb->gem_context))
+               eb->request->flags |= I915_REQUEST_NOPREEMPT;
+
        return 0;
 }
 
index 372c91f6a28ee84315fd797c85c005b81b1acd60..54ec1c4190aced31e39256e54bd8300a4b27ed43 100644 (file)
@@ -344,6 +344,8 @@ static const struct i915_oa_format gen8_plus_oa_formats[I915_OA_FORMAT_MAX] = {
  * struct perf_open_properties - for validated properties given to open a stream
  * @sample_flags: `DRM_I915_PERF_PROP_SAMPLE_*` properties are tracked as flags
  * @single_context: Whether a single or all gpu contexts should be monitored
+ * @hold_preemption: Whether the preemption is disabled for the filtered
+ *                   context
  * @ctx_handle: A gem ctx handle for use with @single_context
  * @metrics_set: An ID for an OA unit metric set advertised via sysfs
  * @oa_format: An OA unit HW report format
@@ -359,6 +361,7 @@ struct perf_open_properties {
        u32 sample_flags;
 
        u64 single_context:1;
+       u64 hold_preemption:1;
        u64 ctx_handle;
 
        /* OA sampling state */
@@ -2514,6 +2517,8 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
        if (WARN_ON(stream->oa_buffer.format_size == 0))
                return -EINVAL;
 
+       stream->hold_preemption = props->hold_preemption;
+
        stream->oa_buffer.format =
                perf->oa_formats[props->oa_format].format;
 
@@ -2834,6 +2839,9 @@ static void i915_perf_enable_locked(struct i915_perf_stream *stream)
 
        if (stream->ops->enable)
                stream->ops->enable(stream);
+
+       if (stream->hold_preemption)
+               i915_gem_context_set_nopreempt(stream->ctx);
 }
 
 /**
@@ -2858,6 +2866,9 @@ static void i915_perf_disable_locked(struct i915_perf_stream *stream)
        /* Allow stream->ops->disable() to refer to this */
        stream->enabled = false;
 
+       if (stream->hold_preemption)
+               i915_gem_context_clear_nopreempt(stream->ctx);
+
        if (stream->ops->disable)
                stream->ops->disable(stream);
 }
@@ -3067,6 +3078,15 @@ i915_perf_open_ioctl_locked(struct i915_perf *perf,
                }
        }
 
+       if (props->hold_preemption) {
+               if (!props->single_context) {
+                       DRM_DEBUG("preemption disable with no context\n");
+                       ret = -EINVAL;
+                       goto err;
+               }
+               privileged_op = true;
+       }
+
        /*
         * On Haswell the OA unit supports clock gating off for a specific
         * context and in this mode there's no visibility of metrics for the
@@ -3081,7 +3101,7 @@ i915_perf_open_ioctl_locked(struct i915_perf *perf,
         * MI_REPORT_PERF_COUNT commands and so consider it a privileged op to
         * enable the OA unit by default.
         */
-       if (IS_HASWELL(perf->i915) && specific_ctx)
+       if (IS_HASWELL(perf->i915) && specific_ctx && !props->hold_preemption)
                privileged_op = false;
 
        /* Similar to perf's kernel.perf_paranoid_cpu sysctl option
@@ -3091,7 +3111,7 @@ i915_perf_open_ioctl_locked(struct i915_perf *perf,
         */
        if (privileged_op &&
            i915_perf_stream_paranoid && !capable(CAP_SYS_ADMIN)) {
-               DRM_DEBUG("Insufficient privileges to open system-wide i915 perf stream\n");
+               DRM_DEBUG("Insufficient privileges to open i915 perf stream\n");
                ret = -EACCES;
                goto err_ctx;
        }
@@ -3293,6 +3313,9 @@ static int read_properties_unlocked(struct i915_perf *perf,
                        props->oa_periodic = true;
                        props->oa_period_exponent = value;
                        break;
+               case DRM_I915_PERF_PROP_HOLD_PREEMPTION:
+                       props->hold_preemption = !!value;
+                       break;
                case DRM_I915_PERF_PROP_MAX:
                        MISSING_CASE(id);
                        return -EINVAL;
@@ -4066,8 +4089,13 @@ int i915_perf_ioctl_version(void)
         *
         * 2: Added runtime modification of OA config.
         *   I915_PERF_IOCTL_CONFIG
+        *
+        * 3: Add DRM_I915_PERF_PROP_HOLD_PREEMPTION parameter to hold
+        *    preemption on a particular context so that performance data is
+        *    accessible from a delta of MI_RPC reports without looking at the
+        *    OA buffer.
         */
-       return 2;
+       return 3;
 }
 
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
index d35a3c1946c35030ad7a6a2f9559db3606ae4107..a1f733fc905a68999efc89999851f6f12bc23134 100644 (file)
@@ -170,6 +170,14 @@ struct i915_perf_stream {
         */
        bool enabled;
 
+       /**
+        * @hold_preemption: Whether preemption is put on hold for command
+        * submissions done on the @ctx. This is useful for some drivers that
+        * cannot easily post process the OA buffer context to subtract delta
+        * of performance counters not associated with @ctx.
+        */
+       bool hold_preemption;
+
        /**
         * @ops: The callbacks providing the implementation of this specific
         * type of configured stream.
index b008ce8b4e6f1da43b6d2c7c7647b65c68a4ef1e..63d40cba97e0e270e1b979e157ccdb3f2f725d94 100644 (file)
@@ -1890,6 +1890,17 @@ enum drm_i915_perf_property_id {
         */
        DRM_I915_PERF_PROP_OA_EXPONENT,
 
+       /**
+        * Specifying this property is only valid when specify a context to
+        * filter with DRM_I915_PERF_PROP_CTX_HANDLE. Specifying this property
+        * will hold preemption of the particular context we want to gather
+        * performance data about. The execbuf2 submissions must include a
+        * drm_i915_gem_execbuffer_ext_perf parameter for this to apply.
+        *
+        * This property is available in perf revision 3.
+        */
+       DRM_I915_PERF_PROP_HOLD_PREEMPTION,
+
        DRM_I915_PERF_PROP_MAX /* non-ABI */
 };