From: Tvrtko Ursulin <tursulin@ursulin.net>
To: Intel-gfx@lists.freedesktop.org
Subject: [RFC 14/17] drm/i915: Expose list of clients in sysfs
Date: Wed, 25 Oct 2017 16:36:29 +0100 [thread overview]
Message-ID: <20171025153632.557-15-tvrtko.ursulin@linux.intel.com> (raw)
In-Reply-To: <20171025153632.557-1-tvrtko.ursulin@linux.intel.com>
From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Expose a list of clients with open file handles in sysfs.
This will be a basis for a top-like utility showing per-client and per-
engine GPU load.
Currently we only expose each client's pid and name under opaque numbered
directories in /sys/class/drm/card0/clients/.
For instance:
/sys/class/drm/card0/clients/3/name: Xorg
/sys/class/drm/card0/clients/3/pid: 5664
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 13 +++++
drivers/gpu/drm/i915/i915_gem.c | 112 +++++++++++++++++++++++++++++++++++---
drivers/gpu/drm/i915/i915_sysfs.c | 8 +++
3 files changed, 126 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1534b05d1ad6..8117a8056a71 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -622,6 +622,16 @@ struct drm_i915_file_private {
*/
#define I915_MAX_CLIENT_CONTEXT_BANS 3
atomic_t context_bans;
+
+ unsigned int client_sysfs_id;
+ unsigned int client_pid;
+ char *client_name;
+ struct kobject *client_root;
+
+ struct {
+ struct device_attribute pid;
+ struct device_attribute name;
+ } attr;
};
/* Used by dp and fdi links */
@@ -2756,6 +2766,9 @@ struct drm_i915_private {
struct i915_pmu pmu;
+ struct kobject *clients_root;
+ atomic_t client_serial;
+
/*
* NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
* will be rejected. Instead look for a better place.
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 08bbceaeb9b8..c73a10a58be1 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -5233,6 +5233,89 @@ int i915_gem_freeze_late(struct drm_i915_private *dev_priv)
return 0;
}
+static ssize_t
+show_client_name(struct device *kdev, struct device_attribute *attr, char *buf)
+{
+ struct drm_i915_file_private *file_priv =
+ container_of(attr, struct drm_i915_file_private, attr.name);
+
+ return snprintf(buf, PAGE_SIZE, "%s", file_priv->client_name);
+}
+
+static ssize_t
+show_client_pid(struct device *kdev, struct device_attribute *attr, char *buf)
+{
+ struct drm_i915_file_private *file_priv =
+ container_of(attr, struct drm_i915_file_private, attr.pid);
+
+ return snprintf(buf, PAGE_SIZE, "%u", file_priv->client_pid);
+}
+
+static int
+i915_gem_add_client(struct drm_i915_private *i915,
+ struct drm_i915_file_private *file_priv,
+ struct task_struct *task,
+ unsigned int serial)
+{
+ int ret = -ENOMEM;
+ struct device_attribute *attr;
+ char id[32];
+
+ file_priv->client_name = kstrdup(task->comm, GFP_KERNEL);
+ if (!file_priv->client_name)
+ goto err_name;
+
+ snprintf(id, sizeof(id), "%u", serial);
+ file_priv->client_root = kobject_create_and_add(id,
+ i915->clients_root);
+ if (!file_priv->client_root)
+ goto err_client;
+
+ attr = &file_priv->attr.name;
+ attr->attr.name = "name";
+ attr->attr.mode = 0444;
+ attr->show = show_client_name;
+
+ ret = sysfs_create_file(file_priv->client_root,
+ (struct attribute *)attr);
+ if (ret)
+ goto err_attr_name;
+
+ attr = &file_priv->attr.pid;
+ attr->attr.name = "pid";
+ attr->attr.mode = 0444;
+ attr->show = show_client_pid;
+
+ ret = sysfs_create_file(file_priv->client_root,
+ (struct attribute *)attr);
+ if (ret)
+ goto err_attr_pid;
+
+ file_priv->client_pid = pid_nr(get_task_pid(task, PIDTYPE_PID));
+
+ return 0;
+
+err_attr_pid:
+ sysfs_remove_file(file_priv->client_root,
+ (struct attribute *)&file_priv->attr.name);
+err_attr_name:
+ kobject_put(file_priv->client_root);
+err_client:
+ kfree(file_priv->client_name);
+err_name:
+ return ret;
+}
+
+static void i915_gem_remove_client(struct drm_i915_file_private *file_priv)
+{
+ sysfs_remove_file(file_priv->client_root,
+ (struct attribute *)&file_priv->attr.pid);
+ sysfs_remove_file(file_priv->client_root,
+ (struct attribute *)&file_priv->attr.name);
+ kobject_put(file_priv->client_root);
+ kfree(file_priv->client_name);
+}
+
void i915_gem_release(struct drm_device *dev, struct drm_file *file)
{
struct drm_i915_file_private *file_priv = file->driver_priv;
@@ -5246,32 +5329,47 @@ void i915_gem_release(struct drm_device *dev, struct drm_file *file)
list_for_each_entry(request, &file_priv->mm.request_list, client_link)
request->file_priv = NULL;
spin_unlock(&file_priv->mm.lock);
+
+ i915_gem_remove_client(file_priv);
}
int i915_gem_open(struct drm_i915_private *i915, struct drm_file *file)
{
+ int ret = -ENOMEM;
struct drm_i915_file_private *file_priv;
- int ret;
DRM_DEBUG("\n");
file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
if (!file_priv)
- return -ENOMEM;
+ goto err_alloc;
+
+ file_priv->client_sysfs_id = atomic_inc_return(&i915->client_serial);
+ ret = i915_gem_add_client(i915, file_priv, current,
+ file_priv->client_sysfs_id);
+ if (ret)
+ goto err_client;
file->driver_priv = file_priv;
+ ret = i915_gem_context_open(i915, file);
+ if (ret)
+ goto err_context;
+
file_priv->dev_priv = i915;
file_priv->file = file;
+ file_priv->bsd_engine = -1;
spin_lock_init(&file_priv->mm.lock);
INIT_LIST_HEAD(&file_priv->mm.request_list);
- file_priv->bsd_engine = -1;
-
- ret = i915_gem_context_open(i915, file);
- if (ret)
- kfree(file_priv);
+ return 0;
+err_context:
+ i915_gem_remove_client(file_priv);
+err_client:
+ atomic_dec(&i915->client_serial);
+ kfree(file_priv);
+err_alloc:
return ret;
}
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index c290cb600eea..05617e0665bf 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -564,6 +564,11 @@ void i915_setup_sysfs(struct drm_i915_private *dev_priv)
struct device *kdev = dev_priv->drm.primary->kdev;
int ret;
+ dev_priv->clients_root =
+ kobject_create_and_add("clients", &kdev->kobj);
+ if (!dev_priv->clients_root)
+ DRM_ERROR("Per-client sysfs setup failed\n");
+
#ifdef CONFIG_PM
if (HAS_RC6(dev_priv)) {
ret = sysfs_merge_group(&kdev->kobj,
@@ -624,4 +629,7 @@ void i915_teardown_sysfs(struct drm_i915_private *dev_priv)
sysfs_unmerge_group(&kdev->kobj, &rc6_attr_group);
sysfs_unmerge_group(&kdev->kobj, &rc6p_attr_group);
#endif
+
+ if (dev_priv->clients_root)
+ kobject_put(dev_priv->clients_root);
}
--
2.9.5
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2017-10-25 15:36 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-10-25 15:36 [RFC 00/17] Per-context and per-client engine busyness Tvrtko Ursulin
2017-10-25 15:36 ` [RFC 01/17] drm/i915: Extract intel_get_cagf Tvrtko Ursulin
2017-10-25 15:36 ` [RFC 02/17] drm/i915/pmu: Expose a PMU interface for perf queries Tvrtko Ursulin
2017-10-25 15:36 ` [RFC 03/17] drm/i915/pmu: Suspend sampling when GPU is idle Tvrtko Ursulin
2017-10-25 15:36 ` [RFC 04/17] drm/i915: Wrap context schedule notification Tvrtko Ursulin
2017-10-25 15:36 ` [RFC 05/17] drm/i915: Engine busy time tracking Tvrtko Ursulin
2017-10-25 15:36 ` [RFC 06/17] drm/i915/pmu: Wire up engine busy stats to PMU Tvrtko Ursulin
2017-10-25 15:36 ` [RFC 07/17] drm/i915/pmu: Add interrupt count metric Tvrtko Ursulin
2017-10-25 15:36 ` [RFC 08/17] drm/i915: Convert intel_rc6_residency_us to ns Tvrtko Ursulin
2017-10-25 15:36 ` [RFC 09/17] drm/i915/pmu: Add RC6 residency metrics Tvrtko Ursulin
2017-10-25 15:36 ` [RFC 10/17] drm/i915: Keep a count of requests waiting for a slot on GPU Tvrtko Ursulin
2017-10-25 15:36 ` [RFC 11/17] drm/i915/pmu: Add queued counter Tvrtko Ursulin
2017-10-25 15:36 ` [RFC 12/17] drm/i915: Track per-context engine busyness Tvrtko Ursulin
2017-10-25 15:36 ` [RFC 13/17] drm/i915: Allow clients to query own per-engine busyness Tvrtko Ursulin
2017-10-25 15:36 ` Tvrtko Ursulin [this message]
2017-10-25 15:36 ` [RFC 15/17] drm/i915: Update client name on context create Tvrtko Ursulin
2017-10-25 15:36 ` [RFC 16/17] drm/i915: Expose per-engine client busyness Tvrtko Ursulin
2017-10-25 15:36 ` [RFC 17/17] drm/i915: Add sysfs toggle to enable per-client engine stats Tvrtko Ursulin
2017-10-25 15:47 ` [RFC 00/17] Per-context and per-client engine busyness Chris Wilson
2017-10-25 17:38 ` Chris Wilson
2017-10-26 7:34 ` Tvrtko Ursulin
2017-10-26 7:51 ` Chris Wilson
2017-10-26 9:50 ` Lionel Landwerlin
2017-10-26 10:10 ` Chris Wilson
2017-10-26 13:00 ` Tvrtko Ursulin
2017-10-26 13:05 ` Chris Wilson
2017-10-26 17:13 ` Lionel Landwerlin
2017-10-26 20:11 ` Chris Wilson
2017-10-27 0:12 ` Lionel Landwerlin
2017-10-25 17:06 ` ✗ Fi.CI.BAT: failure for " 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=20171025153632.557-15-tvrtko.ursulin@linux.intel.com \
--to=tursulin@ursulin.net \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox