From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Register i915 as supporting the drm cgroup controller priority management
and wire it up at execbuf time.
GEM context configured priority then works as a relative value on top of
the base level obtained from the drm cgroup controller.
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
.../gpu/drm/i915/gem/i915_gem_execbuffer.c | 27 ++++++++++++++++++-
drivers/gpu/drm/i915/i915_driver.c | 10 +++++++
drivers/gpu/drm/i915/i915_drm_client.c | 16 +++++++++++
drivers/gpu/drm/i915/i915_drm_client.h | 4 +++
4 files changed, 56 insertions(+), 1 deletion(-)
@@ -4,8 +4,10 @@
* Copyright © 2008,2010 Intel Corporation
*/
+#include <linux/cgroup_drm.h>
#include <linux/dma-resv.h>
#include <linux/highmem.h>
+#include <linux/minmax.h>
#include <linux/sync_file.h>
#include <linux/uaccess.h>
@@ -3015,6 +3017,29 @@ static void retire_requests(struct intel_timeline *tl, struct i915_request *end)
break;
}
+#ifdef CONFIG_CGROUP_DRM
+static void copy_priority(struct i915_sched_attr *attr,
+ const struct i915_execbuffer *eb)
+{
+ const int scale = DIV_ROUND_CLOSEST(DRM_CGROUP_PRIORITY_MAX,
+ I915_CONTEXT_MAX_USER_PRIORITY);
+ int prio;
+
+ *attr = eb->gem_context->sched;
+ prio = attr->priority * scale + eb->file->drm_cgroup_priority;
+ prio = DIV_ROUND_UP(prio, scale);
+ attr->priority = clamp(prio,
+ I915_CONTEXT_MIN_USER_PRIORITY,
+ I915_CONTEXT_MAX_USER_PRIORITY);
+}
+#else
+static void copy_priority(struct i915_sched_attr *attr,
+ const struct i915_execbuffer *eb)
+{
+ *attr = eb->gem_context->sched;
+}
+#endif
+
static int eb_request_add(struct i915_execbuffer *eb, struct i915_request *rq,
int err, bool last_parallel)
{
@@ -3031,7 +3056,7 @@ static int eb_request_add(struct i915_execbuffer *eb, struct i915_request *rq,
/* Check that the context wasn't destroyed before submission */
if (likely(!intel_context_is_closed(eb->context))) {
- attr = eb->gem_context->sched;
+ copy_priority(&attr, eb);
} else {
/* Serialise with context_close via the add_to_timeline */
i915_request_set_error_once(rq, -ENOENT);
@@ -1893,6 +1893,12 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_GEM_VM_DESTROY, i915_gem_vm_destroy_ioctl, DRM_RENDER_ALLOW),
};
+#ifdef CONFIG_CGROUP_DRM
+static const struct drm_cgroup_ops i915_drm_cgroup_ops = {
+ .priority_levels = i915_drm_priority_levels,
+};
+#endif
+
/*
* Interface history:
*
@@ -1921,6 +1927,10 @@ static const struct drm_driver i915_drm_driver = {
.lastclose = i915_driver_lastclose,
.postclose = i915_driver_postclose,
+#ifdef CONFIG_CGROUP_DRM
+ .cg_ops = &i915_drm_cgroup_ops,
+#endif
+
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_import = i915_gem_prime_import,
@@ -75,6 +75,22 @@ void i915_drm_clients_fini(struct i915_drm_clients *clients)
xa_destroy(&clients->xarray);
}
+#ifdef CONFIG_CGROUP_DRM
+unsigned int i915_drm_priority_levels(struct drm_file *file)
+{
+ struct drm_i915_file_private *fpriv = file->driver_priv;
+ struct i915_drm_client *client = fpriv->client;
+ struct drm_i915_private *i915 = client->clients->i915;
+
+ if (GRAPHICS_VER(i915) < 8)
+ return 0;
+ else if (intel_uc_uses_guc_submission(&to_gt(i915)->uc))
+ return 3;
+ else
+ return 2047;
+}
+#endif
+
#ifdef CONFIG_PROC_FS
static const char * const uabi_class_names[] = {
[I915_ENGINE_CLASS_RENDER] = "render",
@@ -15,6 +15,8 @@
#define I915_LAST_UABI_ENGINE_CLASS I915_ENGINE_CLASS_COMPUTE
+struct drm_file;
+
struct drm_i915_private;
struct i915_drm_clients {
@@ -65,4 +67,6 @@ void i915_drm_client_fdinfo(struct seq_file *m, struct file *f);
void i915_drm_clients_fini(struct i915_drm_clients *clients);
+unsigned int i915_drm_priority_levels(struct drm_file *file);
+
#endif /* !__I915_DRM_CLIENT_H__ */