From 5434941fd45d30dadc7e9e1227cf109bb3796d22 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 14 Jun 2021 08:06:18 -0700 Subject: [PATCH] drm/msm: Add debugfs to trigger shrinker Just for the purposes of testing. Write to it the # of objects to scan, read back the # freed. Signed-off-by: Rob Clark Link: https://lore.kernel.org/r/20210614150618.729610-1-robdclark@gmail.com Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_debugfs.c | 28 ++++++++++++++++++++++++++++ drivers/gpu/drm/msm/msm_drv.h | 4 ++++ drivers/gpu/drm/msm/msm_gem_shrinker.c | 18 ++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/drivers/gpu/drm/msm/msm_debugfs.c b/drivers/gpu/drm/msm/msm_debugfs.c index 6be5fdb..09d2d27 100644 --- a/drivers/gpu/drm/msm/msm_debugfs.c +++ b/drivers/gpu/drm/msm/msm_debugfs.c @@ -108,6 +108,31 @@ static const struct file_operations msm_gpu_fops = { .release = msm_gpu_release, }; +static unsigned long last_shrink_freed; + +static int +shrink_get(void *data, u64 *val) +{ + *val = last_shrink_freed; + + return 0; +} + +static int +shrink_set(void *data, u64 val) +{ + struct drm_device *dev = data; + + last_shrink_freed = msm_gem_shrinker_shrink(dev, val); + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(shrink_fops, + shrink_get, shrink_set, + "0x%08llx\n"); + + static int msm_gem_show(struct drm_device *dev, struct seq_file *m) { struct msm_drm_private *priv = dev->dev_private; @@ -229,6 +254,9 @@ void msm_debugfs_init(struct drm_minor *minor) debugfs_create_u32("hangcheck_period_ms", 0600, minor->debugfs_root, &priv->hangcheck_period); + debugfs_create_file("shrink", S_IRWXU, minor->debugfs_root, + dev, &shrink_fops); + if (priv->kms && priv->kms->funcs->debugfs_init) priv->kms->funcs->debugfs_init(priv->kms, minor); } diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 2c84fea..1a48a70 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -299,6 +299,10 @@ bool msm_use_mmu(struct drm_device *dev); int msm_ioctl_gem_submit(struct drm_device *dev, void *data, struct drm_file *file); +#ifdef CONFIG_DEBUG_FS +unsigned long msm_gem_shrinker_shrink(struct drm_device *dev, unsigned long nr_to_scan); +#endif + void msm_gem_shrinker_init(struct drm_device *dev); void msm_gem_shrinker_cleanup(struct drm_device *dev); diff --git a/drivers/gpu/drm/msm/msm_gem_shrinker.c b/drivers/gpu/drm/msm/msm_gem_shrinker.c index 1187ecf..0f1b29e 100644 --- a/drivers/gpu/drm/msm/msm_gem_shrinker.c +++ b/drivers/gpu/drm/msm/msm_gem_shrinker.c @@ -145,6 +145,24 @@ msm_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc) return (freed > 0) ? freed : SHRINK_STOP; } +#ifdef CONFIG_DEBUG_FS +unsigned long +msm_gem_shrinker_shrink(struct drm_device *dev, unsigned long nr_to_scan) +{ + struct msm_drm_private *priv = dev->dev_private; + struct shrink_control sc = { + .nr_to_scan = nr_to_scan, + }; + int ret; + + fs_reclaim_acquire(GFP_KERNEL); + ret = msm_gem_shrinker_scan(&priv->shrinker, &sc); + fs_reclaim_release(GFP_KERNEL); + + return ret; +} +#endif + /* since we don't know any better, lets bail after a few * and if necessary the shrinker will be invoked again. * Seems better than unmapping *everything* -- 2.7.4