From: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> To: Intel-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Subject: [PATCH 7/7] drm/i915: Expose per-engine client busyness Date: Thu, 13 May 2021 12:00:02 +0100 [thread overview] Message-ID: <20210513110002.3641705-8-tvrtko.ursulin@linux.intel.com> (raw) In-Reply-To: <20210513110002.3641705-1-tvrtko.ursulin@linux.intel.com> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Expose per-client and per-engine busyness under the previously added sysfs client root. The new files are one per-engine instance and located under the 'busy' directory. Each contains a monotonically increasing nano-second resolution times each client's jobs were executing on the GPU. This enables userspace to create a top-like tool for GPU utilization: ========================================================================== intel-gpu-top - 935/ 935 MHz; 0% RC6; 14.73 Watts; 1097 irqs/s IMC reads: 1401 MiB/s IMC writes: 4 MiB/s ENGINE BUSY MI_SEMA MI_WAIT Render/3D/0 63.73% |███████████████████ | 3% 0% Blitter/0 9.53% |██▊ | 6% 0% Video/0 39.32% |███████████▊ | 16% 0% Video/1 15.62% |████▋ | 0% 0% VideoEnhance/0 0.00% | | 0% 0% PID NAME RCS BCS VCS VECS 4084 gem_wsim |█████▌ ||█ || || | 4086 gem_wsim |█▌ || ||███ || | ========================================================================== v2: Use intel_context_engine_get_busy_time. v3: New directory structure. v4: Rebase. v5: sysfs_attr_init. v6: Small tidy in i915_gem_add_client. v7: Rebase to be engine class based. v8: * Always enable stats. * Walk all client contexts. v9: * Skip unsupported engine classes. (Chris) * Use scheduler caps. (Chris) v10: * Use pphwsp runtime only. Link: https://patchwork.freedesktop.org/series/71182/ # intel_gpu_top Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Reviewed-by: Aravind Iddamsetty <aravind.iddamsetty@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Link: https://patchwork.freedesktop.org/patch/msgid/20210123153733.18139-8-chris@chris-wilson.co.uk Link: https://patchwork.freedesktop.org/patch/msgid/20210124153136.19124-8-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drm_client.c | 101 ++++++++++++++++++++++++- drivers/gpu/drm/i915/i915_drm_client.h | 10 +++ 2 files changed, 110 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drm_client.c b/drivers/gpu/drm/i915/i915_drm_client.c index 0ca81a750895..1f8b08a413d4 100644 --- a/drivers/gpu/drm/i915/i915_drm_client.c +++ b/drivers/gpu/drm/i915/i915_drm_client.c @@ -9,6 +9,11 @@ #include <drm/drm_print.h> +#include <uapi/drm/i915_drm.h> + +#include "gem/i915_gem_context.h" +#include "gt/intel_engine_user.h" + #include "i915_drm_client.h" #include "i915_drv.h" #include "i915_gem.h" @@ -55,6 +60,95 @@ show_client_pid(struct device *kdev, struct device_attribute *attr, char *buf) return ret; } +static u64 busy_add(struct i915_gem_context *ctx, unsigned int class) +{ + struct i915_gem_engines_iter it; + struct intel_context *ce; + u64 total = 0; + + for_each_gem_engine(ce, rcu_dereference(ctx->engines), it) { + if (ce->engine->uabi_class != class) + continue; + + total += intel_context_get_total_runtime_ns(ce); + } + + return total; +} + +static ssize_t +show_busy(struct device *kdev, struct device_attribute *attr, char *buf) +{ + struct i915_engine_busy_attribute *i915_attr = + container_of(attr, typeof(*i915_attr), attr); + unsigned int class = i915_attr->engine_class; + const struct i915_drm_client *client = i915_attr->client; + const struct list_head *list = &client->ctx_list; + u64 total = atomic64_read(&client->past_runtime[class]); + struct i915_gem_context *ctx; + + rcu_read_lock(); + list_for_each_entry_rcu(ctx, list, client_link) + total += busy_add(ctx, class); + rcu_read_unlock(); + + return sysfs_emit(buf, "%llu\n", total); +} + +static const char * const uabi_class_names[] = { + [I915_ENGINE_CLASS_RENDER] = "0", + [I915_ENGINE_CLASS_COPY] = "1", + [I915_ENGINE_CLASS_VIDEO] = "2", + [I915_ENGINE_CLASS_VIDEO_ENHANCE] = "3", +}; + +static int __client_register_sysfs_busy(struct i915_drm_client *client) +{ + struct i915_drm_clients *clients = client->clients; + unsigned int i; + int ret = 0; + + if (!(clients->i915->caps.scheduler & I915_SCHEDULER_CAP_ENGINE_BUSY_STATS)) + return 0; + + client->busy_root = kobject_create_and_add("busy", client->root); + if (!client->busy_root) + return -ENOMEM; + + for (i = 0; i < ARRAY_SIZE(uabi_class_names); i++) { + struct i915_engine_busy_attribute *i915_attr = + &client->attr.busy[i]; + struct device_attribute *attr = &i915_attr->attr; + + if (!intel_engine_lookup_user(clients->i915, i, 0)) + continue; + + i915_attr->client = client; + i915_attr->engine_class = i; + + sysfs_attr_init(&attr->attr); + + attr->attr.name = uabi_class_names[i]; + attr->attr.mode = 0444; + attr->show = show_busy; + + ret = sysfs_create_file(client->busy_root, &attr->attr); + if (ret) + goto out; + } + +out: + if (ret) + kobject_put(client->busy_root); + + return ret; +} + +static void __client_unregister_sysfs_busy(struct i915_drm_client *client) +{ + kobject_put(fetch_and_zero(&client->busy_root)); +} + static int __client_register_sysfs(struct i915_drm_client *client) { const struct { @@ -90,9 +184,12 @@ static int __client_register_sysfs(struct i915_drm_client *client) ret = sysfs_create_file(client->root, &attr->attr); if (ret) - break; + goto out; } + ret = __client_register_sysfs_busy(client); + +out: if (ret) kobject_put(client->root); @@ -101,6 +198,8 @@ static int __client_register_sysfs(struct i915_drm_client *client) static void __client_unregister_sysfs(struct i915_drm_client *client) { + __client_unregister_sysfs_busy(client); + kobject_put(fetch_and_zero(&client->root)); } diff --git a/drivers/gpu/drm/i915/i915_drm_client.h b/drivers/gpu/drm/i915/i915_drm_client.h index 13f92142e474..83660fa9d2d7 100644 --- a/drivers/gpu/drm/i915/i915_drm_client.h +++ b/drivers/gpu/drm/i915/i915_drm_client.h @@ -30,6 +30,14 @@ struct i915_drm_clients { struct kobject *root; }; +struct i915_drm_client; + +struct i915_engine_busy_attribute { + struct device_attribute attr; + struct i915_drm_client *client; + unsigned int engine_class; +}; + struct i915_drm_client_name { struct rcu_head rcu; struct i915_drm_client *client; @@ -54,9 +62,11 @@ struct i915_drm_client { struct i915_drm_clients *clients; struct kobject *root; + struct kobject *busy_root; struct { struct device_attribute pid; struct device_attribute name; + struct i915_engine_busy_attribute busy[MAX_ENGINE_CLASS + 1]; } attr; /** -- 2.30.2
WARNING: multiple messages have this Message-ID (diff)
From: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> To: Intel-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Subject: [Intel-gfx] [PATCH 7/7] drm/i915: Expose per-engine client busyness Date: Thu, 13 May 2021 12:00:02 +0100 [thread overview] Message-ID: <20210513110002.3641705-8-tvrtko.ursulin@linux.intel.com> (raw) In-Reply-To: <20210513110002.3641705-1-tvrtko.ursulin@linux.intel.com> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Expose per-client and per-engine busyness under the previously added sysfs client root. The new files are one per-engine instance and located under the 'busy' directory. Each contains a monotonically increasing nano-second resolution times each client's jobs were executing on the GPU. This enables userspace to create a top-like tool for GPU utilization: ========================================================================== intel-gpu-top - 935/ 935 MHz; 0% RC6; 14.73 Watts; 1097 irqs/s IMC reads: 1401 MiB/s IMC writes: 4 MiB/s ENGINE BUSY MI_SEMA MI_WAIT Render/3D/0 63.73% |███████████████████ | 3% 0% Blitter/0 9.53% |██▊ | 6% 0% Video/0 39.32% |███████████▊ | 16% 0% Video/1 15.62% |████▋ | 0% 0% VideoEnhance/0 0.00% | | 0% 0% PID NAME RCS BCS VCS VECS 4084 gem_wsim |█████▌ ||█ || || | 4086 gem_wsim |█▌ || ||███ || | ========================================================================== v2: Use intel_context_engine_get_busy_time. v3: New directory structure. v4: Rebase. v5: sysfs_attr_init. v6: Small tidy in i915_gem_add_client. v7: Rebase to be engine class based. v8: * Always enable stats. * Walk all client contexts. v9: * Skip unsupported engine classes. (Chris) * Use scheduler caps. (Chris) v10: * Use pphwsp runtime only. Link: https://patchwork.freedesktop.org/series/71182/ # intel_gpu_top Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Reviewed-by: Aravind Iddamsetty <aravind.iddamsetty@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Link: https://patchwork.freedesktop.org/patch/msgid/20210123153733.18139-8-chris@chris-wilson.co.uk Link: https://patchwork.freedesktop.org/patch/msgid/20210124153136.19124-8-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drm_client.c | 101 ++++++++++++++++++++++++- drivers/gpu/drm/i915/i915_drm_client.h | 10 +++ 2 files changed, 110 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drm_client.c b/drivers/gpu/drm/i915/i915_drm_client.c index 0ca81a750895..1f8b08a413d4 100644 --- a/drivers/gpu/drm/i915/i915_drm_client.c +++ b/drivers/gpu/drm/i915/i915_drm_client.c @@ -9,6 +9,11 @@ #include <drm/drm_print.h> +#include <uapi/drm/i915_drm.h> + +#include "gem/i915_gem_context.h" +#include "gt/intel_engine_user.h" + #include "i915_drm_client.h" #include "i915_drv.h" #include "i915_gem.h" @@ -55,6 +60,95 @@ show_client_pid(struct device *kdev, struct device_attribute *attr, char *buf) return ret; } +static u64 busy_add(struct i915_gem_context *ctx, unsigned int class) +{ + struct i915_gem_engines_iter it; + struct intel_context *ce; + u64 total = 0; + + for_each_gem_engine(ce, rcu_dereference(ctx->engines), it) { + if (ce->engine->uabi_class != class) + continue; + + total += intel_context_get_total_runtime_ns(ce); + } + + return total; +} + +static ssize_t +show_busy(struct device *kdev, struct device_attribute *attr, char *buf) +{ + struct i915_engine_busy_attribute *i915_attr = + container_of(attr, typeof(*i915_attr), attr); + unsigned int class = i915_attr->engine_class; + const struct i915_drm_client *client = i915_attr->client; + const struct list_head *list = &client->ctx_list; + u64 total = atomic64_read(&client->past_runtime[class]); + struct i915_gem_context *ctx; + + rcu_read_lock(); + list_for_each_entry_rcu(ctx, list, client_link) + total += busy_add(ctx, class); + rcu_read_unlock(); + + return sysfs_emit(buf, "%llu\n", total); +} + +static const char * const uabi_class_names[] = { + [I915_ENGINE_CLASS_RENDER] = "0", + [I915_ENGINE_CLASS_COPY] = "1", + [I915_ENGINE_CLASS_VIDEO] = "2", + [I915_ENGINE_CLASS_VIDEO_ENHANCE] = "3", +}; + +static int __client_register_sysfs_busy(struct i915_drm_client *client) +{ + struct i915_drm_clients *clients = client->clients; + unsigned int i; + int ret = 0; + + if (!(clients->i915->caps.scheduler & I915_SCHEDULER_CAP_ENGINE_BUSY_STATS)) + return 0; + + client->busy_root = kobject_create_and_add("busy", client->root); + if (!client->busy_root) + return -ENOMEM; + + for (i = 0; i < ARRAY_SIZE(uabi_class_names); i++) { + struct i915_engine_busy_attribute *i915_attr = + &client->attr.busy[i]; + struct device_attribute *attr = &i915_attr->attr; + + if (!intel_engine_lookup_user(clients->i915, i, 0)) + continue; + + i915_attr->client = client; + i915_attr->engine_class = i; + + sysfs_attr_init(&attr->attr); + + attr->attr.name = uabi_class_names[i]; + attr->attr.mode = 0444; + attr->show = show_busy; + + ret = sysfs_create_file(client->busy_root, &attr->attr); + if (ret) + goto out; + } + +out: + if (ret) + kobject_put(client->busy_root); + + return ret; +} + +static void __client_unregister_sysfs_busy(struct i915_drm_client *client) +{ + kobject_put(fetch_and_zero(&client->busy_root)); +} + static int __client_register_sysfs(struct i915_drm_client *client) { const struct { @@ -90,9 +184,12 @@ static int __client_register_sysfs(struct i915_drm_client *client) ret = sysfs_create_file(client->root, &attr->attr); if (ret) - break; + goto out; } + ret = __client_register_sysfs_busy(client); + +out: if (ret) kobject_put(client->root); @@ -101,6 +198,8 @@ static int __client_register_sysfs(struct i915_drm_client *client) static void __client_unregister_sysfs(struct i915_drm_client *client) { + __client_unregister_sysfs_busy(client); + kobject_put(fetch_and_zero(&client->root)); } diff --git a/drivers/gpu/drm/i915/i915_drm_client.h b/drivers/gpu/drm/i915/i915_drm_client.h index 13f92142e474..83660fa9d2d7 100644 --- a/drivers/gpu/drm/i915/i915_drm_client.h +++ b/drivers/gpu/drm/i915/i915_drm_client.h @@ -30,6 +30,14 @@ struct i915_drm_clients { struct kobject *root; }; +struct i915_drm_client; + +struct i915_engine_busy_attribute { + struct device_attribute attr; + struct i915_drm_client *client; + unsigned int engine_class; +}; + struct i915_drm_client_name { struct rcu_head rcu; struct i915_drm_client *client; @@ -54,9 +62,11 @@ struct i915_drm_client { struct i915_drm_clients *clients; struct kobject *root; + struct kobject *busy_root; struct { struct device_attribute pid; struct device_attribute name; + struct i915_engine_busy_attribute busy[MAX_ENGINE_CLASS + 1]; } attr; /** -- 2.30.2 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2021-05-13 11:00 UTC|newest] Thread overview: 103+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-05-13 10:59 [PATCH 0/7] Per client engine busyness Tvrtko Ursulin 2021-05-13 10:59 ` [Intel-gfx] " Tvrtko Ursulin 2021-05-13 10:59 ` [PATCH 1/7] drm/i915: Expose list of clients in sysfs Tvrtko Ursulin 2021-05-13 10:59 ` [Intel-gfx] " Tvrtko Ursulin 2021-05-13 10:59 ` [PATCH 2/7] drm/i915: Update client name on context create Tvrtko Ursulin 2021-05-13 10:59 ` [Intel-gfx] " Tvrtko Ursulin 2021-05-13 10:59 ` [PATCH 3/7] drm/i915: Make GEM contexts track DRM clients Tvrtko Ursulin 2021-05-13 10:59 ` [Intel-gfx] " Tvrtko Ursulin 2021-05-13 10:59 ` [PATCH 4/7] drm/i915: Track runtime spent in closed and unreachable GEM contexts Tvrtko Ursulin 2021-05-13 10:59 ` [Intel-gfx] " Tvrtko Ursulin 2021-05-13 11:00 ` [PATCH 5/7] drm/i915: Track all user contexts per client Tvrtko Ursulin 2021-05-13 11:00 ` [Intel-gfx] " Tvrtko Ursulin 2021-05-13 11:00 ` [PATCH 6/7] drm/i915: Track context current active time Tvrtko Ursulin 2021-05-13 11:00 ` [Intel-gfx] " Tvrtko Ursulin 2021-05-13 11:00 ` Tvrtko Ursulin [this message] 2021-05-13 11:00 ` [Intel-gfx] [PATCH 7/7] drm/i915: Expose per-engine client busyness Tvrtko Ursulin 2021-05-13 11:28 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for Per client engine busyness Patchwork 2021-05-13 11:30 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork 2021-05-13 11:59 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork 2021-05-13 15:48 ` [PATCH 0/7] " Alex Deucher 2021-05-13 15:48 ` [Intel-gfx] " Alex Deucher 2021-05-13 16:40 ` Tvrtko Ursulin 2021-05-13 16:40 ` [Intel-gfx] " Tvrtko Ursulin 2021-05-14 5:58 ` Alex Deucher 2021-05-14 5:58 ` [Intel-gfx] " Alex Deucher 2021-05-14 7:22 ` Nieto, David M 2021-05-14 7:22 ` [Intel-gfx] " Nieto, David M 2021-05-14 8:04 ` Christian König 2021-05-14 8:04 ` [Intel-gfx] " Christian König 2021-05-14 13:42 ` Tvrtko Ursulin 2021-05-14 13:42 ` [Intel-gfx] " Tvrtko Ursulin 2021-05-14 13:53 ` Christian König 2021-05-14 13:53 ` [Intel-gfx] " Christian König 2021-05-14 14:47 ` Tvrtko Ursulin 2021-05-14 14:47 ` [Intel-gfx] " Tvrtko Ursulin 2021-05-14 14:56 ` Christian König 2021-05-14 14:56 ` [Intel-gfx] " Christian König 2021-05-14 15:03 ` Tvrtko Ursulin 2021-05-14 15:03 ` [Intel-gfx] " Tvrtko Ursulin 2021-05-14 15:10 ` Christian König 2021-05-14 15:10 ` [Intel-gfx] " Christian König 2021-05-17 14:30 ` Daniel Vetter 2021-05-17 14:30 ` [Intel-gfx] " Daniel Vetter 2021-05-17 14:39 ` Nieto, David M 2021-05-17 14:39 ` [Intel-gfx] " Nieto, David M 2021-05-17 16:00 ` Tvrtko Ursulin 2021-05-17 16:00 ` [Intel-gfx] " Tvrtko Ursulin 2021-05-17 18:02 ` Nieto, David M 2021-05-17 18:02 ` [Intel-gfx] " Nieto, David M 2021-05-17 18:16 ` [Nouveau] " Nieto, David M 2021-05-17 18:16 ` [Intel-gfx] " Nieto, David M 2021-05-17 18:16 ` Nieto, David M 2021-05-17 19:03 ` [Nouveau] " Simon Ser 2021-05-17 19:03 ` [Intel-gfx] " Simon Ser 2021-05-17 19:03 ` Simon Ser 2021-05-18 9:08 ` [Nouveau] " Tvrtko Ursulin 2021-05-18 9:08 ` [Intel-gfx] " Tvrtko Ursulin 2021-05-18 9:08 ` Tvrtko Ursulin 2021-05-18 9:16 ` [Nouveau] " Daniel Stone 2021-05-18 9:16 ` [Intel-gfx] " Daniel Stone 2021-05-18 9:16 ` Daniel Stone 2021-05-18 9:40 ` [Nouveau] " Tvrtko Ursulin 2021-05-18 9:40 ` [Intel-gfx] " Tvrtko Ursulin 2021-05-18 9:40 ` Tvrtko Ursulin 2021-05-19 16:16 ` [Nouveau] " Tvrtko Ursulin 2021-05-19 16:16 ` [Intel-gfx] " Tvrtko Ursulin 2021-05-19 16:16 ` Tvrtko Ursulin 2021-05-19 18:23 ` [Nouveau] [Intel-gfx] " Daniel Vetter 2021-05-19 18:23 ` Daniel Vetter 2021-05-19 18:23 ` Daniel Vetter 2021-05-19 23:17 ` [Nouveau] " Nieto, David M 2021-05-19 23:17 ` Nieto, David M 2021-05-19 23:17 ` Nieto, David M 2021-05-20 14:11 ` [Nouveau] " Daniel Vetter 2021-05-20 14:11 ` Daniel Vetter 2021-05-20 14:11 ` Daniel Vetter 2021-05-20 14:12 ` [Nouveau] " Christian König 2021-05-20 14:12 ` Christian König 2021-05-20 14:12 ` Christian König 2021-05-20 14:17 ` [Nouveau] " arabek 2021-05-20 14:17 ` [Intel-gfx] [Nouveau] " arabek 2021-05-20 14:17 ` [Nouveau] [Intel-gfx] " arabek 2021-05-20 8:35 ` Tvrtko Ursulin 2021-05-20 8:35 ` Tvrtko Ursulin 2021-05-20 8:35 ` Tvrtko Ursulin 2021-05-24 10:48 ` [Nouveau] " Tvrtko Ursulin 2021-05-24 10:48 ` Tvrtko Ursulin 2021-05-24 10:48 ` Tvrtko Ursulin 2021-05-18 9:35 ` Tvrtko Ursulin 2021-05-18 9:35 ` [Intel-gfx] " Tvrtko Ursulin 2021-05-18 12:06 ` Christian König 2021-05-18 12:06 ` [Intel-gfx] " Christian König 2021-05-17 19:16 ` Christian König 2021-05-17 19:16 ` [Intel-gfx] " Christian König 2021-06-28 10:16 ` Tvrtko Ursulin 2021-06-28 10:16 ` [Intel-gfx] " Tvrtko Ursulin 2021-06-28 14:37 ` Daniel Vetter 2021-06-28 14:37 ` [Intel-gfx] " Daniel Vetter 2021-05-15 10:40 ` Maxime Schmitt 2021-05-17 16:13 ` Tvrtko Ursulin 2021-05-17 14:20 ` Daniel Vetter 2021-05-17 14:20 ` [Intel-gfx] " Daniel Vetter 2021-05-13 16:38 ` [Intel-gfx] ✗ Fi.CI.IGT: 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=20210513110002.3641705-8-tvrtko.ursulin@linux.intel.com \ --to=tvrtko.ursulin@linux.intel.com \ --cc=Intel-gfx@lists.freedesktop.org \ --cc=dri-devel@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: linkBe 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.