There are cases where a system integrator may wish to raise/lower the priority of GPU workloads being submitted by specific OS process(es), independently of how the software self-classifies its own priority. Exposing "priority offset" as an i915-specific cgroup parameter will enable such system-level configuration. Normally GPU contexts start with a priority value of 0 (I915_CONTEXT_DEFAULT_PRIORITY) and then may be adjusted up/down from there via other mechanisms. We'd like to provide a system-level input to the priority decision that will be taken into consideration, even when userspace later attempts to set an absolute priority value via I915_CONTEXT_PARAM_PRIORITY. The priority offset introduced here provides a base value that will always be added to (or subtracted from) the software's self-assigned priority value. This patch makes priority offset a cgroup-specific value; contexts will be created with a priority offset based on the cgroup membership of the process creating the context at the time the context is created. Note that priority offset is assigned at context creation time; migrating a process to a different cgroup or changing the offset associated with a cgroup will only affect new context creation and will not alter the behavior of existing contexts previously created by the process. v2: - Rebase onto new cgroup_priv API - Use current instead of drm_file->pid to determine which process to lookup priority for. (Chris) - Don't forget to subtract priority offset in context_getparam ioctl to make it match setparam behavior. (Chris) Signed-off-by: Matt Roper <matthew.d.roper@xxxxxxxxx> --- drivers/gpu/drm/i915/i915_cgroup.c | 47 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_drv.h | 15 ++++++----- drivers/gpu/drm/i915/i915_gem_context.c | 7 ++--- drivers/gpu/drm/i915/i915_gem_context.h | 9 +++++++ include/uapi/drm/i915_drm.h | 1 + 5 files changed, 69 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_cgroup.c b/drivers/gpu/drm/i915/i915_cgroup.c index 4a46cb167f53..6a28b1a23971 100644 --- a/drivers/gpu/drm/i915/i915_cgroup.c +++ b/drivers/gpu/drm/i915/i915_cgroup.c @@ -13,6 +13,8 @@ struct i915_cgroup_data { struct cgroup_priv base; struct list_head node; + + int priority_offset; }; static inline struct i915_cgroup_data * @@ -117,8 +119,10 @@ i915_cgroup_setparam_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_cgroup_param *req = data; struct cgroup *cgrp; + struct i915_cgroup_data *cgrpdata; int ret; /* We don't actually support any flags yet. */ @@ -154,7 +158,18 @@ i915_cgroup_setparam_ioctl(struct drm_device *dev, if (ret) goto out; + cgrpdata = get_or_create_cgroup_data(dev_priv, cgrp); + if (IS_ERR(cgrpdata)) { + ret = PTR_ERR(cgrpdata); + goto out; + } + switch (req->param) { + case I915_CGROUP_PARAM_PRIORITY_OFFSET: + DRM_DEBUG_DRIVER("Setting cgroup priority offset to %lld\n", + req->value); + cgrpdata->priority_offset = req->value; + break; default: DRM_DEBUG_DRIVER("Invalid cgroup parameter %lld\n", req->param); ret = -EINVAL; @@ -165,3 +180,35 @@ i915_cgroup_setparam_ioctl(struct drm_device *dev, return ret; } + +/** + * i915_cgroup_get_prio_offset() - get prio offset for current proc's cgroup + * @dev_priv: drm device + * @file_priv: file handle for calling process + * + * RETURNS: + * Priority offset associated with the calling process' cgroup in the default + * (v2) hierarchy, otherwise 0 if no explicit priority has been assigned. + */ +int +i915_cgroup_get_current_prio_offset(struct drm_i915_private *dev_priv) +{ + struct cgroup *cgrp; + struct cgroup_priv *cgrpdata; + int offset = 0; + + cgrp = task_get_dfl_cgroup(current); + if (WARN_ON(!cgrp)) + return 0; + + mutex_lock(&cgrp->privdata_mutex); + + cgrpdata = cgroup_priv_lookup(cgrp, dev_priv); + if (cgrpdata) + offset = cgrp_to_i915(cgrpdata)->priority_offset; + + mutex_unlock(&cgrp->privdata_mutex); + cgroup_put(cgrp); + + return offset; +} diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7c38142ee009..51b80926d20c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2947,18 +2947,19 @@ void i915_cgroup_init(struct drm_i915_private *dev_priv); int i915_cgroup_setparam_ioctl(struct drm_device *dev, void *data, struct drm_file *file); void i915_cgroup_shutdown(struct drm_i915_private *dev_priv); +int i915_cgroup_get_current_prio_offset(struct drm_i915_private *dev_priv); #else -static inline int -i915_cgroup_init(struct drm_i915_private *dev_priv) +static inline void i915_cgroup_init(struct drm_i915_private *dev_priv) {} +static inline void i915_cgroup_shutdown(struct drm_i915_private *dev_priv) {} +static inline int i915_cgroup_setparam_ioctl(struct drm_device *dev, void *data, + struct drm_file *file) { - return 0; + return -EINVAL; } -static inline void i915_cgroup_shutdown(struct drm_i915_private *dev_priv) {} static inline int -i915_cgroup_setparam_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) +i915_cgroup_get_current_prio_offset(struct drm_i915_private *dev_priv) { - return -EINVAL; + return 0; } #endif diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index a73340ae9419..b29fbe0c776f 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -274,7 +274,8 @@ __create_hw_context(struct drm_i915_private *dev_priv, kref_init(&ctx->ref); list_add_tail(&ctx->link, &dev_priv->contexts.list); ctx->i915 = dev_priv; - ctx->priority = I915_PRIORITY_NORMAL; + ctx->priority_offset = i915_cgroup_get_current_prio_offset(dev_priv); + ctx->priority = I915_PRIORITY_NORMAL + ctx->priority_offset; INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL); INIT_LIST_HEAD(&ctx->handles_list); @@ -739,7 +740,7 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data, args->value = i915_gem_context_is_bannable(ctx); break; case I915_CONTEXT_PARAM_PRIORITY: - args->value = ctx->priority; + args->value = ctx->priority - ctx->priority_offset; break; default: ret = -EINVAL; @@ -812,7 +813,7 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data, !capable(CAP_SYS_NICE)) ret = -EPERM; else - ctx->priority = priority; + ctx->priority = priority + ctx->priority_offset; } break; diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h index 7854262ddfd9..c3b4fb54fbb6 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.h +++ b/drivers/gpu/drm/i915/i915_gem_context.h @@ -150,6 +150,15 @@ struct i915_gem_context { */ int priority; + /** + * @priority_offset: priority offset + * + * A value, configured via cgroup, that sets the starting priority + * of the context. Any priority set explicitly via context parameter + * will be added to the priority offset. + */ + int priority_offset; + /** ggtt_offset_bias: placement restriction for context objects */ u32 ggtt_offset_bias; diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index b6651b263838..5b67aaf8a1c0 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -1624,6 +1624,7 @@ struct drm_i915_cgroup_param { __s32 cgroup_fd; __u32 flags; __u64 param; +#define I915_CGROUP_PARAM_PRIORITY_OFFSET 0x1 __s64 value; }; -- 2.14.3 -- To unsubscribe from this list: send the line "unsubscribe cgroups" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html