drm/i915: Move the scheduler feature bits into the purview of the engines
authorChris Wilson <chris@chris-wilson.co.uk>
Wed, 7 Feb 2018 21:05:43 +0000 (21:05 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Thu, 8 Feb 2018 07:30:11 +0000 (07:30 +0000)
Rather than having the high level ioctl interface guess the underlying
implementation details, having the implementation declare what
capabilities it exports. We define an intel_driver_caps, similar to the
intel_device_info, which instead of trying to describe the HW gives
details on what the driver itself supports. This is then populated by
the engine backend for the new scheduler capability field for use
elsewhere.

v2: Use caps.scheduler for validating CONTEXT_PARAM_SET_PRIORITY (Mika)
    One less assumption of engine[RCS] \o/

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tomasz Lis <tomasz.lis@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Reviewed-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Reviewed-by: Tomasz Lis <tomasz.lis@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180207210544.26351-2-chris@chris-wilson.co.uk
Reviewed-by: Michel Thierry <michel.thierry@intel.com>
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_context.c
drivers/gpu/drm/i915/i915_gpu_error.c
drivers/gpu/drm/i915/intel_device_info.c
drivers/gpu/drm/i915/intel_device_info.h
drivers/gpu/drm/i915/intel_lrc.c

index 9e44adef30f080061fa1712ff3957ba1ebf3f1ea..2bdce9fea6717e4731e295e785f148b9f2a68827 100644 (file)
@@ -49,6 +49,7 @@ static int i915_capabilities(struct seq_file *m, void *data)
 
        intel_device_info_dump_flags(info, &p);
        intel_device_info_dump_runtime(info, &p);
+       intel_driver_caps_print(&dev_priv->caps, &p);
 
        kernel_param_lock(THIS_MODULE);
        i915_params_dump(&i915_modparams, &p);
index bb605e0b996cea2916c1ba0f083fcb022e3d12ed..143b9d5438d2df2c4641189b4469380a9c2987d1 100644 (file)
@@ -381,13 +381,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
                value = i915_gem_mmap_gtt_version();
                break;
        case I915_PARAM_HAS_SCHEDULER:
-               value = 0;
-               if (dev_priv->engine[RCS] && dev_priv->engine[RCS]->schedule) {
-                       value |= I915_SCHEDULER_CAP_ENABLED;
-                       value |= I915_SCHEDULER_CAP_PRIORITY;
-                       if (HAS_LOGICAL_RING_PREEMPTION(dev_priv))
-                               value |= I915_SCHEDULER_CAP_PREEMPTION;
-               }
+               value = dev_priv->caps.scheduler;
                break;
 
        case I915_PARAM_MMAP_VERSION:
index 60079a69c2f9658f9ff13ad68853585219241032..dd79d711c3ddce6f3a57fd854056bc33659452bb 100644 (file)
@@ -472,6 +472,7 @@ struct i915_gpu_state {
        u32 reset_count;
        u32 suspend_count;
        struct intel_device_info device_info;
+       struct intel_driver_caps driver_caps;
        struct i915_params params;
 
        struct i915_error_uc {
@@ -1815,6 +1816,7 @@ struct drm_i915_private {
        struct kmem_cache *priorities;
 
        const struct intel_device_info info;
+       struct intel_driver_caps caps;
 
        /**
         * Data Stolen Memory - aka "i915 stolen memory" gives us the start and
index c1b80cd52f9ebf50294358869752b6fa421fc01f..32883bb04747084df61e2d898c6b3446988aa517 100644 (file)
@@ -3229,8 +3229,11 @@ void i915_gem_set_wedged(struct drm_i915_private *i915)
                 * start to complete all requests.
                 */
                engine->submit_request = nop_complete_submit_request;
+               engine->schedule = NULL;
        }
 
+       i915->caps.scheduler = 0;
+
        /*
         * Make sure no request can slip through without getting completed by
         * either this call here to intel_engine_init_global_seqno, or the one
index 648e7536ff51e0eae1365971293ab150f72d9956..8337d15bb0e5dd278fcebc982115ce1849481532 100644 (file)
@@ -807,7 +807,7 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
 
                        if (args->size)
                                ret = -EINVAL;
-                       else if (!to_i915(dev)->engine[RCS]->schedule)
+                       else if (!(to_i915(dev)->caps.scheduler & I915_SCHEDULER_CAP_PRIORITY))
                                ret = -ENODEV;
                        else if (priority > I915_CONTEXT_MAX_USER_PRIORITY ||
                                 priority < I915_CONTEXT_MIN_USER_PRIORITY)
index 67c902412193d452a103016971eeb2a555b066ad..7f82c6062c447551769fbe31c452921977e15b3d 100644 (file)
@@ -579,11 +579,13 @@ static void print_error_obj(struct drm_i915_error_state_buf *m,
 }
 
 static void err_print_capabilities(struct drm_i915_error_state_buf *m,
-                                  const struct intel_device_info *info)
+                                  const struct intel_device_info *info,
+                                  const struct intel_driver_caps *caps)
 {
        struct drm_printer p = i915_error_printer(m);
 
        intel_device_info_dump_flags(info, &p);
+       intel_driver_caps_print(caps, &p);
 }
 
 static void err_print_params(struct drm_i915_error_state_buf *m,
@@ -808,7 +810,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
        if (error->display)
                intel_display_print_error_state(m, error->display);
 
-       err_print_capabilities(m, &error->device_info);
+       err_print_capabilities(m, &error->device_info, &error->driver_caps);
        err_print_params(m, &error->params);
        err_print_uc(m, &error->uc);
 
@@ -1740,6 +1742,7 @@ static void i915_capture_gen_state(struct drm_i915_private *dev_priv,
        memcpy(&error->device_info,
               INTEL_INFO(dev_priv),
               sizeof(error->device_info));
+       error->driver_caps = dev_priv->caps;
 }
 
 static __always_inline void dup_param(const char *type, void *x)
index a2c16140169fcea0ba83b325ab3aa65457512570..298f8996cc540d236ef397a9d8929ee36b967159 100644 (file)
@@ -586,3 +586,9 @@ void intel_device_info_runtime_init(struct intel_device_info *info)
        /* Initialize command stream timestamp frequency */
        info->cs_timestamp_frequency_khz = read_timestamp_frequency(dev_priv);
 }
+
+void intel_driver_caps_print(const struct intel_driver_caps *caps,
+                            struct drm_printer *p)
+{
+       drm_printf(p, "scheduler: %x\n", caps->scheduler);
+}
index 9542018d11d0fbdf7b094620e33d74af50fb9831..71fdfb0451ef8e4a0fb2dd612eb47ca9132c94bf 100644 (file)
@@ -167,6 +167,10 @@ struct intel_device_info {
        } color;
 };
 
+struct intel_driver_caps {
+       unsigned int scheduler;
+};
+
 static inline unsigned int sseu_subslice_total(const struct sseu_dev_info *sseu)
 {
        return hweight8(sseu->slice_mask) * hweight8(sseu->subslice_mask);
@@ -182,4 +186,7 @@ void intel_device_info_dump_flags(const struct intel_device_info *info,
 void intel_device_info_dump_runtime(const struct intel_device_info *info,
                                    struct drm_printer *p);
 
+void intel_driver_caps_print(const struct intel_driver_caps *caps,
+                            struct drm_printer *p);
+
 #endif
index 380c0838d8b3f2e7169897e4755e4110b2970307..449fd1e95f1f3d2e4643810ffd9c473f34ebeb0f 100644 (file)
@@ -1963,6 +1963,12 @@ static void execlists_set_default_submission(struct intel_engine_cs *engine)
        engine->unpark = NULL;
 
        engine->flags |= I915_ENGINE_SUPPORTS_STATS;
+
+       engine->i915->caps.scheduler =
+               I915_SCHEDULER_CAP_ENABLED |
+               I915_SCHEDULER_CAP_PRIORITY;
+       if (HAS_LOGICAL_RING_PREEMPTION(engine->i915))
+               engine->i915->caps.scheduler |= I915_SCHEDULER_CAP_PREEMPTION;
 }
 
 static void