diff mbox series

[30/57] drm/i915: Move timeslicing flag to scheduler

Message ID 20210201085715.27435-30-chris@chris-wilson.co.uk (mailing list archive)
State New, archived
Headers show
Series [01/57] drm/i915/gt: Restrict the GT clock override to just Icelake | expand

Commit Message

Chris Wilson Feb. 1, 2021, 8:56 a.m. UTC
Whether a scheduler chooses to implement timeslicing is up to it, and
not an underlying property of the HW engine. The scheduler does depend
on the HW supporting preemption.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/gt/intel_engine.h         |  6 ++++++
 drivers/gpu/drm/i915/gt/intel_engine_types.h   | 18 ++++--------------
 .../drm/i915/gt/intel_execlists_submission.c   |  9 ++++++---
 drivers/gpu/drm/i915/gt/selftest_execlists.c   |  2 +-
 drivers/gpu/drm/i915/i915_scheduler_types.h    | 10 ++++++++++
 5 files changed, 27 insertions(+), 18 deletions(-)

Comments

Tvrtko Ursulin Feb. 4, 2021, 3:18 p.m. UTC | #1
On 01/02/2021 08:56, Chris Wilson wrote:
> Whether a scheduler chooses to implement timeslicing is up to it, and
> not an underlying property of the HW engine. The scheduler does depend
> on the HW supporting preemption.

Therefore, continuing on the comment I made in the previous patch, if we 
had a helper with which engine would request scheduling (setting the 
tasklet), if it passed in a pointer to itself, scheduler would then be 
able to inspect if the engine supports preemption and so set its own 
internal flag. Makes sense? It would require something like:

   i915_sched_enable_scheduling(se, engine, tasklet)

Or something like that if my memory still holds.

Regards,

Tvrtko

> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>   drivers/gpu/drm/i915/gt/intel_engine.h         |  6 ++++++
>   drivers/gpu/drm/i915/gt/intel_engine_types.h   | 18 ++++--------------
>   .../drm/i915/gt/intel_execlists_submission.c   |  9 ++++++---
>   drivers/gpu/drm/i915/gt/selftest_execlists.c   |  2 +-
>   drivers/gpu/drm/i915/i915_scheduler_types.h    | 10 ++++++++++
>   5 files changed, 27 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h b/drivers/gpu/drm/i915/gt/intel_engine.h
> index 4f0163457aed..ca3a9cb06328 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine.h
> +++ b/drivers/gpu/drm/i915/gt/intel_engine.h
> @@ -279,4 +279,10 @@ intel_engine_flush_scheduler(struct intel_engine_cs *engine)
>   	i915_sched_flush(intel_engine_get_scheduler(engine));
>   }
>   
> +static inline bool
> +intel_engine_has_timeslices(struct intel_engine_cs *engine)
> +{
> +	return i915_sched_has_timeslices(intel_engine_get_scheduler(engine));
> +}
> +
>   #endif /* _INTEL_RINGBUFFER_H_ */
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h
> index a3024a0de1de..96a0aec29672 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
> +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
> @@ -442,11 +442,10 @@ struct intel_engine_cs {
>   #define I915_ENGINE_SUPPORTS_STATS   BIT(1)
>   #define I915_ENGINE_HAS_PREEMPTION   BIT(2)
>   #define I915_ENGINE_HAS_SEMAPHORES   BIT(3)
> -#define I915_ENGINE_HAS_TIMESLICES   BIT(4)
> -#define I915_ENGINE_NEEDS_BREADCRUMB_TASKLET BIT(5)
> -#define I915_ENGINE_IS_VIRTUAL       BIT(6)
> -#define I915_ENGINE_HAS_RELATIVE_MMIO BIT(7)
> -#define I915_ENGINE_REQUIRES_CMD_PARSER BIT(8)
> +#define I915_ENGINE_NEEDS_BREADCRUMB_TASKLET BIT(4)
> +#define I915_ENGINE_IS_VIRTUAL       BIT(5)
> +#define I915_ENGINE_HAS_RELATIVE_MMIO BIT(6)
> +#define I915_ENGINE_REQUIRES_CMD_PARSER BIT(7)
>   	unsigned int flags;
>   
>   	/*
> @@ -541,15 +540,6 @@ intel_engine_has_semaphores(const struct intel_engine_cs *engine)
>   	return engine->flags & I915_ENGINE_HAS_SEMAPHORES;
>   }
>   
> -static inline bool
> -intel_engine_has_timeslices(const struct intel_engine_cs *engine)
> -{
> -	if (!IS_ACTIVE(CONFIG_DRM_I915_TIMESLICE_DURATION))
> -		return false;
> -
> -	return engine->flags & I915_ENGINE_HAS_TIMESLICES;
> -}
> -
>   static inline bool
>   intel_engine_needs_breadcrumb_tasklet(const struct intel_engine_cs *engine)
>   {
> diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
> index 3217cb4369ad..d4b6d262265a 100644
> --- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
> +++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
> @@ -1023,7 +1023,7 @@ static bool needs_timeslice(const struct intel_engine_cs *engine,
>   {
>   	const struct i915_sched *se = &engine->sched;
>   
> -	if (!intel_engine_has_timeslices(engine))
> +	if (!i915_sched_has_timeslices(se))
>   		return false;
>   
>   	/* If not currently active, or about to switch, wait for next event */
> @@ -2918,8 +2918,6 @@ logical_ring_default_vfuncs(struct intel_engine_cs *engine)
>   		engine->flags |= I915_ENGINE_HAS_SEMAPHORES;
>   		if (can_preempt(engine)) {
>   			engine->flags |= I915_ENGINE_HAS_PREEMPTION;
> -			if (IS_ACTIVE(CONFIG_DRM_I915_TIMESLICE_DURATION))
> -				engine->flags |= I915_ENGINE_HAS_TIMESLICES;
>   		}
>   	}
>   
> @@ -2927,6 +2925,11 @@ logical_ring_default_vfuncs(struct intel_engine_cs *engine)
>   		engine->emit_bb_start = gen8_emit_bb_start;
>   	else
>   		engine->emit_bb_start = gen8_emit_bb_start_noarb;
> +
> +	if (IS_ACTIVE(CONFIG_DRM_I915_TIMESLICE_DURATION) &&
> +	    intel_engine_has_preemption(engine))
> +		__set_bit(I915_SCHED_HAS_TIMESLICES_BIT,
> +			  &engine->sched.flags);
>   }
>   
>   static void logical_ring_default_irqs(struct intel_engine_cs *engine)
> diff --git a/drivers/gpu/drm/i915/gt/selftest_execlists.c b/drivers/gpu/drm/i915/gt/selftest_execlists.c
> index cfc0f4b9fbc5..147cbfd6dec0 100644
> --- a/drivers/gpu/drm/i915/gt/selftest_execlists.c
> +++ b/drivers/gpu/drm/i915/gt/selftest_execlists.c
> @@ -3825,7 +3825,7 @@ static unsigned int
>   __select_siblings(struct intel_gt *gt,
>   		  unsigned int class,
>   		  struct intel_engine_cs **siblings,
> -		  bool (*filter)(const struct intel_engine_cs *))
> +		  bool (*filter)(struct intel_engine_cs *))
>   {
>   	unsigned int n = 0;
>   	unsigned int inst;
> diff --git a/drivers/gpu/drm/i915/i915_scheduler_types.h b/drivers/gpu/drm/i915/i915_scheduler_types.h
> index cb1eddb7edc8..dfb29b8c2bee 100644
> --- a/drivers/gpu/drm/i915/i915_scheduler_types.h
> +++ b/drivers/gpu/drm/i915/i915_scheduler_types.h
> @@ -12,12 +12,14 @@
>   #include <linux/workqueue.h>
>   
>   #include "i915_priolist_types.h"
> +#include "i915_utils.h"
>   
>   struct drm_printer;
>   struct i915_request;
>   
>   enum {
>   	I915_SCHED_ACTIVE_BIT = 0,
> +	I915_SCHED_HAS_TIMESLICES_BIT,
>   };
>   
>   /**
> @@ -184,4 +186,12 @@ static inline bool i915_sched_is_active(const struct i915_sched *se)
>   	return test_bit(I915_SCHED_ACTIVE_BIT, &se->flags);
>   }
>   
> +static inline bool i915_sched_has_timeslices(const struct i915_sched *se)
> +{
> +	if (!IS_ACTIVE(CONFIG_DRM_I915_TIMESLICE_DURATION))
> +		return false;
> +
> +	return test_bit(I915_SCHED_HAS_TIMESLICES_BIT, &se->flags);
> +}
> +
>   #endif /* _I915_SCHEDULER_TYPES_H_ */
>
Chris Wilson Feb. 4, 2021, 4:11 p.m. UTC | #2
Quoting Tvrtko Ursulin (2021-02-04 15:18:31)
> 
> On 01/02/2021 08:56, Chris Wilson wrote:
> > Whether a scheduler chooses to implement timeslicing is up to it, and
> > not an underlying property of the HW engine. The scheduler does depend
> > on the HW supporting preemption.
> 
> Therefore, continuing on the comment I made in the previous patch, if we 
> had a helper with which engine would request scheduling (setting the 
> tasklet), if it passed in a pointer to itself, scheduler would then be 
> able to inspect if the engine supports preemption and so set its own 
> internal flag. Makes sense? It would require something like:

Actually not keen on pushing the inspection into the core scheduler and
would rather have the backend turn it on for itself. Because it's not
just about the engine supporting preemption, it's about whether or not
the backend wants to bother implement timeslicing itself.

If we skip to the end, it looks like this for execlists:

        i915_sched_init(&el->sched, i915->drm.dev,
                        engine->name, engine->mask,
                        &execlists_ops, engine);

        if (IS_ACTIVE(CONFIG_DRM_I915_TIMESLICE_DURATION) &&
            intel_engine_has_preemption(engine))
                __set_bit(I915_SCHED_TIMESLICE_BIT, &el->sched.flags);

        if (intel_engine_has_preemption(engine)) {
                __set_bit(I915_SCHED_BUSYWAIT_BIT, &el->sched.flags);
                __set_bit(I915_SCHED_PREEMPT_RESET_BIT, &el->sched.flags);
        }

with the virtual scheduler:

        ve->base.sched =
                i915_sched_create(ve->base.i915->drm.dev,
                                  ve->base.name,
                                  ve->base.mask,
                                  &virtual_ops, ve);
        if (!ve->base.sched) {
                err = -ENOMEM;
                goto err_put;
        }

        ve->base.sched->flags |= sched; /* override submission method */

I think the virtual scheduler suggests that we can't rely on the
scheduler core to dtrt by itself. And if you are still awake by the time
we get to this point, how to avoid ve->base.sched->flags |= sched are
welcome.
-Chris
Tvrtko Ursulin Feb. 5, 2021, 9:48 a.m. UTC | #3
On 04/02/2021 16:11, Chris Wilson wrote:
> Quoting Tvrtko Ursulin (2021-02-04 15:18:31)
>>
>> On 01/02/2021 08:56, Chris Wilson wrote:
>>> Whether a scheduler chooses to implement timeslicing is up to it, and
>>> not an underlying property of the HW engine. The scheduler does depend
>>> on the HW supporting preemption.
>>
>> Therefore, continuing on the comment I made in the previous patch, if we
>> had a helper with which engine would request scheduling (setting the
>> tasklet), if it passed in a pointer to itself, scheduler would then be
>> able to inspect if the engine supports preemption and so set its own
>> internal flag. Makes sense? It would require something like:
> 
> Actually not keen on pushing the inspection into the core scheduler and
> would rather have the backend turn it on for itself. Because it's not
> just about the engine supporting preemption, it's about whether or not
> the backend wants to bother implement timeslicing itself.
> 
> If we skip to the end, it looks like this for execlists:
> 
>          i915_sched_init(&el->sched, i915->drm.dev,
>                          engine->name, engine->mask,
>                          &execlists_ops, engine);
> 
>          if (IS_ACTIVE(CONFIG_DRM_I915_TIMESLICE_DURATION) &&
>              intel_engine_has_preemption(engine))
>                  __set_bit(I915_SCHED_TIMESLICE_BIT, &el->sched.flags);
> 
>          if (intel_engine_has_preemption(engine)) {
>                  __set_bit(I915_SCHED_BUSYWAIT_BIT, &el->sched.flags);
>                  __set_bit(I915_SCHED_PREEMPT_RESET_BIT, &el->sched.flags);
>          }
> 
> with the virtual scheduler:
> 
>          ve->base.sched =
>                  i915_sched_create(ve->base.i915->drm.dev,
>                                    ve->base.name,
>                                    ve->base.mask,
>                                    &virtual_ops, ve);
>          if (!ve->base.sched) {
>                  err = -ENOMEM;
>                  goto err_put;
>          }
> 
>          ve->base.sched->flags |= sched; /* override submission method */
> 
> I think the virtual scheduler suggests that we can't rely on the
> scheduler core to dtrt by itself. And if you are still awake by the time
> we get to this point, how to avoid ve->base.sched->flags |= sched are
> welcome.

Not at the moment. Since it is details lets finish first and then see is 
my thinking.

Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

Regards,

Tvrtko
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h b/drivers/gpu/drm/i915/gt/intel_engine.h
index 4f0163457aed..ca3a9cb06328 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine.h
@@ -279,4 +279,10 @@  intel_engine_flush_scheduler(struct intel_engine_cs *engine)
 	i915_sched_flush(intel_engine_get_scheduler(engine));
 }
 
+static inline bool
+intel_engine_has_timeslices(struct intel_engine_cs *engine)
+{
+	return i915_sched_has_timeslices(intel_engine_get_scheduler(engine));
+}
+
 #endif /* _INTEL_RINGBUFFER_H_ */
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index a3024a0de1de..96a0aec29672 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -442,11 +442,10 @@  struct intel_engine_cs {
 #define I915_ENGINE_SUPPORTS_STATS   BIT(1)
 #define I915_ENGINE_HAS_PREEMPTION   BIT(2)
 #define I915_ENGINE_HAS_SEMAPHORES   BIT(3)
-#define I915_ENGINE_HAS_TIMESLICES   BIT(4)
-#define I915_ENGINE_NEEDS_BREADCRUMB_TASKLET BIT(5)
-#define I915_ENGINE_IS_VIRTUAL       BIT(6)
-#define I915_ENGINE_HAS_RELATIVE_MMIO BIT(7)
-#define I915_ENGINE_REQUIRES_CMD_PARSER BIT(8)
+#define I915_ENGINE_NEEDS_BREADCRUMB_TASKLET BIT(4)
+#define I915_ENGINE_IS_VIRTUAL       BIT(5)
+#define I915_ENGINE_HAS_RELATIVE_MMIO BIT(6)
+#define I915_ENGINE_REQUIRES_CMD_PARSER BIT(7)
 	unsigned int flags;
 
 	/*
@@ -541,15 +540,6 @@  intel_engine_has_semaphores(const struct intel_engine_cs *engine)
 	return engine->flags & I915_ENGINE_HAS_SEMAPHORES;
 }
 
-static inline bool
-intel_engine_has_timeslices(const struct intel_engine_cs *engine)
-{
-	if (!IS_ACTIVE(CONFIG_DRM_I915_TIMESLICE_DURATION))
-		return false;
-
-	return engine->flags & I915_ENGINE_HAS_TIMESLICES;
-}
-
 static inline bool
 intel_engine_needs_breadcrumb_tasklet(const struct intel_engine_cs *engine)
 {
diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
index 3217cb4369ad..d4b6d262265a 100644
--- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
@@ -1023,7 +1023,7 @@  static bool needs_timeslice(const struct intel_engine_cs *engine,
 {
 	const struct i915_sched *se = &engine->sched;
 
-	if (!intel_engine_has_timeslices(engine))
+	if (!i915_sched_has_timeslices(se))
 		return false;
 
 	/* If not currently active, or about to switch, wait for next event */
@@ -2918,8 +2918,6 @@  logical_ring_default_vfuncs(struct intel_engine_cs *engine)
 		engine->flags |= I915_ENGINE_HAS_SEMAPHORES;
 		if (can_preempt(engine)) {
 			engine->flags |= I915_ENGINE_HAS_PREEMPTION;
-			if (IS_ACTIVE(CONFIG_DRM_I915_TIMESLICE_DURATION))
-				engine->flags |= I915_ENGINE_HAS_TIMESLICES;
 		}
 	}
 
@@ -2927,6 +2925,11 @@  logical_ring_default_vfuncs(struct intel_engine_cs *engine)
 		engine->emit_bb_start = gen8_emit_bb_start;
 	else
 		engine->emit_bb_start = gen8_emit_bb_start_noarb;
+
+	if (IS_ACTIVE(CONFIG_DRM_I915_TIMESLICE_DURATION) &&
+	    intel_engine_has_preemption(engine))
+		__set_bit(I915_SCHED_HAS_TIMESLICES_BIT,
+			  &engine->sched.flags);
 }
 
 static void logical_ring_default_irqs(struct intel_engine_cs *engine)
diff --git a/drivers/gpu/drm/i915/gt/selftest_execlists.c b/drivers/gpu/drm/i915/gt/selftest_execlists.c
index cfc0f4b9fbc5..147cbfd6dec0 100644
--- a/drivers/gpu/drm/i915/gt/selftest_execlists.c
+++ b/drivers/gpu/drm/i915/gt/selftest_execlists.c
@@ -3825,7 +3825,7 @@  static unsigned int
 __select_siblings(struct intel_gt *gt,
 		  unsigned int class,
 		  struct intel_engine_cs **siblings,
-		  bool (*filter)(const struct intel_engine_cs *))
+		  bool (*filter)(struct intel_engine_cs *))
 {
 	unsigned int n = 0;
 	unsigned int inst;
diff --git a/drivers/gpu/drm/i915/i915_scheduler_types.h b/drivers/gpu/drm/i915/i915_scheduler_types.h
index cb1eddb7edc8..dfb29b8c2bee 100644
--- a/drivers/gpu/drm/i915/i915_scheduler_types.h
+++ b/drivers/gpu/drm/i915/i915_scheduler_types.h
@@ -12,12 +12,14 @@ 
 #include <linux/workqueue.h>
 
 #include "i915_priolist_types.h"
+#include "i915_utils.h"
 
 struct drm_printer;
 struct i915_request;
 
 enum {
 	I915_SCHED_ACTIVE_BIT = 0,
+	I915_SCHED_HAS_TIMESLICES_BIT,
 };
 
 /**
@@ -184,4 +186,12 @@  static inline bool i915_sched_is_active(const struct i915_sched *se)
 	return test_bit(I915_SCHED_ACTIVE_BIT, &se->flags);
 }
 
+static inline bool i915_sched_has_timeslices(const struct i915_sched *se)
+{
+	if (!IS_ACTIVE(CONFIG_DRM_I915_TIMESLICE_DURATION))
+		return false;
+
+	return test_bit(I915_SCHED_HAS_TIMESLICES_BIT, &se->flags);
+}
+
 #endif /* _I915_SCHEDULER_TYPES_H_ */