All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matt Roper <matthew.d.roper@intel.com>
To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org,
	cgroups@vger.kernel.org
Subject: [PATCH v3 4/6] drm/i915: cgroup integration (v2)
Date: Tue,  6 Mar 2018 15:46:58 -0800	[thread overview]
Message-ID: <20180306234700.6562-5-matthew.d.roper@intel.com> (raw)
In-Reply-To: <20180306234700.6562-1-matthew.d.roper@intel.com>

Introduce a new DRM_IOCTL_I915_CGROUP_SETPARAM ioctl that will allow
userspace to set i915-specific parameters for individual cgroups.  i915
cgroup data will be registered and later looked up via the new
cgroup_priv infrastructure.

v2:
 - Large rebase/rewrite for new cgroup_priv interface

Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/Makefile      |   1 +
 drivers/gpu/drm/i915/i915_cgroup.c | 167 +++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_drv.c    |   5 ++
 drivers/gpu/drm/i915/i915_drv.h    |  24 ++++++
 include/uapi/drm/i915_drm.h        |  12 +++
 5 files changed, 209 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/i915_cgroup.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 1bd9bc5b8c5c..5974e32834bf 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -48,6 +48,7 @@ i915-y := i915_drv.o \
 i915-$(CONFIG_COMPAT)   += i915_ioc32.o
 i915-$(CONFIG_DEBUG_FS) += i915_debugfs.o intel_pipe_crc.o
 i915-$(CONFIG_PERF_EVENTS) += i915_pmu.o
+i915-$(CONFIG_CGROUPS) += i915_cgroup.o
 
 # GEM code
 i915-y += i915_cmd_parser.o \
diff --git a/drivers/gpu/drm/i915/i915_cgroup.c b/drivers/gpu/drm/i915/i915_cgroup.c
new file mode 100644
index 000000000000..4a46cb167f53
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_cgroup.c
@@ -0,0 +1,167 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * i915_cgroup.c - Linux cgroups integration for i915
+ *
+ * Copyright (C) 2018 Intel Corporation
+ */
+
+#include <linux/cgroup.h>
+
+#include "i915_drv.h"
+
+struct i915_cgroup_data {
+	struct cgroup_priv base;
+
+	struct list_head node;
+};
+
+static inline struct i915_cgroup_data *
+cgrp_to_i915(struct cgroup_priv *priv)
+{
+	return container_of(priv, struct i915_cgroup_data, base);
+}
+
+static void
+i915_cgroup_free(struct cgroup_priv *priv)
+{
+	struct cgroup *cgrp = priv->cgroup;
+	struct i915_cgroup_data *ipriv;
+
+	WARN_ON(!mutex_is_locked(&cgrp->privdata_mutex));
+
+	ipriv = cgrp_to_i915(priv);
+
+	/*
+	 * Remove private data from both cgroup's hashtable and i915's list.
+	 * If this function is being called as a result of cgroup removal
+	 * (as opposed to an i915 unload), it will have already been removed from
+	 * the hashtable, but the hash_del() call here is still safe.
+	 */
+	hash_del(&priv->hnode);
+	list_del(&ipriv->node);
+
+	kfree(ipriv);
+}
+
+void
+i915_cgroup_init(struct drm_i915_private *dev_priv)
+{
+	INIT_LIST_HEAD(&dev_priv->cgroup_list);
+}
+
+void
+i915_cgroup_shutdown(struct drm_i915_private *dev_priv)
+{
+	struct i915_cgroup_data *priv, *tmp;
+	struct cgroup *cgrp;
+
+	mutex_lock(&cgroup_mutex);
+
+	list_for_each_entry_safe(priv, tmp, &dev_priv->cgroup_list, node) {
+		cgrp = priv->base.cgroup;
+
+		mutex_lock(&cgrp->privdata_mutex);
+		i915_cgroup_free(&priv->base);
+		mutex_unlock(&cgrp->privdata_mutex);
+	}
+
+	mutex_unlock(&cgroup_mutex);
+}
+
+/*
+ * Return i915 cgroup private data, creating and registering it if one doesn't
+ * already exist for this cgroup.
+ */
+static struct i915_cgroup_data *
+get_or_create_cgroup_data(struct drm_i915_private *dev_priv,
+			  struct cgroup *cgrp)
+{
+	struct cgroup_priv *priv;
+	struct i915_cgroup_data *ipriv;
+
+	mutex_lock(&cgrp->privdata_mutex);
+
+	priv = cgroup_priv_lookup(cgrp, dev_priv);
+	if (priv) {
+		ipriv = cgrp_to_i915(priv);
+	} else {
+		ipriv = kzalloc(sizeof *ipriv, GFP_KERNEL);
+		if (!ipriv) {
+			ipriv = ERR_PTR(-ENOMEM);
+			goto out;
+		}
+
+		ipriv->base.key = dev_priv;
+		ipriv->base.free = i915_cgroup_free;
+		list_add(&ipriv->node, &dev_priv->cgroup_list);
+
+		cgroup_priv_install(cgrp, &ipriv->base);
+	}
+
+out:
+	mutex_unlock(&cgrp->privdata_mutex);
+
+	return ipriv;
+}
+
+/**
+ * i915_cgroup_setparam_ioctl - ioctl to alter i915 settings for a cgroup
+ * @dev: DRM device
+ * @data: data pointer for the ioctl
+ * @file_priv: DRM file handle for the ioctl call
+ *
+ * Allows i915-specific parameters to be set for a Linux cgroup.
+ */
+int
+i915_cgroup_setparam_ioctl(struct drm_device *dev,
+			   void *data,
+			   struct drm_file *file)
+{
+	struct drm_i915_cgroup_param *req = data;
+	struct cgroup *cgrp;
+	int ret;
+
+	/* We don't actually support any flags yet. */
+	if (req->flags) {
+		DRM_DEBUG_DRIVER("Invalid flags\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * Make sure the file descriptor really is a cgroup fd and is on the
+	 * v2 hierarchy.
+	 */
+	cgrp = cgroup_get_from_fd(req->cgroup_fd);
+	if (IS_ERR(cgrp)) {
+		DRM_DEBUG_DRIVER("Invalid cgroup file descriptor\n");
+		return PTR_ERR(cgrp);
+	}
+
+	/*
+	 * Access control:  The strategy for using cgroups in a given
+	 * environment is generally determined by the system integrator
+	 * and/or OS vendor, so the specific policy about who can/can't
+	 * manipulate them tends to be domain-specific (and may vary
+	 * depending on the location in the cgroup hierarchy).  Rather than
+	 * trying to tie permission on this ioctl to a DRM-specific concepts
+	 * like DRM master, we'll allow cgroup parameters to be set by any
+	 * process that has been granted write access on the cgroup's
+	 * virtual file system (i.e., the same permissions that would
+	 * generally be needed to update the virtual files provided by
+	 * cgroup controllers).
+	 */
+	ret = cgroup_permission(req->cgroup_fd, MAY_WRITE);
+	if (ret)
+		goto out;
+
+	switch (req->param) {
+	default:
+		DRM_DEBUG_DRIVER("Invalid cgroup parameter %lld\n", req->param);
+		ret = -EINVAL;
+	}
+
+out:
+	cgroup_put(cgrp);
+
+	return ret;
+}
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index d61b51c0bf0b..a1c7bc9cd173 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1405,6 +1405,8 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	intel_runtime_pm_put(dev_priv);
 
+	i915_cgroup_init(dev_priv);
+
 	i915_welcome_messages(dev_priv);
 
 	return 0;
@@ -1431,6 +1433,8 @@ void i915_driver_unload(struct drm_device *dev)
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct pci_dev *pdev = dev_priv->drm.pdev;
 
+	i915_cgroup_shutdown(dev_priv);
+
 	i915_driver_unregister(dev_priv);
 
 	if (i915_gem_suspend(dev_priv))
@@ -2832,6 +2836,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
 	DRM_IOCTL_DEF_DRV(I915_PERF_OPEN, i915_perf_open_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_PERF_ADD_CONFIG, i915_perf_add_config_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_PERF_REMOVE_CONFIG, i915_perf_remove_config_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_CGROUP_SETPARAM, i915_cgroup_setparam_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
 };
 
 static struct drm_driver driver = {
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 7eec99d7fad4..7c38142ee009 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2006,6 +2006,9 @@ struct drm_i915_private {
 
 	struct intel_ppat ppat;
 
+	/* cgroup private data */
+	struct list_head cgroup_list;
+
 	/* Kernel Modesetting */
 
 	struct intel_crtc *plane_to_crtc_mapping[I915_MAX_PIPES];
@@ -2938,6 +2941,27 @@ intel_ggtt_update_needs_vtd_wa(struct drm_i915_private *dev_priv)
 int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv,
 				int enable_ppgtt);
 
+/* i915_cgroup.c */
+#ifdef CONFIG_CGROUPS
+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);
+#else
+static inline int
+i915_cgroup_init(struct drm_i915_private *dev_priv)
+{
+	return 0;
+}
+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 -EINVAL;
+}
+#endif
+
 /* i915_drv.c */
 void __printf(3, 4)
 __i915_printk(struct drm_i915_private *dev_priv, const char *level,
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 29fa48e4755d..b6651b263838 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -318,6 +318,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_I915_PERF_OPEN		0x36
 #define DRM_I915_PERF_ADD_CONFIG	0x37
 #define DRM_I915_PERF_REMOVE_CONFIG	0x38
+#define DRM_I915_CGROUP_SETPARAM	0x39
 
 #define DRM_IOCTL_I915_INIT		DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
 #define DRM_IOCTL_I915_FLUSH		DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -375,6 +376,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_IOCTL_I915_PERF_OPEN	DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_OPEN, struct drm_i915_perf_open_param)
 #define DRM_IOCTL_I915_PERF_ADD_CONFIG	DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_ADD_CONFIG, struct drm_i915_perf_oa_config)
 #define DRM_IOCTL_I915_PERF_REMOVE_CONFIG	DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_REMOVE_CONFIG, __u64)
+#define DRM_IOCTL_I915_CGROUP_SETPARAM		DRM_IOW(DRM_COMMAND_BASE + DRM_I915_CGROUP_SETPARAM, struct drm_i915_cgroup_param)
 
 /* Allow drivers to submit batchbuffers directly to hardware, relying
  * on the security mechanisms provided by hardware.
@@ -1615,6 +1617,16 @@ struct drm_i915_perf_oa_config {
 	__u64 flex_regs_ptr;
 };
 
+/**
+ * Structure to set i915 parameter on a cgroup.
+ */
+struct drm_i915_cgroup_param {
+	__s32 cgroup_fd;
+	__u32 flags;
+	__u64 param;
+	__s64 value;
+};
+
 #if defined(__cplusplus)
 }
 #endif
-- 
2.14.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  parent reply	other threads:[~2018-03-06 23:46 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-06 23:46 [PATCH v3 0/6] DRM/i915 cgroup integration Matt Roper
2018-03-06 23:46 ` [PATCH v3 1/6] cgroup: Allow registration and lookup of cgroup private data Matt Roper
2018-03-13 20:50   ` Tejun Heo
2018-03-13 21:27     ` Alexei Starovoitov
2018-03-13 21:37       ` Roman Gushchin
2018-03-13 21:47         ` Alexei Starovoitov
2018-03-13 22:09           ` Roman Gushchin
2018-03-13 22:13           ` Tejun Heo
2018-03-13 22:42             ` Alexei Starovoitov
2018-03-13 22:52               ` Roman Gushchin
2018-03-06 23:46 ` [PATCH v3 2/6] cgroup: Introduce task_get_dfl_cgroup() Matt Roper
2018-03-13 20:41   ` Tejun Heo
2018-03-06 23:46 ` [PATCH v3 3/6] cgroup: Introduce cgroup_permission() Matt Roper
2018-03-13 20:43   ` Tejun Heo
2018-03-06 23:46 ` Matt Roper [this message]
2018-03-06 23:46 ` [PATCH v3 5/6] drm/i915: Introduce 'priority offset' for GPU contexts (v2) Matt Roper
2018-03-08 11:32   ` Chris Wilson
2018-03-08 13:11     ` Chris Wilson
2018-03-08 18:22       ` Matt Roper
2018-03-08 18:48         ` Chris Wilson
2018-03-08 18:55           ` Chris Wilson
2018-03-08 19:31             ` Matt Roper
2018-03-06 23:47 ` [PATCH v3 6/6] drm/i915: Add context priority & priority offset to debugfs (v2) Matt Roper
2018-03-06 23:49 ` [PATCH i-g-t 1/2] tools: Introduce intel_cgroup tool Matt Roper
2018-03-06 23:49   ` [PATCH i-g-t 2/2] tests: Introduce drv_cgroup Matt Roper
2018-03-06 23:59 ` ✗ Fi.CI.SPARSE: warning for DRM/i915 cgroup integration Patchwork
2018-03-07  0:14 ` ✓ Fi.CI.BAT: success " Patchwork
2018-03-07  5:16 ` ✗ Fi.CI.IGT: failure " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180306234700.6562-5-matthew.d.roper@intel.com \
    --to=matthew.d.roper@intel.com \
    --cc=cgroups@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.