Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915: Expose client engine utilisation via fdinfo

Similar to AMD commit
874442541133 ("drm/amdgpu: Add show_fdinfo() interface"), using the
infrastructure added in previous patches, we add basic client info
and GPU engine utilisation for i915.

Example of the output:

pos: 0
flags: 0100002
mnt_id: 21
drm-driver: i915
drm-pdev: 0000:00:02.0
drm-client-id: 7
drm-engine-render: 9288864723 ns
drm-engine-copy: 2035071108 ns
drm-engine-video: 0 ns
drm-engine-video-enhance: 0 ns

v2:
* Update for removal of name and pid.

v3:
* Use drm_driver.name.

v4:
* Added drm-engine-capacity- tag.
* Fix typo. (Umesh)

v5:
* Don't output engine data before Gen8.

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: David M Nieto <David.Nieto@amd.com>
Cc: Christian König <christian.koenig@amd.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Chris Healy <cphealy@gmail.com>
Acked-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
Acked-by: Rob Clark <robdclark@gmail.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20220401142205.3123159-9-tvrtko.ursulin@linux.intel.com

+125
+6
Documentation/gpu/drm-usage-stats.rst
··· 104 104 105 105 Default unit shall be bytes with optional unit specifiers of 'KiB' or 'MiB' 106 106 indicating kibi- or mebi-bytes. 107 + 108 + =============================== 109 + Driver specific implementations 110 + =============================== 111 + 112 + :ref:`i915-usage-stats`
+28
Documentation/gpu/i915.rst
··· 709 709 710 710 .. kernel-doc:: drivers/gpu/drm/i915/i915_reg.h 711 711 :doc: The i915 register macro definition style guide 712 + 713 + .. _i915-usage-stats: 714 + 715 + i915 DRM client usage stats implementation 716 + ========================================== 717 + 718 + The drm/i915 driver implements the DRM client usage stats specification as 719 + documented in :ref:`drm-client-usage-stats`. 720 + 721 + Example of the output showing the implemented key value pairs and entirety of 722 + the currently possible format options: 723 + 724 + :: 725 + 726 + pos: 0 727 + flags: 0100002 728 + mnt_id: 21 729 + drm-driver: i915 730 + drm-pdev: 0000:00:02.0 731 + drm-client-id: 7 732 + drm-engine-render: 9288864723 ns 733 + drm-engine-copy: 2035071108 ns 734 + drm-engine-video: 0 ns 735 + drm-engine-capacity-video: 2 736 + drm-engine-video-enhance: 0 ns 737 + 738 + Possible `drm-engine-` key names are: `render`, `copy`, `video` and 739 + `video-enhance`.
+3
drivers/gpu/drm/i915/i915_driver.c
··· 1742 1742 .read = drm_read, 1743 1743 .compat_ioctl = i915_ioc32_compat_ioctl, 1744 1744 .llseek = noop_llseek, 1745 + #ifdef CONFIG_PROC_FS 1746 + .show_fdinfo = i915_drm_client_fdinfo, 1747 + #endif 1745 1748 }; 1746 1749 1747 1750 static int
+84
drivers/gpu/drm/i915/i915_drm_client.c
··· 7 7 #include <linux/slab.h> 8 8 #include <linux/types.h> 9 9 10 + #include <uapi/drm/i915_drm.h> 11 + 12 + #include <drm/drm_print.h> 13 + 14 + #include "gem/i915_gem_context.h" 10 15 #include "i915_drm_client.h" 16 + #include "i915_file_private.h" 11 17 #include "i915_gem.h" 12 18 #include "i915_utils.h" 13 19 ··· 74 68 GEM_BUG_ON(!xa_empty(&clients->xarray)); 75 69 xa_destroy(&clients->xarray); 76 70 } 71 + 72 + #ifdef CONFIG_PROC_FS 73 + static const char * const uabi_class_names[] = { 74 + [I915_ENGINE_CLASS_RENDER] = "render", 75 + [I915_ENGINE_CLASS_COPY] = "copy", 76 + [I915_ENGINE_CLASS_VIDEO] = "video", 77 + [I915_ENGINE_CLASS_VIDEO_ENHANCE] = "video-enhance", 78 + }; 79 + 80 + static u64 busy_add(struct i915_gem_context *ctx, unsigned int class) 81 + { 82 + struct i915_gem_engines_iter it; 83 + struct intel_context *ce; 84 + u64 total = 0; 85 + 86 + for_each_gem_engine(ce, rcu_dereference(ctx->engines), it) { 87 + if (ce->engine->uabi_class != class) 88 + continue; 89 + 90 + total += intel_context_get_total_runtime_ns(ce); 91 + } 92 + 93 + return total; 94 + } 95 + 96 + static void 97 + show_client_class(struct seq_file *m, 98 + struct i915_drm_client *client, 99 + unsigned int class) 100 + { 101 + const struct list_head *list = &client->ctx_list; 102 + u64 total = atomic64_read(&client->past_runtime[class]); 103 + const unsigned int capacity = 104 + client->clients->i915->engine_uabi_class_count[class]; 105 + struct i915_gem_context *ctx; 106 + 107 + rcu_read_lock(); 108 + list_for_each_entry_rcu(ctx, list, client_link) 109 + total += busy_add(ctx, class); 110 + rcu_read_unlock(); 111 + 112 + seq_printf(m, "drm-engine-%s:\t%llu ns\n", 113 + uabi_class_names[class], total); 114 + 115 + if (capacity > 1) 116 + seq_printf(m, "drm-engine-capacity-%s:\t%u\n", 117 + uabi_class_names[class], 118 + capacity); 119 + } 120 + 121 + void i915_drm_client_fdinfo(struct seq_file *m, struct file *f) 122 + { 123 + struct drm_file *file = f->private_data; 124 + struct drm_i915_file_private *file_priv = file->driver_priv; 125 + struct drm_i915_private *i915 = file_priv->dev_priv; 126 + struct i915_drm_client *client = file_priv->client; 127 + struct pci_dev *pdev = to_pci_dev(i915->drm.dev); 128 + unsigned int i; 129 + 130 + /* 131 + * ****************************************************************** 132 + * For text output format description please see drm-usage-stats.rst! 133 + * ****************************************************************** 134 + */ 135 + 136 + seq_printf(m, "drm-driver:\t%s\n", i915->drm.driver->name); 137 + seq_printf(m, "drm-pdev:\t%04x:%02x:%02x.%d\n", 138 + pci_domain_nr(pdev->bus), pdev->bus->number, 139 + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); 140 + seq_printf(m, "drm-client-id:\t%u\n", client->id); 141 + 142 + if (GRAPHICS_VER(i915) < 8) 143 + return; 144 + 145 + for (i = 0; i < ARRAY_SIZE(uabi_class_names); i++) 146 + show_client_class(m, client, i); 147 + } 148 + #endif
+4
drivers/gpu/drm/i915/i915_drm_client.h
··· 59 59 60 60 struct i915_drm_client *i915_drm_client_add(struct i915_drm_clients *clients); 61 61 62 + #ifdef CONFIG_PROC_FS 63 + void i915_drm_client_fdinfo(struct seq_file *m, struct file *f); 64 + #endif 65 + 62 66 void i915_drm_clients_fini(struct i915_drm_clients *clients); 63 67 64 68 #endif /* !__I915_DRM_CLIENT_H__ */