Commit 72338a1f authored by Chris Wilson's avatar Chris Wilson

drm/i915/gt: Expose reset stop timeout via sysfs

When we allow ourselves to sleep before a GPU reset after disabling
submission, even for a few milliseconds, gives an innocent context the
opportunity to clear the GPU before the reset occurs. However, how long
to sleep depends on the typical non-preemptible duration (a similar
problem to determining the ideal preempt-reset timeout or even the
heartbeat interval). As this seems of a hard policy decision, punt it to
userspace.

The timeout can be adjusted using

	/sys/class/drm/card?/engine/*/stop_timeout_ms
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Jon Bloomfield <jon.bloomfield@intel.com>
Reviewed-by: default avatarSteve Carbonari <steven.carbonari@intel.com>
Tested-by: default avatarSteve Carbonari <steven.carbonari@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200228131716.3243616-5-chris@chris-wilson.co.uk
parent 062444bb
...@@ -63,6 +63,9 @@ config DRM_I915_STOP_TIMEOUT ...@@ -63,6 +63,9 @@ config DRM_I915_STOP_TIMEOUT
that the reset itself may take longer and so be more disruptive to that the reset itself may take longer and so be more disruptive to
interactive or low latency workloads. interactive or low latency workloads.
This is adjustable via
/sys/class/drm/card?/engine/*/stop_timeout_ms
config DRM_I915_TIMESLICE_DURATION config DRM_I915_TIMESLICE_DURATION
int "Scheduling quantum for userspace batches (ms, jiffy granularity)" int "Scheduling quantum for userspace batches (ms, jiffy granularity)"
default 1 # milliseconds default 1 # milliseconds
......
...@@ -232,6 +232,45 @@ timeslice_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) ...@@ -232,6 +232,45 @@ timeslice_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
static struct kobj_attribute timeslice_duration_attr = static struct kobj_attribute timeslice_duration_attr =
__ATTR(timeslice_duration_ms, 0644, timeslice_show, timeslice_store); __ATTR(timeslice_duration_ms, 0644, timeslice_show, timeslice_store);
static ssize_t
stop_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t count)
{
struct intel_engine_cs *engine = kobj_to_engine(kobj);
unsigned long long duration;
int err;
/*
* When we allow ourselves to sleep before a GPU reset after disabling
* submission, even for a few milliseconds, gives an innocent context
* the opportunity to clear the GPU before the reset occurs. However,
* how long to sleep depends on the typical non-preemptible duration
* (a similar problem to determining the ideal preempt-reset timeout
* or even the heartbeat interval).
*/
err = kstrtoull(buf, 0, &duration);
if (err)
return err;
if (duration > jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT))
return -EINVAL;
WRITE_ONCE(engine->props.stop_timeout_ms, duration);
return count;
}
static ssize_t
stop_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct intel_engine_cs *engine = kobj_to_engine(kobj);
return sprintf(buf, "%lu\n", engine->props.stop_timeout_ms);
}
static struct kobj_attribute stop_timeout_attr =
__ATTR(stop_timeout_ms, 0644, stop_show, stop_store);
static void kobj_engine_release(struct kobject *kobj) static void kobj_engine_release(struct kobject *kobj)
{ {
kfree(kobj); kfree(kobj);
...@@ -273,6 +312,7 @@ void intel_engines_add_sysfs(struct drm_i915_private *i915) ...@@ -273,6 +312,7 @@ void intel_engines_add_sysfs(struct drm_i915_private *i915)
&caps_attr.attr, &caps_attr.attr,
&all_caps_attr.attr, &all_caps_attr.attr,
&max_spin_attr.attr, &max_spin_attr.attr,
&stop_timeout_attr.attr,
NULL NULL
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment