[PATCH v3 6/7] drm/drm_file: add display of driver's internal memory size
Rob Clark
robdclark at gmail.com
Mon Jun 24 17:47:28 UTC 2024
On Thu, Jun 6, 2024 at 1:35 AM Tvrtko Ursulin <tursulin at ursulin.net> wrote:
>
>
> On 06/06/2024 02:49, Adrián Larumbe wrote:
>
> > Some drivers must allocate a considerable amount of memory for bookkeeping
> > structures and GPU's MCU-kernel shared communication regions. These are
> > often created as a result of the invocation of the driver's ioctl()
> > interface functions, so it is sensible to consider them as being owned by
> > the render context associated with an open drm file.
> >
> > However, at the moment drm_show_memory_stats only traverses the UM-exposed
> > drm objects for which a handle exists. Private driver objects and memory
> > regions, though connected to a render context, are unaccounted for in their
> > fdinfo numbers.
> >
> > Add a new drm_memory_stats 'internal' memory category.
> >
> > Because deciding what constitutes an 'internal' object and where to find
> > these are driver-dependent, calculation of this size must be done through a
> > driver-provided function pointer, which becomes the third argument of
> > drm_show_memory_stats. Drivers which have no interest in exposing the size
> > of internal memory objects can keep passing NULL for unaltered behaviour.
> >
> > Signed-off-by: Adrián Larumbe <adrian.larumbe at collabora.com>
>
> Please Cc people who were previously involved in defining
> drm-usage-stats.rst. I added Rob, but I am not sure if I forgot someone
> from the top of my head.
>
> Internal as a category sounds potentially useful. One reservation I have
> though is itdoes not necessarily fit with the others but is something
> semantically different from them.
>
> In i915 I had the similar desire to account for internal objects and
> have approached it by similarly tracking them outside the DRM idr but
> counting them under the existing respective categories and memory
> regions. Ie. internal objects can also be purgeable or not, etc, and can
> be backed by either system memory or device local memory.
>
> Advantage is it is more accurate in those aspect and does not require
> adding a new category.
>
> Downside of this is that 'internal' is bunched with the explicit
> userspace objects so perhaps less accurate in this other aspect.
>
> Regards,
>
> Tvrtko
>
> > ---
> > Documentation/gpu/drm-usage-stats.rst | 4 ++++
> > drivers/gpu/drm/drm_file.c | 9 +++++++--
> > drivers/gpu/drm/msm/msm_drv.c | 2 +-
> > drivers/gpu/drm/panfrost/panfrost_drv.c | 2 +-
> > include/drm/drm_file.h | 7 ++++++-
> > 5 files changed, 19 insertions(+), 5 deletions(-)
> >
> > diff --git a/Documentation/gpu/drm-usage-stats.rst b/Documentation/gpu/drm-usage-stats.rst
> > index 6dc299343b48..0da5ebecd232 100644
> > --- a/Documentation/gpu/drm-usage-stats.rst
> > +++ b/Documentation/gpu/drm-usage-stats.rst
> > @@ -157,6 +157,10 @@ The total size of buffers that are purgeable.
> >
> > The total size of buffers that are active on one or more engines.
> >
> > +- drm-internal-<region>: <uint> [KiB|MiB]
> > +
> > +The total size of GEM objects that aren't exposed to user space.
> > +
> > Implementation Details
> > ======================
> >
> > diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
> > index 638ffa4444f5..d1c13eed8d34 100644
> > --- a/drivers/gpu/drm/drm_file.c
> > +++ b/drivers/gpu/drm/drm_file.c
> > @@ -874,9 +874,10 @@ void drm_print_memory_stats(struct drm_printer *p,
> > enum drm_gem_object_status supported_status,
> > const char *region)
> > {
> > - print_size(p, "total", region, stats->private + stats->shared);
> > + print_size(p, "total", region, stats->private + stats->shared + stats->internal);
> > print_size(p, "shared", region, stats->shared);
> > print_size(p, "active", region, stats->active);
> > + print_size(p, "internal", region, stats->internal);
> >
> > if (supported_status & DRM_GEM_OBJECT_RESIDENT)
> > print_size(p, "resident", region, stats->resident);
> > @@ -890,11 +891,12 @@ 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
> > + * @func: driver-specific function pointer to count the size of internal objects
> > *
> > * 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)
> > +void drm_show_memory_stats(struct drm_printer *p, struct drm_file *file, internal_bos func)
> > {
> > struct drm_gem_object *obj;
> > struct drm_memory_stats status = {};
> > @@ -940,6 +942,9 @@ void drm_show_memory_stats(struct drm_printer *p, struct drm_file *file)
> > }
> > spin_unlock(&file->table_lock);
> >
> > + if (func)
> > + func(&status, file);
Seems like it would be simpler to just pass `u64 internal` to
drm_show_memory_stats() instead of a callback.
But I agree with Tvrtko's comment about being somewhat (I think?)
orthogonal to active/resident. I guess somewhere you have a list of
internal BOs?
Perhaps another option is to pass an (optionally NULL) list of BOs to
drm_show_memory_stats() to iterate so that they can be counted as
active/resident/etc? Or yet another alternative, pass an (optionally
NULL) `struct drm_memory_stats *` to initialize status.
BR,
-R
> > +
> > drm_print_memory_stats(p, &status, supported_status, "memory");
> > }
> > EXPORT_SYMBOL(drm_show_memory_stats);
> > diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> > index 9c33f4e3f822..f97d3cdc4f50 100644
> > --- a/drivers/gpu/drm/msm/msm_drv.c
> > +++ b/drivers/gpu/drm/msm/msm_drv.c
> > @@ -880,7 +880,7 @@ static void msm_show_fdinfo(struct drm_printer *p, struct drm_file *file)
> >
> > msm_gpu_show_fdinfo(priv->gpu, file->driver_priv, p);
> >
> > - drm_show_memory_stats(p, file);
> > + drm_show_memory_stats(p, file, NULL);
> > }
> >
> > static const struct file_operations fops = {
> > diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c
> > index ef9f6c0716d5..53640ac44e42 100644
> > --- a/drivers/gpu/drm/panfrost/panfrost_drv.c
> > +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
> > @@ -570,7 +570,7 @@ static void panfrost_show_fdinfo(struct drm_printer *p, struct drm_file *file)
> >
> > panfrost_gpu_show_fdinfo(pfdev, file->driver_priv, p);
> >
> > - drm_show_memory_stats(p, file);
> > + drm_show_memory_stats(p, file, NULL);
> > }
> >
> > static const struct file_operations panfrost_drm_driver_fops = {
> > diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h
> > index ab230d3af138..d71a5ac50ea9 100644
> > --- a/include/drm/drm_file.h
> > +++ b/include/drm/drm_file.h
> > @@ -464,6 +464,7 @@ void drm_send_event_timestamp_locked(struct drm_device *dev,
> > * @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
> > + * @internal: Total size of GEM objects that aren't exposed to user space
> > *
> > * Used by drm_print_memory_stats()
> > */
> > @@ -473,16 +474,20 @@ struct drm_memory_stats {
> > u64 resident;
> > u64 purgeable;
> > u64 active;
> > + u64 internal;
> > };
> >
> > enum drm_gem_object_status;
> >
> > +typedef void (*internal_bos)(struct drm_memory_stats *status,
> > + struct drm_file *file);
> > +
> > 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_memory_stats(struct drm_printer *p, struct drm_file *file, internal_bos func);
> > void drm_show_fdinfo(struct seq_file *m, struct file *f);
> >
> > struct file *mock_drm_getfile(struct drm_minor *minor, unsigned int flags);
More information about the dri-devel
mailing list