Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/xe: Make the gem shrinker drm managed

Make the xe drm shrinker drm managed like many other resources
created at device creation time.

Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Link: https://lore.kernel.org/r/20250508113015.3374-1-thomas.hellstrom@linux.intel.com

+22 -28
+3 -6
drivers/gpu/drm/xe/xe_device.c
··· 402 402 if (xe->unordered_wq) 403 403 destroy_workqueue(xe->unordered_wq); 404 404 405 - if (!IS_ERR_OR_NULL(xe->mem.shrinker)) 406 - xe_shrinker_destroy(xe->mem.shrinker); 407 - 408 405 if (xe->destroy_wq) 409 406 destroy_workqueue(xe->destroy_wq); 410 407 ··· 435 438 if (err) 436 439 goto err; 437 440 438 - xe->mem.shrinker = xe_shrinker_create(xe); 439 - if (IS_ERR(xe->mem.shrinker)) 440 - return ERR_CAST(xe->mem.shrinker); 441 + err = xe_shrinker_create(xe); 442 + if (err) 443 + goto err; 441 444 442 445 xe->info.devid = pdev->device; 443 446 xe->info.revid = pdev->revision;
+18 -19
drivers/gpu/drm/xe/xe_shrinker.c
··· 5 5 6 6 #include <linux/shrinker.h> 7 7 8 + #include <drm/drm_managed.h> 8 9 #include <drm/ttm/ttm_backup.h> 9 10 #include <drm/ttm/ttm_bo.h> 10 11 #include <drm/ttm/ttm_tt.h> ··· 214 213 xe_pm_runtime_put(shrinker->xe); 215 214 } 216 215 216 + static void xe_shrinker_fini(struct drm_device *drm, void *arg) 217 + { 218 + struct xe_shrinker *shrinker = arg; 219 + 220 + xe_assert(shrinker->xe, !shrinker->shrinkable_pages); 221 + xe_assert(shrinker->xe, !shrinker->purgeable_pages); 222 + shrinker_free(shrinker->shrink); 223 + flush_work(&shrinker->pm_worker); 224 + kfree(shrinker); 225 + } 226 + 217 227 /** 218 228 * xe_shrinker_create() - Create an xe per-device shrinker 219 229 * @xe: Pointer to the xe device. 220 230 * 221 - * Returns: A pointer to the created shrinker on success, 222 - * Negative error code on failure. 231 + * Return: %0 on success. Negative error code on failure. 223 232 */ 224 - struct xe_shrinker *xe_shrinker_create(struct xe_device *xe) 233 + int xe_shrinker_create(struct xe_device *xe) 225 234 { 226 235 struct xe_shrinker *shrinker = kzalloc(sizeof(*shrinker), GFP_KERNEL); 227 236 228 237 if (!shrinker) 229 - return ERR_PTR(-ENOMEM); 238 + return -ENOMEM; 230 239 231 240 shrinker->shrink = shrinker_alloc(0, "drm-xe_gem:%s", xe->drm.unique); 232 241 if (!shrinker->shrink) { 233 242 kfree(shrinker); 234 - return ERR_PTR(-ENOMEM); 243 + return -ENOMEM; 235 244 } 236 245 237 246 INIT_WORK(&shrinker->pm_worker, xe_shrinker_pm); ··· 251 240 shrinker->shrink->scan_objects = xe_shrinker_scan; 252 241 shrinker->shrink->private_data = shrinker; 253 242 shrinker_register(shrinker->shrink); 243 + xe->mem.shrinker = shrinker; 254 244 255 - return shrinker; 256 - } 257 - 258 - /** 259 - * xe_shrinker_destroy() - Destroy an xe per-device shrinker 260 - * @shrinker: Pointer to the shrinker to destroy. 261 - */ 262 - void xe_shrinker_destroy(struct xe_shrinker *shrinker) 263 - { 264 - xe_assert(shrinker->xe, !shrinker->shrinkable_pages); 265 - xe_assert(shrinker->xe, !shrinker->purgeable_pages); 266 - shrinker_free(shrinker->shrink); 267 - flush_work(&shrinker->pm_worker); 268 - kfree(shrinker); 245 + return drmm_add_action_or_reset(&xe->drm, xe_shrinker_fini, shrinker); 269 246 }
+1 -3
drivers/gpu/drm/xe/xe_shrinker.h
··· 11 11 12 12 void xe_shrinker_mod_pages(struct xe_shrinker *shrinker, long shrinkable, long purgeable); 13 13 14 - struct xe_shrinker *xe_shrinker_create(struct xe_device *xe); 15 - 16 - void xe_shrinker_destroy(struct xe_shrinker *shrinker); 14 + int xe_shrinker_create(struct xe_device *xe); 17 15 18 16 #endif