[PATCH] drm/xe: Make the gem shrinker drm managed
Thomas Hellström
thomas.hellstrom at linux.intel.com
Thu May 8 13:29:09 UTC 2025
On Thu, 2025-05-08 at 12:50 +0100, Matthew Auld wrote:
> On 08/05/2025 12:30, Thomas Hellström wrote:
> > Make the xe drm shrinker drm managed like many other resources
> > created at device creation time.
> >
> > Signed-off-by: Thomas Hellström <thomas.hellstrom at linux.intel.com>
> > ---
> > drivers/gpu/drm/xe/xe_device.c | 9 +++-----
> > drivers/gpu/drm/xe/xe_shrinker.c | 37 ++++++++++++++++-----------
> > -----
> > drivers/gpu/drm/xe/xe_shrinker.h | 4 +---
> > 3 files changed, 22 insertions(+), 28 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/xe/xe_device.c
> > b/drivers/gpu/drm/xe/xe_device.c
> > index c02c4c4e9412..399ae5f40321 100644
> > --- a/drivers/gpu/drm/xe/xe_device.c
> > +++ b/drivers/gpu/drm/xe/xe_device.c
> > @@ -402,9 +402,6 @@ static void xe_device_destroy(struct drm_device
> > *dev, void *dummy)
> > if (xe->unordered_wq)
> > destroy_workqueue(xe->unordered_wq);
> >
> > - if (!IS_ERR_OR_NULL(xe->mem.shrinker))
> > - xe_shrinker_destroy(xe->mem.shrinker);
> > -
> > if (xe->destroy_wq)
> > destroy_workqueue(xe->destroy_wq);
> >
> > @@ -438,9 +435,9 @@ struct xe_device *xe_device_create(struct
> > pci_dev *pdev,
> > if (err)
> > goto err;
> >
> > - xe->mem.shrinker = xe_shrinker_create(xe);
> > - if (IS_ERR(xe->mem.shrinker))
> > - return ERR_CAST(xe->mem.shrinker);
> > + err = xe_shrinker_create(xe);
> > + if (err)
> > + goto err;
> >
> > xe->info.devid = pdev->device;
> > xe->info.revid = pdev->revision;
> > diff --git a/drivers/gpu/drm/xe/xe_shrinker.c
> > b/drivers/gpu/drm/xe/xe_shrinker.c
> > index 86d47aaf0358..125c836e0ee4 100644
> > --- a/drivers/gpu/drm/xe/xe_shrinker.c
> > +++ b/drivers/gpu/drm/xe/xe_shrinker.c
> > @@ -5,6 +5,7 @@
> >
> > #include <linux/shrinker.h>
> >
> > +#include <drm/drm_managed.h>
> > #include <drm/ttm/ttm_backup.h>
> > #include <drm/ttm/ttm_bo.h>
> > #include <drm/ttm/ttm_tt.h>
> > @@ -213,24 +214,34 @@ static void xe_shrinker_pm(struct work_struct
> > *work)
> > xe_pm_runtime_put(shrinker->xe);
> > }
> >
> > +static void xe_shrinker_fini(struct drm_device *drm, void *arg)
> > +{
> > + struct xe_shrinker *shrinker = arg;
> > +
> > + xe_assert(shrinker->xe, !shrinker->shrinkable_pages);
> > + xe_assert(shrinker->xe, !shrinker->purgeable_pages);
> > + shrinker_free(shrinker->shrink);
> > + flush_work(&shrinker->pm_worker);
>
> As an aside, would it make sense of us to cut over to async rpm get
> instead of having to do something similar by hand? IIRC it also does
> some more fancy stuff under the hood which might be beneficial.
I wasn't aware of that. I'll take a closer look, but yeah, it sounds
like it makes sense.
Thanks for reviewing.
/Thomas
>
> Reviewed-by: Matthew Auld <matthew.auld at intel.com>
>
> > + kfree(shrinker);
> > +}
> > +
> > /**
> > * xe_shrinker_create() - Create an xe per-device shrinker
> > * @xe: Pointer to the xe device.
> > *
> > - * Returns: A pointer to the created shrinker on success,
> > - * Negative error code on failure.
> > + * Return: %0 on success. Negative error code on failure.
> > */
> > -struct xe_shrinker *xe_shrinker_create(struct xe_device *xe)
> > +int xe_shrinker_create(struct xe_device *xe)
> > {
> > struct xe_shrinker *shrinker = kzalloc(sizeof(*shrinker),
> > GFP_KERNEL);
> >
> > if (!shrinker)
> > - return ERR_PTR(-ENOMEM);
> > + return -ENOMEM;
> >
> > shrinker->shrink = shrinker_alloc(0, "drm-xe_gem:%s", xe-
> > >drm.unique);
> > if (!shrinker->shrink) {
> > kfree(shrinker);
> > - return ERR_PTR(-ENOMEM);
> > + return -ENOMEM;
> > }
> >
> > INIT_WORK(&shrinker->pm_worker, xe_shrinker_pm);
> > @@ -240,19 +251,7 @@ struct xe_shrinker *xe_shrinker_create(struct
> > xe_device *xe)
> > shrinker->shrink->scan_objects = xe_shrinker_scan;
> > shrinker->shrink->private_data = shrinker;
> > shrinker_register(shrinker->shrink);
> > + xe->mem.shrinker = shrinker;
> >
> > - return shrinker;
> > -}
> > -
> > -/**
> > - * xe_shrinker_destroy() - Destroy an xe per-device shrinker
> > - * @shrinker: Pointer to the shrinker to destroy.
> > - */
> > -void xe_shrinker_destroy(struct xe_shrinker *shrinker)
> > -{
> > - xe_assert(shrinker->xe, !shrinker->shrinkable_pages);
> > - xe_assert(shrinker->xe, !shrinker->purgeable_pages);
> > - shrinker_free(shrinker->shrink);
> > - flush_work(&shrinker->pm_worker);
> > - kfree(shrinker);
> > + return drmm_add_action_or_reset(&xe->drm,
> > xe_shrinker_fini, shrinker);
> > }
> > diff --git a/drivers/gpu/drm/xe/xe_shrinker.h
> > b/drivers/gpu/drm/xe/xe_shrinker.h
> > index 28a038f4fcbf..5132ae5192e1 100644
> > --- a/drivers/gpu/drm/xe/xe_shrinker.h
> > +++ b/drivers/gpu/drm/xe/xe_shrinker.h
> > @@ -11,8 +11,6 @@ struct xe_device;
> >
> > void xe_shrinker_mod_pages(struct xe_shrinker *shrinker, long
> > shrinkable, long purgeable);
> >
> > -struct xe_shrinker *xe_shrinker_create(struct xe_device *xe);
> > -
> > -void xe_shrinker_destroy(struct xe_shrinker *shrinker);
> > +int xe_shrinker_create(struct xe_device *xe);
> >
> > #endif
>
More information about the Intel-xe
mailing list