mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-03-22 07:27:12 +08:00
drm/i915/guc: Limit scheduling properties to avoid overflow
GuC converts the pre-emption timeout and timeslice quantum values into clock ticks internally. That significantly reduces the point of 32bit overflow. On current platforms, worst case scenario is approximately 110 seconds. Rather than allowing the user to set higher values and then get confused by early timeouts, add limits when setting these values. v2: Add helper functions for clamping (review feedback from Tvrtko). v3: Add a bunch of BUG_ON range checks in addition to the checks already in the clamping functions (Tvrtko) Signed-off-by: John Harrison <John.C.Harrison@Intel.com> Reviewed-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> Acked-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20221006213813.1563435-2-John.C.Harrison@Intel.com
This commit is contained in:
@@ -512,6 +512,26 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id,
|
||||
engine->flags |= I915_ENGINE_HAS_EU_PRIORITY;
|
||||
}
|
||||
|
||||
/* Cap properties according to any system limits */
|
||||
#define CLAMP_PROP(field) \
|
||||
do { \
|
||||
u64 clamp = intel_clamp_##field(engine, engine->props.field); \
|
||||
if (clamp != engine->props.field) { \
|
||||
drm_notice(&engine->i915->drm, \
|
||||
"Warning, clamping %s to %lld to prevent overflow\n", \
|
||||
#field, clamp); \
|
||||
engine->props.field = clamp; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
CLAMP_PROP(heartbeat_interval_ms);
|
||||
CLAMP_PROP(max_busywait_duration_ns);
|
||||
CLAMP_PROP(preempt_timeout_ms);
|
||||
CLAMP_PROP(stop_timeout_ms);
|
||||
CLAMP_PROP(timeslice_duration_ms);
|
||||
|
||||
#undef CLAMP_PROP
|
||||
|
||||
engine->defaults = engine->props; /* never to change again */
|
||||
|
||||
engine->context_size = intel_engine_context_size(gt, engine->class);
|
||||
@@ -534,6 +554,55 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 intel_clamp_heartbeat_interval_ms(struct intel_engine_cs *engine, u64 value)
|
||||
{
|
||||
value = min_t(u64, value, jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT));
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
u64 intel_clamp_max_busywait_duration_ns(struct intel_engine_cs *engine, u64 value)
|
||||
{
|
||||
value = min(value, jiffies_to_nsecs(2));
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
u64 intel_clamp_preempt_timeout_ms(struct intel_engine_cs *engine, u64 value)
|
||||
{
|
||||
/*
|
||||
* NB: The GuC API only supports 32bit values. However, the limit is further
|
||||
* reduced due to internal calculations which would otherwise overflow.
|
||||
*/
|
||||
if (intel_guc_submission_is_wanted(&engine->gt->uc.guc))
|
||||
value = min_t(u64, value, guc_policy_max_preempt_timeout_ms());
|
||||
|
||||
value = min_t(u64, value, jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT));
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
u64 intel_clamp_stop_timeout_ms(struct intel_engine_cs *engine, u64 value)
|
||||
{
|
||||
value = min_t(u64, value, jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT));
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
u64 intel_clamp_timeslice_duration_ms(struct intel_engine_cs *engine, u64 value)
|
||||
{
|
||||
/*
|
||||
* NB: The GuC API only supports 32bit values. However, the limit is further
|
||||
* reduced due to internal calculations which would otherwise overflow.
|
||||
*/
|
||||
if (intel_guc_submission_is_wanted(&engine->gt->uc.guc))
|
||||
value = min_t(u64, value, guc_policy_max_exec_quantum_ms());
|
||||
|
||||
value = min_t(u64, value, jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT));
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static void __setup_engine_capabilities(struct intel_engine_cs *engine)
|
||||
{
|
||||
struct drm_i915_private *i915 = engine->i915;
|
||||
|
||||
Reference in New Issue
Block a user