On Fri, Sep 29, 2023 at 11:16 AM Adrián Larumbe <adrian.larumbe@xxxxxxxxxxxxx> wrote: > > Some BO's might be mapped onto physical memory chunkwise and on demand, > like Panfrost's tiler heap. In this case, even though the > drm_gem_shmem_object page array might already be allocated, only a very > small fraction of the BO is currently backed by system memory, but > drm_show_memory_stats will then proceed to add its entire virtual size to > the file's total resident size regardless. > > This led to very unrealistic RSS sizes being reckoned for Panfrost, where > said tiler heap buffer is initially allocated with a virtual size of 128 > MiB, but only a small part of it will eventually be backed by system memory > after successive GPU page faults. > > Provide a new DRM object generic function that would allow drivers to > return a more accurate RSS and purgeable sizes for their BOs. > > Signed-off-by: Adrián Larumbe <adrian.larumbe@xxxxxxxxxxxxx> > Reviewed-by: Boris Brezillon <boris.brezillon@xxxxxxxxxxxxx> > Reviewed-by: Steven Price <steven.price@xxxxxxx> > Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@xxxxxxxxxxxxx> Reviewed-by: Rob Clark <robdclark@xxxxxxxxx> > --- > drivers/gpu/drm/drm_file.c | 8 +++++--- > include/drm/drm_gem.h | 9 +++++++++ > 2 files changed, 14 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c > index 883d83bc0e3d..9a1bd8d0d785 100644 > --- a/drivers/gpu/drm/drm_file.c > +++ b/drivers/gpu/drm/drm_file.c > @@ -930,6 +930,8 @@ void drm_show_memory_stats(struct drm_printer *p, struct drm_file *file) > spin_lock(&file->table_lock); > idr_for_each_entry (&file->object_idr, obj, id) { > enum drm_gem_object_status s = 0; > + size_t add_size = (obj->funcs && obj->funcs->rss) ? > + obj->funcs->rss(obj) : obj->size; > > if (obj->funcs && obj->funcs->status) { > s = obj->funcs->status(obj); > @@ -944,7 +946,7 @@ void drm_show_memory_stats(struct drm_printer *p, struct drm_file *file) > } > > if (s & DRM_GEM_OBJECT_RESIDENT) { > - status.resident += obj->size; > + status.resident += add_size; > } else { > /* If already purged or not yet backed by pages, don't > * count it as purgeable: > @@ -953,14 +955,14 @@ void drm_show_memory_stats(struct drm_printer *p, struct drm_file *file) > } > > if (!dma_resv_test_signaled(obj->resv, dma_resv_usage_rw(true))) { > - status.active += obj->size; > + status.active += add_size; > > /* If still active, don't count as purgeable: */ > s &= ~DRM_GEM_OBJECT_PURGEABLE; > } > > if (s & DRM_GEM_OBJECT_PURGEABLE) > - status.purgeable += obj->size; > + status.purgeable += add_size; > } > spin_unlock(&file->table_lock); > > diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h > index bc9f6aa2f3fe..16364487fde9 100644 > --- a/include/drm/drm_gem.h > +++ b/include/drm/drm_gem.h > @@ -208,6 +208,15 @@ struct drm_gem_object_funcs { > */ > enum drm_gem_object_status (*status)(struct drm_gem_object *obj); > > + /** > + * @rss: > + * > + * Return resident size of the object in physical memory. > + * > + * Called by drm_show_memory_stats(). > + */ > + size_t (*rss)(struct drm_gem_object *obj); > + > /** > * @vm_ops: > * > -- > 2.42.0 >