From: Chris Wilson <chris@chris-wilson.co.uk> To: dri-devel@lists.freedesktop.org Cc: intel-gfx@lists.freedesktop.org, Chris Wilson <chris@chris-wilson.co.uk> Subject: [RFC 1/3] proc: Show GPU runtimes Date: Thu, 4 Feb 2021 12:11:19 +0000 [thread overview] Message-ID: <20210204121121.2660-1-chris@chris-wilson.co.uk> (raw) Present an interface for system monitors to watch the GPU usage as a whole and by individual applications. By consolidating the information into a canonical location, we have a single interface that can track the utilisation of all GPU devices and sub-devices. This is preferrable to asking the system monitors to walk the sysfs, or other interfaces, of each device and parse the custom information presented by each driver. Opens: - Should we try to name each channel so that it can be shown in UI? In gnome-system-monitor, we would have a task list: Process ... GPU0% GPU1% and charts that would show the GPU% on/next the CPU overview. Then we could have a futher expansion of a GPU% into per-channel utilisation. That would be useful to check to see what is saturating a particular channel, e.g. find the video decoder bottleneck. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> --- fs/proc/Makefile | 1 + fs/proc/base.c | 2 + fs/proc/gpu.c | 83 ++++++++++++++++++++++++++++++++++++++++ fs/proc/internal.h | 6 +++ include/linux/proc_gpu.h | 33 ++++++++++++++++ 5 files changed, 125 insertions(+) create mode 100644 fs/proc/gpu.c create mode 100644 include/linux/proc_gpu.h diff --git a/fs/proc/Makefile b/fs/proc/Makefile index bd08616ed8ba..bdc42b592e3e 100644 --- a/fs/proc/Makefile +++ b/fs/proc/Makefile @@ -16,6 +16,7 @@ proc-y += cmdline.o proc-y += consoles.o proc-y += cpuinfo.o proc-y += devices.o +proc-y += gpu.o proc-y += interrupts.o proc-y += loadavg.o proc-y += meminfo.o diff --git a/fs/proc/base.c b/fs/proc/base.c index b3422cda2a91..062298f5f6c8 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -3266,6 +3266,7 @@ static const struct pid_entry tgid_base_stuff[] = { #ifdef CONFIG_SECCOMP_CACHE_DEBUG ONE("seccomp_cache", S_IRUSR, proc_pid_seccomp_cache), #endif + ONE("gpu", S_IRUGO, proc_pid_gpu), }; static int proc_tgid_base_readdir(struct file *file, struct dir_context *ctx) @@ -3598,6 +3599,7 @@ static const struct pid_entry tid_base_stuff[] = { #ifdef CONFIG_SECCOMP_CACHE_DEBUG ONE("seccomp_cache", S_IRUSR, proc_pid_seccomp_cache), #endif + ONE("gpu", S_IRUGO, proc_pid_gpu), }; static int proc_tid_base_readdir(struct file *file, struct dir_context *ctx) diff --git a/fs/proc/gpu.c b/fs/proc/gpu.c new file mode 100644 index 000000000000..7264bf1f2f7b --- /dev/null +++ b/fs/proc/gpu.c @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <linux/fs.h> +#include <linux/init.h> +#include <linux/proc_fs.h> +#include <linux/proc_gpu.h> +#include <linux/seq_file.h> +#include <linux/spinlock.h> +#include <linux/list.h> + +#include "internal.h" + +static LIST_HEAD(gpu); +static DEFINE_SPINLOCK(lock); + +void proc_gpu_register(struct proc_gpu *pg) +{ + spin_lock(&lock); + list_add_tail(&pg->link, &gpu); + spin_unlock(&lock); +} +EXPORT_SYMBOL_GPL(proc_gpu_register); + +void proc_gpu_unregister(struct proc_gpu *pg) +{ + spin_lock(&lock); + list_del(&pg->link); + spin_unlock(&lock); +} +EXPORT_SYMBOL_GPL(proc_gpu_unregister); + +static void print_runtime(struct seq_file *m, const struct proc_gpu_runtime *rt) +{ + int i; + + seq_printf(m, "%llu", rt->device); + + for (i = 0; i < rt->nchannel; i++) + seq_printf(m, " %llu", rt->channel[i]); + + seq_printf(m, " %s\n", rt->name); +} + +int proc_pid_gpu(struct seq_file *m, struct pid_namespace *ns, + struct pid *pid, struct task_struct *task) +{ + struct proc_gpu *p, *pn, mark = {}; + struct proc_gpu_runtime rt; + + spin_lock(&lock); + list_for_each_entry_safe(p, pn, &gpu, link) { + if (!p->fn) + continue; + + rt.name[0] = '\0'; + p->fn(p, pid, &rt); + if (!rt.name[0]) + continue; + + list_add(&mark.link, &p->link); + spin_unlock(&lock); + + print_runtime(m, &rt); + + spin_lock(&lock); + list_safe_reset_next(&mark, pn, link); + list_del(&mark.link); + } + spin_unlock(&lock); + + return 0; +} + +static int proc_gpu_show(struct seq_file *m, void *v) +{ + return proc_pid_gpu(m, NULL, NULL, NULL); +} + +static int __init proc_gpu_init(void) +{ + proc_create_single("gpu", 0, NULL, proc_gpu_show); + return 0; +} +fs_initcall(proc_gpu_init); diff --git a/fs/proc/internal.h b/fs/proc/internal.h index f60b379dcdc7..08bf45bec975 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h @@ -221,6 +221,12 @@ void set_proc_pid_nlink(void); extern struct inode *proc_get_inode(struct super_block *, struct proc_dir_entry *); extern void proc_entry_rundown(struct proc_dir_entry *); +/* + * proc_gpu.c + */ +int proc_pid_gpu(struct seq_file *m, struct pid_namespace *ns, + struct pid *pid, struct task_struct *task); + /* * proc_namespaces.c */ diff --git a/include/linux/proc_gpu.h b/include/linux/proc_gpu.h new file mode 100644 index 000000000000..05c1db951c80 --- /dev/null +++ b/include/linux/proc_gpu.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Interface for showing per-gpu/per-process runtimes in /proc. + */ +#ifndef _LINUX_PROC_GPU_H +#define _LINUX_PROC_GPU_H + +#include <linux/list.h> +#include <linux/types.h> + +struct pid; +struct proc_gpu; + +struct proc_gpu_runtime { + char name[60]; + int nchannel; + u64 device; + u64 channel[64]; +}; + +typedef void (*proc_gpu_fn_t)(struct proc_gpu *arg, + struct pid *pid, + struct proc_gpu_runtime *rt); + +struct proc_gpu { + struct list_head link; + proc_gpu_fn_t fn; +}; + +void proc_gpu_register(struct proc_gpu *pg); +void proc_gpu_unregister(struct proc_gpu *pg); + +#endif /* _LINUX_PROC_GPU_H */ -- 2.20.1 _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
WARNING: multiple messages have this Message-ID (diff)
From: Chris Wilson <chris@chris-wilson.co.uk> To: dri-devel@lists.freedesktop.org Cc: intel-gfx@lists.freedesktop.org, Chris Wilson <chris@chris-wilson.co.uk> Subject: [Intel-gfx] [RFC 1/3] proc: Show GPU runtimes Date: Thu, 4 Feb 2021 12:11:19 +0000 [thread overview] Message-ID: <20210204121121.2660-1-chris@chris-wilson.co.uk> (raw) Present an interface for system monitors to watch the GPU usage as a whole and by individual applications. By consolidating the information into a canonical location, we have a single interface that can track the utilisation of all GPU devices and sub-devices. This is preferrable to asking the system monitors to walk the sysfs, or other interfaces, of each device and parse the custom information presented by each driver. Opens: - Should we try to name each channel so that it can be shown in UI? In gnome-system-monitor, we would have a task list: Process ... GPU0% GPU1% and charts that would show the GPU% on/next the CPU overview. Then we could have a futher expansion of a GPU% into per-channel utilisation. That would be useful to check to see what is saturating a particular channel, e.g. find the video decoder bottleneck. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> --- fs/proc/Makefile | 1 + fs/proc/base.c | 2 + fs/proc/gpu.c | 83 ++++++++++++++++++++++++++++++++++++++++ fs/proc/internal.h | 6 +++ include/linux/proc_gpu.h | 33 ++++++++++++++++ 5 files changed, 125 insertions(+) create mode 100644 fs/proc/gpu.c create mode 100644 include/linux/proc_gpu.h diff --git a/fs/proc/Makefile b/fs/proc/Makefile index bd08616ed8ba..bdc42b592e3e 100644 --- a/fs/proc/Makefile +++ b/fs/proc/Makefile @@ -16,6 +16,7 @@ proc-y += cmdline.o proc-y += consoles.o proc-y += cpuinfo.o proc-y += devices.o +proc-y += gpu.o proc-y += interrupts.o proc-y += loadavg.o proc-y += meminfo.o diff --git a/fs/proc/base.c b/fs/proc/base.c index b3422cda2a91..062298f5f6c8 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -3266,6 +3266,7 @@ static const struct pid_entry tgid_base_stuff[] = { #ifdef CONFIG_SECCOMP_CACHE_DEBUG ONE("seccomp_cache", S_IRUSR, proc_pid_seccomp_cache), #endif + ONE("gpu", S_IRUGO, proc_pid_gpu), }; static int proc_tgid_base_readdir(struct file *file, struct dir_context *ctx) @@ -3598,6 +3599,7 @@ static const struct pid_entry tid_base_stuff[] = { #ifdef CONFIG_SECCOMP_CACHE_DEBUG ONE("seccomp_cache", S_IRUSR, proc_pid_seccomp_cache), #endif + ONE("gpu", S_IRUGO, proc_pid_gpu), }; static int proc_tid_base_readdir(struct file *file, struct dir_context *ctx) diff --git a/fs/proc/gpu.c b/fs/proc/gpu.c new file mode 100644 index 000000000000..7264bf1f2f7b --- /dev/null +++ b/fs/proc/gpu.c @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <linux/fs.h> +#include <linux/init.h> +#include <linux/proc_fs.h> +#include <linux/proc_gpu.h> +#include <linux/seq_file.h> +#include <linux/spinlock.h> +#include <linux/list.h> + +#include "internal.h" + +static LIST_HEAD(gpu); +static DEFINE_SPINLOCK(lock); + +void proc_gpu_register(struct proc_gpu *pg) +{ + spin_lock(&lock); + list_add_tail(&pg->link, &gpu); + spin_unlock(&lock); +} +EXPORT_SYMBOL_GPL(proc_gpu_register); + +void proc_gpu_unregister(struct proc_gpu *pg) +{ + spin_lock(&lock); + list_del(&pg->link); + spin_unlock(&lock); +} +EXPORT_SYMBOL_GPL(proc_gpu_unregister); + +static void print_runtime(struct seq_file *m, const struct proc_gpu_runtime *rt) +{ + int i; + + seq_printf(m, "%llu", rt->device); + + for (i = 0; i < rt->nchannel; i++) + seq_printf(m, " %llu", rt->channel[i]); + + seq_printf(m, " %s\n", rt->name); +} + +int proc_pid_gpu(struct seq_file *m, struct pid_namespace *ns, + struct pid *pid, struct task_struct *task) +{ + struct proc_gpu *p, *pn, mark = {}; + struct proc_gpu_runtime rt; + + spin_lock(&lock); + list_for_each_entry_safe(p, pn, &gpu, link) { + if (!p->fn) + continue; + + rt.name[0] = '\0'; + p->fn(p, pid, &rt); + if (!rt.name[0]) + continue; + + list_add(&mark.link, &p->link); + spin_unlock(&lock); + + print_runtime(m, &rt); + + spin_lock(&lock); + list_safe_reset_next(&mark, pn, link); + list_del(&mark.link); + } + spin_unlock(&lock); + + return 0; +} + +static int proc_gpu_show(struct seq_file *m, void *v) +{ + return proc_pid_gpu(m, NULL, NULL, NULL); +} + +static int __init proc_gpu_init(void) +{ + proc_create_single("gpu", 0, NULL, proc_gpu_show); + return 0; +} +fs_initcall(proc_gpu_init); diff --git a/fs/proc/internal.h b/fs/proc/internal.h index f60b379dcdc7..08bf45bec975 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h @@ -221,6 +221,12 @@ void set_proc_pid_nlink(void); extern struct inode *proc_get_inode(struct super_block *, struct proc_dir_entry *); extern void proc_entry_rundown(struct proc_dir_entry *); +/* + * proc_gpu.c + */ +int proc_pid_gpu(struct seq_file *m, struct pid_namespace *ns, + struct pid *pid, struct task_struct *task); + /* * proc_namespaces.c */ diff --git a/include/linux/proc_gpu.h b/include/linux/proc_gpu.h new file mode 100644 index 000000000000..05c1db951c80 --- /dev/null +++ b/include/linux/proc_gpu.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Interface for showing per-gpu/per-process runtimes in /proc. + */ +#ifndef _LINUX_PROC_GPU_H +#define _LINUX_PROC_GPU_H + +#include <linux/list.h> +#include <linux/types.h> + +struct pid; +struct proc_gpu; + +struct proc_gpu_runtime { + char name[60]; + int nchannel; + u64 device; + u64 channel[64]; +}; + +typedef void (*proc_gpu_fn_t)(struct proc_gpu *arg, + struct pid *pid, + struct proc_gpu_runtime *rt); + +struct proc_gpu { + struct list_head link; + proc_gpu_fn_t fn; +}; + +void proc_gpu_register(struct proc_gpu *pg); +void proc_gpu_unregister(struct proc_gpu *pg); + +#endif /* _LINUX_PROC_GPU_H */ -- 2.20.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next reply other threads:[~2021-02-04 12:11 UTC|newest] Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-02-04 12:11 Chris Wilson [this message] 2021-02-04 12:11 ` [Intel-gfx] [RFC 1/3] proc: Show GPU runtimes Chris Wilson 2021-02-04 12:11 ` [RFC 2/3] drm/i915: Look up clients by pid Chris Wilson 2021-02-04 12:11 ` [Intel-gfx] " Chris Wilson 2021-02-04 12:11 ` [RFC 3/3] drm/i915/gt: Export device and per-process runtimes via procfs Chris Wilson 2021-02-04 12:11 ` [Intel-gfx] " Chris Wilson 2021-02-12 14:57 ` Emil Velikov 2021-02-12 14:57 ` [Intel-gfx] " Emil Velikov 2021-02-12 15:16 ` Chris Wilson 2021-02-12 15:16 ` [Intel-gfx] " Chris Wilson 2021-02-12 15:45 ` Emil Velikov 2021-02-12 15:45 ` [Intel-gfx] " Emil Velikov 2021-02-12 16:07 ` Chris Wilson 2021-02-12 16:07 ` [Intel-gfx] " Chris Wilson 2021-02-04 17:01 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [RFC,1/3] proc: Show GPU runtimes Patchwork 2021-02-04 17:31 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork 2021-02-04 22:16 ` [Intel-gfx] ✓ Fi.CI.IGT: " 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=20210204121121.2660-1-chris@chris-wilson.co.uk \ --to=chris@chris-wilson.co.uk \ --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: 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.