* [PATCH v5 0/7] drm: fdinfo memory stats
@ 2023-05-24 15:59 Rob Clark
2023-05-24 15:59 ` [PATCH v5 1/7] drm/docs: Fix usage stats typos Rob Clark
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Rob Clark @ 2023-05-24 15:59 UTC (permalink / raw)
To: dri-devel
Cc: freedreno, Daniel Vetter, Tvrtko Ursulin, Boris Brezillon,
Christopher Healy, Emil Velikov, Christian König, Rob Clark,
Alex Deucher, open list:RADEON and AMDGPU DRM DRIVERS,
Arunpravin Paneer Selvam, Dave Airlie, Guchun Chen, Jim Cromie,
Lijo Lazar, open list:DRM DRIVER FOR MSM ADRENO GPU,
open list:DOCUMENTATION, open list, Marek Olšák,
Mario Limonciello, Michel Dänzer, Sean Paul, Shashank Sharma,
Srinivasan Shanmugam, YiPeng Chai
From: Rob Clark <robdclark@chromium.org>
Similar motivation to other similar recent attempt[1]. But with an
attempt to have some shared code for this. As well as documentation.
It is probably a bit UMA-centric, I guess devices with VRAM might want
some placement stats as well. But this seems like a reasonable start.
Basic gputop support: https://patchwork.freedesktop.org/series/116236/
And already nvtop support: https://github.com/Syllo/nvtop/pull/204
I've combined the separate series to add comm/cmdline override onto
the end of this, simply out of convenience (they would otherwise
conflict in a bunch of places).
v2: Extend things to allow for multiple regions other than just system
"memory", make drm_show_memory_stats() a helper so that, drivers
can use it or not based on their needs (but in either case, re-
use drm_print_memory_stats()
v3: Docs fixes
v4: use u64 for drm_memory_stats, small docs update and collected
Tvrtko's a-b
v5: Rebase on drm-misc-next, drop comm/cmdline override patches
[1] https://patchwork.freedesktop.org/series/112397/
Rob Clark (7):
drm/docs: Fix usage stats typos
drm: Add common fdinfo helper
drm/msm: Switch to fdinfo helper
drm/amdgpu: Switch to fdinfo helper
drm: Add fdinfo memory stats
drm/msm: Add memory stats to fdinfo
drm/doc: Relax fdinfo string constraints
Documentation/gpu/drm-usage-stats.rst | 91 ++++++++++----
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c | 32 +++--
drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.h | 2 +-
drivers/gpu/drm/drm_file.c | 132 +++++++++++++++++++++
drivers/gpu/drm/msm/msm_drv.c | 13 +-
drivers/gpu/drm/msm/msm_gem.c | 15 +++
drivers/gpu/drm/msm/msm_gpu.c | 2 -
include/drm/drm_drv.h | 7 ++
include/drm/drm_file.h | 32 +++++
include/drm/drm_gem.h | 32 +++++
11 files changed, 308 insertions(+), 53 deletions(-)
--
2.40.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v5 1/7] drm/docs: Fix usage stats typos
2023-05-24 15:59 [PATCH v5 0/7] drm: fdinfo memory stats Rob Clark
@ 2023-05-24 15:59 ` Rob Clark
2023-05-24 15:59 ` [PATCH v5 2/7] drm: Add common fdinfo helper Rob Clark
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Rob Clark @ 2023-05-24 15:59 UTC (permalink / raw)
To: dri-devel
Cc: freedreno, Daniel Vetter, Tvrtko Ursulin, Boris Brezillon,
Christopher Healy, Emil Velikov, Christian König, Rob Clark,
Rodrigo Vivi, Dave Airlie, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Jonathan Corbet,
open list:DOCUMENTATION, open list
From: Rob Clark <robdclark@chromium.org>
Fix a couple missing ':'s.
Signed-off-by: Rob Clark <robdclark@chromium.org>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Dave Airlie <airlied@redhat.com>
---
Documentation/gpu/drm-usage-stats.rst | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Documentation/gpu/drm-usage-stats.rst b/Documentation/gpu/drm-usage-stats.rst
index b46327356e80..72d069e5dacb 100644
--- a/Documentation/gpu/drm-usage-stats.rst
+++ b/Documentation/gpu/drm-usage-stats.rst
@@ -98,33 +98,33 @@ is not allowed.
Each possible memory type which can be used to store buffer objects by the
GPU in question shall be given a stable and unique name to be returned as the
string here.
Value shall reflect the amount of storage currently consumed by the buffer
object belong to this client, in the respective memory region.
Default unit shall be bytes with optional unit specifiers of 'KiB' or 'MiB'
indicating kibi- or mebi-bytes.
-- drm-cycles-<str> <uint>
+- drm-cycles-<str>: <uint>
Engine identifier string must be the same as the one specified in the
drm-engine-<str> tag and shall contain the number of busy cycles for the given
engine.
Values are not required to be constantly monotonic if it makes the driver
implementation easier, but are required to catch up with the previously reported
larger value within a reasonable period. Upon observing a value lower than what
was previously read, userspace is expected to stay with that larger previous
value until a monotonic update is seen.
-- drm-maxfreq-<str> <uint> [Hz|MHz|KHz]
+- drm-maxfreq-<str>: <uint> [Hz|MHz|KHz]
Engine identifier string must be the same as the one specified in the
drm-engine-<str> tag and shall contain the maximum frequency for the given
engine. Taken together with drm-cycles-<str>, this can be used to calculate
percentage utilization of the engine, whereas drm-engine-<str> only reflects
time active without considering what frequency the engine is operating as a
percentage of it's maximum frequency.
Driver specific implementations
===============================
--
2.40.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v5 2/7] drm: Add common fdinfo helper
2023-05-24 15:59 [PATCH v5 0/7] drm: fdinfo memory stats Rob Clark
2023-05-24 15:59 ` [PATCH v5 1/7] drm/docs: Fix usage stats typos Rob Clark
@ 2023-05-24 15:59 ` Rob Clark
2023-05-24 15:59 ` [PATCH v5 5/7] drm: Add fdinfo memory stats Rob Clark
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Rob Clark @ 2023-05-24 15:59 UTC (permalink / raw)
To: dri-devel
Cc: freedreno, Daniel Vetter, Tvrtko Ursulin, Boris Brezillon,
Christopher Healy, Emil Velikov, Christian König, Rob Clark,
Daniel Vetter, Dave Airlie, David Airlie, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Jonathan Corbet,
open list:DOCUMENTATION, open list
From: Rob Clark <robdclark@chromium.org>
Handle a bit of the boiler-plate in a single case, and make it easier to
add some core tracked stats. This also ensures consistent behavior
across drivers for standardised fields.
v2: Update drm-usage-stats.rst, 64b client-id, rename drm_show_fdinfo
v3: Rebase on drm-misc-next
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Rob Clark <robdclark@chromium.org>
Acked-by: Dave Airlie <airlied@redhat.com>
---
Documentation/gpu/drm-usage-stats.rst | 10 +++++++-
drivers/gpu/drm/drm_file.c | 35 +++++++++++++++++++++++++++
include/drm/drm_drv.h | 7 ++++++
include/drm/drm_file.h | 4 +++
4 files changed, 55 insertions(+), 1 deletion(-)
diff --git a/Documentation/gpu/drm-usage-stats.rst b/Documentation/gpu/drm-usage-stats.rst
index 72d069e5dacb..552195fb1ea3 100644
--- a/Documentation/gpu/drm-usage-stats.rst
+++ b/Documentation/gpu/drm-usage-stats.rst
@@ -119,14 +119,22 @@ value until a monotonic update is seen.
- drm-maxfreq-<str>: <uint> [Hz|MHz|KHz]
Engine identifier string must be the same as the one specified in the
drm-engine-<str> tag and shall contain the maximum frequency for the given
engine. Taken together with drm-cycles-<str>, this can be used to calculate
percentage utilization of the engine, whereas drm-engine-<str> only reflects
time active without considering what frequency the engine is operating as a
percentage of it's maximum frequency.
+Implementation Details
+======================
+
+Drivers should use drm_show_fdinfo() in their `struct file_operations`, and
+implement &drm_driver.show_fdinfo if they wish to provide any stats which
+are not provided by drm_show_fdinfo(). But even driver specific stats should
+be documented above and where possible, aligned with other drivers.
+
Driver specific implementations
-===============================
+-------------------------------
:ref:`i915-usage-stats`
diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
index c1018c470047..37b4f76a5191 100644
--- a/drivers/gpu/drm/drm_file.c
+++ b/drivers/gpu/drm/drm_file.c
@@ -141,28 +141,31 @@ bool drm_dev_needs_global_mutex(struct drm_device *dev)
*
* This allocates a new DRM file context. It is not linked into any context and
* can be used by the caller freely. Note that the context keeps a pointer to
* @minor, so it must be freed before @minor is.
*
* RETURNS:
* Pointer to newly allocated context, ERR_PTR on failure.
*/
struct drm_file *drm_file_alloc(struct drm_minor *minor)
{
+ static atomic64_t ident = ATOMIC_INIT(0);
struct drm_device *dev = minor->dev;
struct drm_file *file;
int ret;
file = kzalloc(sizeof(*file), GFP_KERNEL);
if (!file)
return ERR_PTR(-ENOMEM);
+ /* Get a unique identifier for fdinfo: */
+ file->client_id = atomic64_inc_return(&ident);
file->pid = get_pid(task_tgid(current));
file->minor = minor;
/* for compatibility root is always authenticated */
file->authenticated = capable(CAP_SYS_ADMIN);
INIT_LIST_HEAD(&file->lhead);
INIT_LIST_HEAD(&file->fbs);
mutex_init(&file->fbs_lock);
INIT_LIST_HEAD(&file->blobs);
@@ -861,20 +864,52 @@ EXPORT_SYMBOL(drm_send_event_locked);
void drm_send_event(struct drm_device *dev, struct drm_pending_event *e)
{
unsigned long irqflags;
spin_lock_irqsave(&dev->event_lock, irqflags);
drm_send_event_helper(dev, e, 0);
spin_unlock_irqrestore(&dev->event_lock, irqflags);
}
EXPORT_SYMBOL(drm_send_event);
+/**
+ * drm_show_fdinfo - helper for drm file fops
+ * @seq_file: output stream
+ * @f: the device file instance
+ *
+ * Helper to implement fdinfo, for userspace to query usage stats, etc, of a
+ * process using the GPU. See also &drm_driver.show_fdinfo.
+ *
+ * For text output format description please see Documentation/gpu/drm-usage-stats.rst
+ */
+void drm_show_fdinfo(struct seq_file *m, struct file *f)
+{
+ struct drm_file *file = f->private_data;
+ struct drm_device *dev = file->minor->dev;
+ struct drm_printer p = drm_seq_file_printer(m);
+
+ drm_printf(&p, "drm-driver:\t%s\n", dev->driver->name);
+ drm_printf(&p, "drm-client-id:\t%llu\n", file->client_id);
+
+ if (dev_is_pci(dev->dev)) {
+ struct pci_dev *pdev = to_pci_dev(dev->dev);
+
+ drm_printf(&p, "drm-pdev:\t%04x:%02x:%02x.%d\n",
+ pci_domain_nr(pdev->bus), pdev->bus->number,
+ PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
+ }
+
+ if (dev->driver->show_fdinfo)
+ dev->driver->show_fdinfo(&p, file);
+}
+EXPORT_SYMBOL(drm_show_fdinfo);
+
/**
* mock_drm_getfile - Create a new struct file for the drm device
* @minor: drm minor to wrap (e.g. #drm_device.primary)
* @flags: file creation mode (O_RDWR etc)
*
* This create a new struct file that wraps a DRM file context around a
* DRM minor. This mimicks userspace opening e.g. /dev/dri/card0, but without
* invoking userspace. The struct file may be operated on using its f_op
* (the drm_device.driver.fops) to mimick userspace operations, or be supplied
* to userspace facing functions as an internal/anonymous client.
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index b419c59c4bef..89e2706cac56 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -394,20 +394,27 @@ struct drm_driver {
* Called by the user via ioctl.
*
* Returns:
*
* Zero on success, negative errno on failure.
*/
int (*dumb_map_offset)(struct drm_file *file_priv,
struct drm_device *dev, uint32_t handle,
uint64_t *offset);
+ /**
+ * @show_fdinfo:
+ *
+ * Print device specific fdinfo. See Documentation/gpu/drm-usage-stats.rst.
+ */
+ void (*show_fdinfo)(struct drm_printer *p, struct drm_file *f);
+
/** @major: driver major number */
int major;
/** @minor: driver minor number */
int minor;
/** @patchlevel: driver patch level */
int patchlevel;
/** @name: driver name */
char *name;
/** @desc: driver description */
char *desc;
diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h
index ecffe24e2b1b..7d9b3c65cbc1 100644
--- a/include/drm/drm_file.h
+++ b/include/drm/drm_file.h
@@ -251,20 +251,23 @@ struct drm_file {
* primary nodes and authentication <drm_primary_node>`.
*/
struct drm_master *master;
/** @master_lookup_lock: Serializes @master. */
spinlock_t master_lookup_lock;
/** @pid: Process that opened this file. */
struct pid *pid;
+ /** @client_id: A unique id for fdinfo */
+ u64 client_id;
+
/** @magic: Authentication magic, see @authenticated. */
drm_magic_t magic;
/**
* @lhead:
*
* List of all open files of a DRM device, linked into
* &drm_device.filelist. Protected by &drm_device.filelist_mutex.
*/
struct list_head lhead;
@@ -431,14 +434,15 @@ int drm_event_reserve_init(struct drm_device *dev,
struct drm_file *file_priv,
struct drm_pending_event *p,
struct drm_event *e);
void drm_event_cancel_free(struct drm_device *dev,
struct drm_pending_event *p);
void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e);
void drm_send_event(struct drm_device *dev, struct drm_pending_event *e);
void drm_send_event_timestamp_locked(struct drm_device *dev,
struct drm_pending_event *e,
ktime_t timestamp);
+void drm_show_fdinfo(struct seq_file *m, struct file *f);
struct file *mock_drm_getfile(struct drm_minor *minor, unsigned int flags);
#endif /* _DRM_FILE_H_ */
--
2.40.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v5 5/7] drm: Add fdinfo memory stats
2023-05-24 15:59 [PATCH v5 0/7] drm: fdinfo memory stats Rob Clark
2023-05-24 15:59 ` [PATCH v5 1/7] drm/docs: Fix usage stats typos Rob Clark
2023-05-24 15:59 ` [PATCH v5 2/7] drm: Add common fdinfo helper Rob Clark
@ 2023-05-24 15:59 ` Rob Clark
2023-05-24 15:59 ` [PATCH v5 7/7] drm/doc: Relax fdinfo string constraints Rob Clark
2023-05-24 16:10 ` [PATCH v5 0/7] drm: fdinfo memory stats Neil Armstrong
4 siblings, 0 replies; 6+ messages in thread
From: Rob Clark @ 2023-05-24 15:59 UTC (permalink / raw)
To: dri-devel
Cc: freedreno, Daniel Vetter, Tvrtko Ursulin, Boris Brezillon,
Christopher Healy, Emil Velikov, Christian König, Rob Clark,
Daniel Vetter, Tvrtko Ursulin, Dave Airlie, David Airlie,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Jonathan Corbet, open list:DOCUMENTATION, open list
From: Rob Clark <robdclark@chromium.org>
Add support to dump GEM stats to fdinfo.
v2: Fix typos, change size units to match docs, use div_u64
v3: Do it in core
v4: more kerneldoc
v5: doc fixes
v6: Actually use u64, bit more comment docs
Signed-off-by: Rob Clark <robdclark@chromium.org>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Acked-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Acked-by: Dave Airlie <airlied@redhat.com>
---
Documentation/gpu/drm-usage-stats.rst | 54 +++++++++++----
drivers/gpu/drm/drm_file.c | 99 ++++++++++++++++++++++++++-
include/drm/drm_file.h | 28 ++++++++
include/drm/drm_gem.h | 32 +++++++++
4 files changed, 200 insertions(+), 13 deletions(-)
diff --git a/Documentation/gpu/drm-usage-stats.rst b/Documentation/gpu/drm-usage-stats.rst
index 552195fb1ea3..d012eb56885e 100644
--- a/Documentation/gpu/drm-usage-stats.rst
+++ b/Documentation/gpu/drm-usage-stats.rst
@@ -45,37 +45,43 @@ Mandatory fully standardised keys
---------------------------------
- drm-driver: <str>
String shall contain the name this driver registered as via the respective
`struct drm_driver` data structure.
Optional fully standardised keys
--------------------------------
+Identification
+^^^^^^^^^^^^^^
+
- drm-pdev: <aaaa:bb.cc.d>
For PCI devices this should contain the PCI slot address of the device in
question.
- drm-client-id: <uint>
Unique value relating to the open DRM file descriptor used to distinguish
duplicated and shared file descriptors. Conceptually the value should map 1:1
to the in kernel representation of `struct drm_file` instances.
Uniqueness of the value shall be either globally unique, or unique within the
scope of each device, in which case `drm-pdev` shall be present as well.
Userspace should make sure to not double account any usage statistics by using
the above described criteria in order to associate data to individual clients.
+Utilization
+^^^^^^^^^^^
+
- drm-engine-<str>: <uint> ns
GPUs usually contain multiple execution engines. Each shall be given a stable
and unique name (str), with possible values documented in the driver specific
documentation.
Value shall be in specified time units which the respective GPU engine spent
busy executing workloads belonging to this client.
Values are not required to be constantly monotonic if it makes the driver
@@ -86,32 +92,20 @@ value until a monotonic update is seen.
- drm-engine-capacity-<str>: <uint>
Engine identifier string must be the same as the one specified in the
drm-engine-<str> tag and shall contain a greater than zero number in case the
exported engine corresponds to a group of identical hardware engines.
In the absence of this tag parser shall assume capacity of one. Zero capacity
is not allowed.
-- drm-memory-<str>: <uint> [KiB|MiB]
-
-Each possible memory type which can be used to store buffer objects by the
-GPU in question shall be given a stable and unique name to be returned as the
-string here.
-
-Value shall reflect the amount of storage currently consumed by the buffer
-object belong to this client, in the respective memory region.
-
-Default unit shall be bytes with optional unit specifiers of 'KiB' or 'MiB'
-indicating kibi- or mebi-bytes.
-
- drm-cycles-<str>: <uint>
Engine identifier string must be the same as the one specified in the
drm-engine-<str> tag and shall contain the number of busy cycles for the given
engine.
Values are not required to be constantly monotonic if it makes the driver
implementation easier, but are required to catch up with the previously reported
larger value within a reasonable period. Upon observing a value lower than what
was previously read, userspace is expected to stay with that larger previous
@@ -119,20 +113,56 @@ value until a monotonic update is seen.
- drm-maxfreq-<str>: <uint> [Hz|MHz|KHz]
Engine identifier string must be the same as the one specified in the
drm-engine-<str> tag and shall contain the maximum frequency for the given
engine. Taken together with drm-cycles-<str>, this can be used to calculate
percentage utilization of the engine, whereas drm-engine-<str> only reflects
time active without considering what frequency the engine is operating as a
percentage of it's maximum frequency.
+Memory
+^^^^^^
+
+- drm-memory-<region>: <uint> [KiB|MiB]
+
+Each possible memory type which can be used to store buffer objects by the
+GPU in question shall be given a stable and unique name to be returned as the
+string here. The name "memory" is reserved to refer to normal system memory.
+
+Value shall reflect the amount of storage currently consumed by the buffer
+objects belong to this client, in the respective memory region.
+
+Default unit shall be bytes with optional unit specifiers of 'KiB' or 'MiB'
+indicating kibi- or mebi-bytes.
+
+- drm-shared-<region>: <uint> [KiB|MiB]
+
+The total size of buffers that are shared with another file (ie. have more
+than a single handle).
+
+- drm-total-<region>: <uint> [KiB|MiB]
+
+The total size of buffers that including shared and private memory.
+
+- drm-resident-<region>: <uint> [KiB|MiB]
+
+The total size of buffers that are resident in the specified region.
+
+- drm-purgeable-<region>: <uint> [KiB|MiB]
+
+The total size of buffers that are purgeable.
+
+- drm-active-<region>: <uint> [KiB|MiB]
+
+The total size of buffers that are active on one or more engines.
+
Implementation Details
======================
Drivers should use drm_show_fdinfo() in their `struct file_operations`, and
implement &drm_driver.show_fdinfo if they wish to provide any stats which
are not provided by drm_show_fdinfo(). But even driver specific stats should
be documented above and where possible, aligned with other drivers.
Driver specific implementations
-------------------------------
diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
index 37b4f76a5191..883d83bc0e3d 100644
--- a/drivers/gpu/drm/drm_file.c
+++ b/drivers/gpu/drm/drm_file.c
@@ -35,20 +35,21 @@
#include <linux/dma-fence.h>
#include <linux/file.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <drm/drm_client.h>
#include <drm/drm_drv.h>
#include <drm/drm_file.h>
+#include <drm/drm_gem.h>
#include <drm/drm_print.h>
#include "drm_crtc_internal.h"
#include "drm_internal.h"
#include "drm_legacy.h"
/* from BKL pushdown */
DEFINE_MUTEX(drm_global_mutex);
bool drm_dev_needs_global_mutex(struct drm_device *dev)
@@ -864,23 +865,119 @@ EXPORT_SYMBOL(drm_send_event_locked);
void drm_send_event(struct drm_device *dev, struct drm_pending_event *e)
{
unsigned long irqflags;
spin_lock_irqsave(&dev->event_lock, irqflags);
drm_send_event_helper(dev, e, 0);
spin_unlock_irqrestore(&dev->event_lock, irqflags);
}
EXPORT_SYMBOL(drm_send_event);
+static void print_size(struct drm_printer *p, const char *stat,
+ const char *region, u64 sz)
+{
+ const char *units[] = {"", " KiB", " MiB"};
+ unsigned u;
+
+ for (u = 0; u < ARRAY_SIZE(units) - 1; u++) {
+ if (sz < SZ_1K)
+ break;
+ sz = div_u64(sz, SZ_1K);
+ }
+
+ drm_printf(p, "drm-%s-%s:\t%llu%s\n", stat, region, sz, units[u]);
+}
+
+/**
+ * drm_print_memory_stats - A helper to print memory stats
+ * @p: The printer to print output to
+ * @stats: The collected memory stats
+ * @supported_status: Bitmask of optional stats which are available
+ * @region: The memory region
+ *
+ */
+void drm_print_memory_stats(struct drm_printer *p,
+ const struct drm_memory_stats *stats,
+ enum drm_gem_object_status supported_status,
+ const char *region)
+{
+ print_size(p, "total", region, stats->private + stats->shared);
+ print_size(p, "shared", region, stats->shared);
+ print_size(p, "active", region, stats->active);
+
+ if (supported_status & DRM_GEM_OBJECT_RESIDENT)
+ print_size(p, "resident", region, stats->resident);
+
+ if (supported_status & DRM_GEM_OBJECT_PURGEABLE)
+ print_size(p, "purgeable", region, stats->purgeable);
+}
+EXPORT_SYMBOL(drm_print_memory_stats);
+
+/**
+ * drm_show_memory_stats - Helper to collect and show standard fdinfo memory stats
+ * @p: the printer to print output to
+ * @file: the DRM file
+ *
+ * Helper to iterate over GEM objects with a handle allocated in the specified
+ * file.
+ */
+void drm_show_memory_stats(struct drm_printer *p, struct drm_file *file)
+{
+ struct drm_gem_object *obj;
+ struct drm_memory_stats status = {};
+ enum drm_gem_object_status supported_status;
+ int id;
+
+ spin_lock(&file->table_lock);
+ idr_for_each_entry (&file->object_idr, obj, id) {
+ enum drm_gem_object_status s = 0;
+
+ if (obj->funcs && obj->funcs->status) {
+ s = obj->funcs->status(obj);
+ supported_status = DRM_GEM_OBJECT_RESIDENT |
+ DRM_GEM_OBJECT_PURGEABLE;
+ }
+
+ if (obj->handle_count > 1) {
+ status.shared += obj->size;
+ } else {
+ status.private += obj->size;
+ }
+
+ if (s & DRM_GEM_OBJECT_RESIDENT) {
+ status.resident += obj->size;
+ } else {
+ /* If already purged or not yet backed by pages, don't
+ * count it as purgeable:
+ */
+ s &= ~DRM_GEM_OBJECT_PURGEABLE;
+ }
+
+ if (!dma_resv_test_signaled(obj->resv, dma_resv_usage_rw(true))) {
+ status.active += obj->size;
+
+ /* If still active, don't count as purgeable: */
+ s &= ~DRM_GEM_OBJECT_PURGEABLE;
+ }
+
+ if (s & DRM_GEM_OBJECT_PURGEABLE)
+ status.purgeable += obj->size;
+ }
+ spin_unlock(&file->table_lock);
+
+ drm_print_memory_stats(p, &status, supported_status, "memory");
+}
+EXPORT_SYMBOL(drm_show_memory_stats);
+
/**
* drm_show_fdinfo - helper for drm file fops
- * @seq_file: output stream
+ * @m: output stream
* @f: the device file instance
*
* Helper to implement fdinfo, for userspace to query usage stats, etc, of a
* process using the GPU. See also &drm_driver.show_fdinfo.
*
* For text output format description please see Documentation/gpu/drm-usage-stats.rst
*/
void drm_show_fdinfo(struct seq_file *m, struct file *f)
{
struct drm_file *file = f->private_data;
diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h
index 7d9b3c65cbc1..966912053cb0 100644
--- a/include/drm/drm_file.h
+++ b/include/drm/drm_file.h
@@ -34,20 +34,21 @@
#include <linux/completion.h>
#include <linux/idr.h>
#include <uapi/drm/drm.h>
#include <drm/drm_prime.h>
struct dma_fence;
struct drm_file;
struct drm_device;
+struct drm_printer;
struct device;
struct file;
/*
* FIXME: Not sure we want to have drm_minor here in the end, but to avoid
* header include loops we need it here for now.
*/
/* Note that the order of this enum is ABI (it determines
* /dev/dri/renderD* numbers).
@@ -434,15 +435,42 @@ int drm_event_reserve_init(struct drm_device *dev,
struct drm_file *file_priv,
struct drm_pending_event *p,
struct drm_event *e);
void drm_event_cancel_free(struct drm_device *dev,
struct drm_pending_event *p);
void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e);
void drm_send_event(struct drm_device *dev, struct drm_pending_event *e);
void drm_send_event_timestamp_locked(struct drm_device *dev,
struct drm_pending_event *e,
ktime_t timestamp);
+
+/**
+ * struct drm_memory_stats - GEM object stats associated
+ * @shared: Total size of GEM objects shared between processes
+ * @private: Total size of GEM objects
+ * @resident: Total size of GEM objects backing pages
+ * @purgeable: Total size of GEM objects that can be purged (resident and not active)
+ * @active: Total size of GEM objects active on one or more engines
+ *
+ * Used by drm_print_memory_stats()
+ */
+struct drm_memory_stats {
+ u64 shared;
+ u64 private;
+ u64 resident;
+ u64 purgeable;
+ u64 active;
+};
+
+enum drm_gem_object_status;
+
+void drm_print_memory_stats(struct drm_printer *p,
+ const struct drm_memory_stats *stats,
+ enum drm_gem_object_status supported_status,
+ const char *region);
+
+void drm_show_memory_stats(struct drm_printer *p, struct drm_file *file);
void drm_show_fdinfo(struct seq_file *m, struct file *f);
struct file *mock_drm_getfile(struct drm_minor *minor, unsigned int flags);
#endif /* _DRM_FILE_H_ */
diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
index b8efd836edef..bbc721870c13 100644
--- a/include/drm/drm_gem.h
+++ b/include/drm/drm_gem.h
@@ -35,20 +35,39 @@
*/
#include <linux/kref.h>
#include <linux/dma-resv.h>
#include <drm/drm_vma_manager.h>
struct iosys_map;
struct drm_gem_object;
+/**
+ * enum drm_gem_object_status - bitmask of object state for fdinfo reporting
+ * @DRM_GEM_OBJECT_RESIDENT: object is resident in memory (ie. not unpinned)
+ * @DRM_GEM_OBJECT_PURGEABLE: object marked as purgeable by userspace
+ *
+ * Bitmask of status used for fdinfo memory stats, see &drm_gem_object_funcs.status
+ * and drm_show_fdinfo(). Note that an object can DRM_GEM_OBJECT_PURGEABLE if
+ * it still active or not resident, in which case drm_show_fdinfo() will not
+ * account for it as purgeable. So drivers do not need to check if the buffer
+ * is idle and resident to return this bit. (Ie. userspace can mark a buffer
+ * as purgeable even while it is still busy on the GPU.. it does not _actually_
+ * become puregeable until it becomes idle. The status gem object func does
+ * not need to consider this.)
+ */
+enum drm_gem_object_status {
+ DRM_GEM_OBJECT_RESIDENT = BIT(0),
+ DRM_GEM_OBJECT_PURGEABLE = BIT(1),
+};
+
/**
* struct drm_gem_object_funcs - GEM object functions
*/
struct drm_gem_object_funcs {
/**
* @free:
*
* Deconstructor for drm_gem_objects.
*
* This callback is mandatory.
@@ -167,20 +186,33 @@ struct drm_gem_object_funcs {
/**
* @evict:
*
* Evicts gem object out from memory. Used by the drm_gem_object_evict()
* helper. Returns 0 on success, -errno otherwise.
*
* This callback is optional.
*/
int (*evict)(struct drm_gem_object *obj);
+ /**
+ * @status:
+ *
+ * The optional status callback can return additional object state
+ * which determines which stats the object is counted against. The
+ * callback is called under table_lock. Racing against object status
+ * change is "harmless", and the callback can expect to not race
+ * against object destruction.
+ *
+ * Called by drm_show_memory_stats().
+ */
+ enum drm_gem_object_status (*status)(struct drm_gem_object *obj);
+
/**
* @vm_ops:
*
* Virtual memory operations used with mmap.
*
* This is optional but necessary for mmap support.
*/
const struct vm_operations_struct *vm_ops;
};
--
2.40.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v5 7/7] drm/doc: Relax fdinfo string constraints
2023-05-24 15:59 [PATCH v5 0/7] drm: fdinfo memory stats Rob Clark
` (2 preceding siblings ...)
2023-05-24 15:59 ` [PATCH v5 5/7] drm: Add fdinfo memory stats Rob Clark
@ 2023-05-24 15:59 ` Rob Clark
2023-05-24 16:10 ` [PATCH v5 0/7] drm: fdinfo memory stats Neil Armstrong
4 siblings, 0 replies; 6+ messages in thread
From: Rob Clark @ 2023-05-24 15:59 UTC (permalink / raw)
To: dri-devel
Cc: freedreno, Daniel Vetter, Tvrtko Ursulin, Boris Brezillon,
Christopher Healy, Emil Velikov, Christian König, Rob Clark,
Tvrtko Ursulin, Dave Airlie, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Jonathan Corbet,
open list:DOCUMENTATION, open list
From: Rob Clark <robdclark@chromium.org>
The restriction about no whitespace, etc, really only applies to the
usage of strings in keys. Values can contain anything (other than
newline).
Signed-off-by: Rob Clark <robdclark@chromium.org>
Acked-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Acked-by: Dave Airlie <airlied@redhat.com>
---
Documentation/gpu/drm-usage-stats.rst | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/Documentation/gpu/drm-usage-stats.rst b/Documentation/gpu/drm-usage-stats.rst
index d012eb56885e..fe35a291ff3e 100644
--- a/Documentation/gpu/drm-usage-stats.rst
+++ b/Documentation/gpu/drm-usage-stats.rst
@@ -17,41 +17,42 @@ wherever possible effort should still be made to standardise as much as
possible.
File format specification
=========================
- File shall contain one key value pair per one line of text.
- Colon character (`:`) must be used to delimit keys and values.
- All keys shall be prefixed with `drm-`.
- Whitespace between the delimiter and first non-whitespace character shall be
ignored when parsing.
-- Neither keys or values are allowed to contain whitespace characters.
+- Keys are not allowed to contain whitespace characters.
- Numerical key value pairs can end with optional unit string.
- Data type of the value is fixed as defined in the specification.
Key types
---------
1. Mandatory, fully standardised.
2. Optional, fully standardised.
3. Driver specific.
Data types
----------
- <uint> - Unsigned integer without defining the maximum value.
-- <str> - String excluding any above defined reserved characters or whitespace.
+- <keystr> - String excluding any above defined reserved characters or whitespace.
+- <valstr> - String.
Mandatory fully standardised keys
---------------------------------
-- drm-driver: <str>
+- drm-driver: <valstr>
String shall contain the name this driver registered as via the respective
`struct drm_driver` data structure.
Optional fully standardised keys
--------------------------------
Identification
^^^^^^^^^^^^^^
@@ -68,62 +69,62 @@ to the in kernel representation of `struct drm_file` instances.
Uniqueness of the value shall be either globally unique, or unique within the
scope of each device, in which case `drm-pdev` shall be present as well.
Userspace should make sure to not double account any usage statistics by using
the above described criteria in order to associate data to individual clients.
Utilization
^^^^^^^^^^^
-- drm-engine-<str>: <uint> ns
+- drm-engine-<keystr>: <uint> ns
GPUs usually contain multiple execution engines. Each shall be given a stable
-and unique name (str), with possible values documented in the driver specific
+and unique name (keystr), with possible values documented in the driver specific
documentation.
Value shall be in specified time units which the respective GPU engine spent
busy executing workloads belonging to this client.
Values are not required to be constantly monotonic if it makes the driver
implementation easier, but are required to catch up with the previously reported
larger value within a reasonable period. Upon observing a value lower than what
was previously read, userspace is expected to stay with that larger previous
value until a monotonic update is seen.
-- drm-engine-capacity-<str>: <uint>
+- drm-engine-capacity-<keystr>: <uint>
Engine identifier string must be the same as the one specified in the
-drm-engine-<str> tag and shall contain a greater than zero number in case the
+drm-engine-<keystr> tag and shall contain a greater than zero number in case the
exported engine corresponds to a group of identical hardware engines.
In the absence of this tag parser shall assume capacity of one. Zero capacity
is not allowed.
-- drm-cycles-<str>: <uint>
+- drm-cycles-<keystr>: <uint>
Engine identifier string must be the same as the one specified in the
-drm-engine-<str> tag and shall contain the number of busy cycles for the given
+drm-engine-<keystr> tag and shall contain the number of busy cycles for the given
engine.
Values are not required to be constantly monotonic if it makes the driver
implementation easier, but are required to catch up with the previously reported
larger value within a reasonable period. Upon observing a value lower than what
was previously read, userspace is expected to stay with that larger previous
value until a monotonic update is seen.
-- drm-maxfreq-<str>: <uint> [Hz|MHz|KHz]
+- drm-maxfreq-<keystr>: <uint> [Hz|MHz|KHz]
Engine identifier string must be the same as the one specified in the
-drm-engine-<str> tag and shall contain the maximum frequency for the given
-engine. Taken together with drm-cycles-<str>, this can be used to calculate
-percentage utilization of the engine, whereas drm-engine-<str> only reflects
+drm-engine-<keystr> tag and shall contain the maximum frequency for the given
+engine. Taken together with drm-cycles-<keystr>, this can be used to calculate
+percentage utilization of the engine, whereas drm-engine-<keystr> only reflects
time active without considering what frequency the engine is operating as a
percentage of it's maximum frequency.
Memory
^^^^^^
- drm-memory-<region>: <uint> [KiB|MiB]
Each possible memory type which can be used to store buffer objects by the
GPU in question shall be given a stable and unique name to be returned as the
--
2.40.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v5 0/7] drm: fdinfo memory stats
2023-05-24 15:59 [PATCH v5 0/7] drm: fdinfo memory stats Rob Clark
` (3 preceding siblings ...)
2023-05-24 15:59 ` [PATCH v5 7/7] drm/doc: Relax fdinfo string constraints Rob Clark
@ 2023-05-24 16:10 ` Neil Armstrong
4 siblings, 0 replies; 6+ messages in thread
From: Neil Armstrong @ 2023-05-24 16:10 UTC (permalink / raw)
To: dri-devel, Rob Clark
Cc: freedreno, Daniel Vetter, Tvrtko Ursulin, Boris Brezillon,
Christopher Healy, Emil Velikov, Christian König, Rob Clark,
Alex Deucher, amd-gfx, Arunpravin Paneer Selvam, Dave Airlie,
Guchun Chen, Jim Cromie, Lijo Lazar, linux-arm-msm, linux-doc,
linux-kernel, Marek Olšák, Mario Limonciello,
Michel Dänzer, Sean Paul, Shashank Sharma,
Srinivasan Shanmugam, YiPeng Chai
Hi,
On Wed, 24 May 2023 08:59:30 -0700, Rob Clark wrote:
> From: Rob Clark <robdclark@chromium.org>
>
> Similar motivation to other similar recent attempt[1]. But with an
> attempt to have some shared code for this. As well as documentation.
>
> It is probably a bit UMA-centric, I guess devices with VRAM might want
> some placement stats as well. But this seems like a reasonable start.
>
> [...]
Thanks, Applied to https://anongit.freedesktop.org/git/drm/drm-misc.git (drm-misc-next)
[1/7] drm/docs: Fix usage stats typos
https://cgit.freedesktop.org/drm/drm-misc/commit/?id=0020582a8afe9a8570f80ec503c59bf049a616de
[2/7] drm: Add common fdinfo helper
https://cgit.freedesktop.org/drm/drm-misc/commit/?id=3f09a0cd4ea3b9d34495450d686227d48e7ec648
[3/7] drm/msm: Switch to fdinfo helper
https://cgit.freedesktop.org/drm/drm-misc/commit/?id=51d86ee5e07ccef85af04ee9850b0baa107999b6
[4/7] drm/amdgpu: Switch to fdinfo helper
https://cgit.freedesktop.org/drm/drm-misc/commit/?id=376c25f8ca47084c4f0aff0f14684780756ccef4
[5/7] drm: Add fdinfo memory stats
https://cgit.freedesktop.org/drm/drm-misc/commit/?id=686b21b5f6ca2f8a716f9a4ade07246dbfb2713e
[6/7] drm/msm: Add memory stats to fdinfo
https://cgit.freedesktop.org/drm/drm-misc/commit/?id=3e9757f5ddb98238226ad68a1609aa313de35adb
[7/7] drm/doc: Relax fdinfo string constraints
https://cgit.freedesktop.org/drm/drm-misc/commit/?id=90d63a150b85fd1debb9c01237fb78faee02746a
--
Neil
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2023-05-24 16:10 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-05-24 15:59 [PATCH v5 0/7] drm: fdinfo memory stats Rob Clark
2023-05-24 15:59 ` [PATCH v5 1/7] drm/docs: Fix usage stats typos Rob Clark
2023-05-24 15:59 ` [PATCH v5 2/7] drm: Add common fdinfo helper Rob Clark
2023-05-24 15:59 ` [PATCH v5 5/7] drm: Add fdinfo memory stats Rob Clark
2023-05-24 15:59 ` [PATCH v5 7/7] drm/doc: Relax fdinfo string constraints Rob Clark
2023-05-24 16:10 ` [PATCH v5 0/7] drm: fdinfo memory stats Neil Armstrong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).