Divide all the indices by 64 to save memory. Signed-off-by: Matthew Wilcox <wi...@infradead.org> --- drivers/gpu/drm/drm_drv.c | 49 ++++++++++++++------------------------- 1 file changed, 17 insertions(+), 32 deletions(-)
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 12e5e2be7890..17ed29f49060 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -64,8 +64,7 @@ MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables a debug cat "\t\tBit 8 (0x100) will enable DP messages (displayport code)"); module_param_named(debug, drm_debug, int, 0600); -static DEFINE_SPINLOCK(drm_minor_lock); -static struct idr drm_minors_idr; +static DEFINE_XARRAY_FLAGS(drm_minors, XA_FLAGS_ALLOC | XA_FLAGS_LOCK_IRQ); /* * If the drm core fails to init for whatever reason, @@ -109,7 +108,6 @@ static struct drm_minor **drm_minor_get_slot(struct drm_device *dev, static int drm_minor_alloc(struct drm_device *dev, unsigned int type) { struct drm_minor *minor; - unsigned long flags; int r; minor = kzalloc(sizeof(*minor), GFP_KERNEL); @@ -118,22 +116,12 @@ static int drm_minor_alloc(struct drm_device *dev, unsigned int type) minor->type = type; minor->dev = dev; + minor->index = 64 * type; - idr_preload(GFP_KERNEL); - spin_lock_irqsave(&drm_minor_lock, flags); - r = idr_alloc(&drm_minors_idr, - NULL, - 64 * type, - 64 * (type + 1), - GFP_NOWAIT); - spin_unlock_irqrestore(&drm_minor_lock, flags); - idr_preload_end(); - + r = xa_insert_irq(&drm_minors, minor->index / 64, NULL, GFP_KERNEL); if (r < 0) goto err_free; - minor->index = r; - minor->kdev = drm_sysfs_minor_alloc(minor); if (IS_ERR(minor->kdev)) { r = PTR_ERR(minor->kdev); @@ -144,9 +132,7 @@ static int drm_minor_alloc(struct drm_device *dev, unsigned int type) return 0; err_index: - spin_lock_irqsave(&drm_minor_lock, flags); - idr_remove(&drm_minors_idr, minor->index); - spin_unlock_irqrestore(&drm_minor_lock, flags); + xa_erase_irq(&drm_minors, minor->index / 64); err_free: kfree(minor); return r; @@ -164,9 +150,9 @@ static void drm_minor_free(struct drm_device *dev, unsigned int type) put_device(minor->kdev); - spin_lock_irqsave(&drm_minor_lock, flags); - idr_remove(&drm_minors_idr, minor->index); - spin_unlock_irqrestore(&drm_minor_lock, flags); + xa_lock_irqsave(&drm_minors, flags); + __xa_erase(&drm_minors, minor->index / 64); + xa_unlock_irqrestore(&drm_minors, flags); kfree(minor); *slot = NULL; @@ -195,9 +181,9 @@ static int drm_minor_register(struct drm_device *dev, unsigned int type) goto err_debugfs; /* replace NULL with @minor so lookups will succeed from now on */ - spin_lock_irqsave(&drm_minor_lock, flags); - idr_replace(&drm_minors_idr, minor, minor->index); - spin_unlock_irqrestore(&drm_minor_lock, flags); + xa_lock_irqsave(&drm_minors, flags); + __xa_store(&drm_minors, minor->index / 64, minor, 0); + xa_unlock_irqrestore(&drm_minors, flags); DRM_DEBUG("new minor registered %d\n", minor->index); return 0; @@ -217,9 +203,9 @@ static void drm_minor_unregister(struct drm_device *dev, unsigned int type) return; /* replace @minor with NULL so lookups will fail from now on */ - spin_lock_irqsave(&drm_minor_lock, flags); - idr_replace(&drm_minors_idr, NULL, minor->index); - spin_unlock_irqrestore(&drm_minor_lock, flags); + xa_lock_irqsave(&drm_minors, flags); + __xa_store(&drm_minors, minor->index / 64, NULL, 0); + xa_unlock_irqrestore(&drm_minors, flags); device_del(minor->kdev); dev_set_drvdata(minor->kdev, NULL); /* safety belt */ @@ -240,11 +226,11 @@ struct drm_minor *drm_minor_acquire(unsigned int minor_id) struct drm_minor *minor; unsigned long flags; - spin_lock_irqsave(&drm_minor_lock, flags); - minor = idr_find(&drm_minors_idr, minor_id); + xa_lock_irqsave(&drm_minors, flags); + minor = xa_load(&drm_minors, minor_id / 64); if (minor) drm_dev_get(minor->dev); - spin_unlock_irqrestore(&drm_minor_lock, flags); + xa_unlock_irqrestore(&drm_minors, flags); if (!minor) { return ERR_PTR(-ENODEV); @@ -958,7 +944,7 @@ static void drm_core_exit(void) unregister_chrdev(DRM_MAJOR, "drm"); debugfs_remove(drm_debugfs_root); drm_sysfs_destroy(); - idr_destroy(&drm_minors_idr); + WARN_ON(!xa_empty(&drm_minors)); drm_connector_ida_destroy(); } @@ -967,7 +953,6 @@ static int __init drm_core_init(void) int ret; drm_connector_ida_init(); - idr_init(&drm_minors_idr); ret = drm_sysfs_init(); if (ret < 0) { -- 2.20.1 _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel