aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-10-03 16:34:53 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2017-10-04 12:52:46 -0400
commitac14fbd460d0ec16e7750e40dcd8199b0ff83d0a (patch)
tree73adbde54a0150ad818049ddfd51df7ff32580d4
parentbeecec9017901849352cfd2886981fe462f9fed0 (diff)
drm/i915/scheduler: Support user-defined priorities
Use a priority stored in the context as the initial value when submitting a request. This allows us to change the default priority on a per-context basis, allowing different contexts to be favoured with GPU time at the expense of lower importance work. The user can adjust the context's priority via I915_CONTEXT_PARAM_PRIORITY, with more positive values being higher priority (they will be serviced earlier, after their dependencies have been resolved). Any prerequisite work for an execbuf will have its priority raised to match the new request as required. Normal users can specify any value in the range of -1023 to 0 [default], i.e. they can reduce the priority of their workloads (and temporarily boost it back to normal if so desired). Privileged users can specify any value in the range of -1023 to 1023, [default is 0], i.e. they can raise their priority above all overs and so potentially starve the system. Note that the existing schedulers are not fair, nor load balancing, the execution is strictly by priority on a first-come, first-served basis, and the driver may choose to boost some requests above the range available to users. This priority was originally based around nice(2), but evolved to allow clients to adjust their priority within a small range, and allow for a privileged high priority range. For example, this can be used to implement EGL_IMG_context_priority https://www.khronos.org/registry/egl/extensions/IMG/EGL_IMG_context_priority.txt EGL_CONTEXT_PRIORITY_LEVEL_IMG determines the priority level of the context to be created. This attribute is a hint, as an implementation may not support multiple contexts at some priority levels and system policy may limit access to high priority contexts to appropriate system privilege level. The default value for EGL_CONTEXT_PRIORITY_LEVEL_IMG is EGL_CONTEXT_PRIORITY_MEDIUM_IMG." so we can map PRIORITY_HIGH -> 1023 [privileged, will failback to 0] PRIORITY_MED -> 0 [default] PRIORITY_LOW -> -1023 They also map onto the priorities used by VkQueue (and a VkQueue is essentially a timeline, our i915_gem_context under full-ppgtt). v2: s/CAP_SYS_ADMIN/CAP_SYS_NICE/ v3: Report min/max user priorities as defines in the uapi, and rebase internal priorities on the exposed values. Testcase: igt/gem_exec_schedule Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20171003203453.15692-9-chris@chris-wilson.co.uk
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c1
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.c23
-rw-r--r--drivers/gpu/drm/i915/i915_gem_request.h14
-rw-r--r--include/uapi/drm/i915_drm.h7
4 files changed, 41 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 7614880edad8..66fc156b294a 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -370,6 +370,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
370 value = 0; 370 value = 0;
371 if (dev_priv->engine[RCS] && dev_priv->engine[RCS]->schedule) { 371 if (dev_priv->engine[RCS] && dev_priv->engine[RCS]->schedule) {
372 value |= I915_SCHEDULER_CAP_ENABLED; 372 value |= I915_SCHEDULER_CAP_ENABLED;
373 value |= I915_SCHEDULER_CAP_PRIORITY;
373 374
374 if (INTEL_INFO(dev_priv)->has_logical_ring_preemption && 375 if (INTEL_INFO(dev_priv)->has_logical_ring_preemption &&
375 i915_modparams.enable_execlists && 376 i915_modparams.enable_execlists &&
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 2bb8e58706ba..5bf96a258509 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -1070,6 +1070,9 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
1070 case I915_CONTEXT_PARAM_BANNABLE: 1070 case I915_CONTEXT_PARAM_BANNABLE:
1071 args->value = i915_gem_context_is_bannable(ctx); 1071 args->value = i915_gem_context_is_bannable(ctx);
1072 break; 1072 break;
1073 case I915_CONTEXT_PARAM_PRIORITY:
1074 args->value = ctx->priority;
1075 break;
1073 default: 1076 default:
1074 ret = -EINVAL; 1077 ret = -EINVAL;
1075 break; 1078 break;
@@ -1125,6 +1128,26 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
1125 else 1128 else
1126 i915_gem_context_clear_bannable(ctx); 1129 i915_gem_context_clear_bannable(ctx);
1127 break; 1130 break;
1131
1132 case I915_CONTEXT_PARAM_PRIORITY:
1133 {
1134 int priority = args->value;
1135
1136 if (args->size)
1137 ret = -EINVAL;
1138 else if (!to_i915(dev)->engine[RCS]->schedule)
1139 ret = -ENODEV;
1140 else if (priority > I915_CONTEXT_MAX_USER_PRIORITY ||
1141 priority < I915_CONTEXT_MIN_USER_PRIORITY)
1142 ret = -EINVAL;
1143 else if (priority > I915_CONTEXT_DEFAULT_PRIORITY &&
1144 !capable(CAP_SYS_NICE))
1145 ret = -EPERM;
1146 else
1147 ctx->priority = priority;
1148 }
1149 break;
1150
1128 default: 1151 default:
1129 ret = -EINVAL; 1152 ret = -EINVAL;
1130 break; 1153 break;
diff --git a/drivers/gpu/drm/i915/i915_gem_request.h b/drivers/gpu/drm/i915/i915_gem_request.h
index 6b9e992d01de..26249f39de67 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.h
+++ b/drivers/gpu/drm/i915/i915_gem_request.h
@@ -30,6 +30,8 @@
30#include "i915_gem.h" 30#include "i915_gem.h"
31#include "i915_sw_fence.h" 31#include "i915_sw_fence.h"
32 32
33#include <uapi/drm/i915_drm.h>
34
33struct drm_file; 35struct drm_file;
34struct drm_i915_gem_object; 36struct drm_i915_gem_object;
35struct drm_i915_gem_request; 37struct drm_i915_gem_request;
@@ -69,10 +71,14 @@ struct i915_priotree {
69 struct list_head waiters_list; /* those after us, they depend upon us */ 71 struct list_head waiters_list; /* those after us, they depend upon us */
70 struct list_head link; 72 struct list_head link;
71 int priority; 73 int priority;
72#define I915_PRIORITY_MAX 1024 74};
73#define I915_PRIORITY_NORMAL 0 75
74#define I915_PRIORITY_MIN (-I915_PRIORITY_MAX) 76enum {
75#define I915_PRIORITY_INVALID INT_MIN 77 I915_PRIORITY_MIN = I915_CONTEXT_MIN_USER_PRIORITY - 1,
78 I915_PRIORITY_NORMAL = I915_CONTEXT_DEFAULT_PRIORITY,
79 I915_PRIORITY_MAX = I915_CONTEXT_MAX_USER_PRIORITY + 1,
80
81 I915_PRIORITY_INVALID = INT_MIN
76}; 82};
77 83
78struct i915_gem_capture_list { 84struct i915_gem_capture_list {
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index aa4a3b20ef6b..7266b53191ee 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -402,6 +402,9 @@ typedef struct drm_i915_irq_wait {
402 * priorities and the driver will attempt to execute batches in priority order. 402 * priorities and the driver will attempt to execute batches in priority order.
403 * The param returns a capability bitmask, nonzero implies that the scheduler 403 * The param returns a capability bitmask, nonzero implies that the scheduler
404 * is enabled, with different features present according to the mask. 404 * is enabled, with different features present according to the mask.
405 *
406 * The initial priority for each batch is supplied by the context and is
407 * controlled via I915_CONTEXT_PARAM_PRIORITY.
405 */ 408 */
406#define I915_PARAM_HAS_SCHEDULER 41 409#define I915_PARAM_HAS_SCHEDULER 41
407#define I915_SCHEDULER_CAP_ENABLED (1ul << 0) 410#define I915_SCHEDULER_CAP_ENABLED (1ul << 0)
@@ -1367,6 +1370,10 @@ struct drm_i915_gem_context_param {
1367#define I915_CONTEXT_PARAM_GTT_SIZE 0x3 1370#define I915_CONTEXT_PARAM_GTT_SIZE 0x3
1368#define I915_CONTEXT_PARAM_NO_ERROR_CAPTURE 0x4 1371#define I915_CONTEXT_PARAM_NO_ERROR_CAPTURE 0x4
1369#define I915_CONTEXT_PARAM_BANNABLE 0x5 1372#define I915_CONTEXT_PARAM_BANNABLE 0x5
1373#define I915_CONTEXT_PARAM_PRIORITY 0x6
1374#define I915_CONTEXT_MAX_USER_PRIORITY 1023 /* inclusive */
1375#define I915_CONTEXT_DEFAULT_PRIORITY 0
1376#define I915_CONTEXT_MIN_USER_PRIORITY -1023 /* inclusive */
1370 __u64 value; 1377 __u64 value;
1371}; 1378};
1372 1379