Signed-off-by: Matthew Wilcox <willy@xxxxxxxxxxxxx> --- drivers/block/zram/zram_drv.c | 40 +++++++++++++---------------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index e7a5f1d1c314..f7e53a681637 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -36,9 +36,7 @@ #include "zram_drv.h" -static DEFINE_IDR(zram_index_idr); -/* idr index must be protected */ -static DEFINE_MUTEX(zram_index_mutex); +static DEFINE_XARRAY_ALLOC(zram_devs); static int zram_major; static const char *default_compressor = "lzo-rle"; @@ -1901,10 +1899,9 @@ static int zram_add(void) if (!zram) return -ENOMEM; - ret = idr_alloc(&zram_index_idr, zram, 0, 0, GFP_KERNEL); + ret = xa_alloc(&zram_devs, &device_id, zram, xa_limit_32b, GFP_KERNEL); if (ret < 0) goto out_free_dev; - device_id = ret; init_rwsem(&zram->init_lock); #ifdef CONFIG_ZRAM_WRITEBACK @@ -1915,7 +1912,7 @@ static int zram_add(void) pr_err("Error allocating disk queue for device %d\n", device_id); ret = -ENOMEM; - goto out_free_idr; + goto out_remove_dev; } blk_queue_make_request(queue, zram_make_request); @@ -1979,8 +1976,8 @@ static int zram_add(void) out_free_queue: blk_cleanup_queue(queue); -out_free_idr: - idr_remove(&zram_index_idr, device_id); +out_remove_dev: + xa_erase(&zram_devs, device_id); out_free_dev: kfree(zram); return ret; @@ -2034,9 +2031,7 @@ static ssize_t hot_add_show(struct class *class, { int ret; - mutex_lock(&zram_index_mutex); ret = zram_add(); - mutex_unlock(&zram_index_mutex); if (ret < 0) return ret; @@ -2059,18 +2054,15 @@ static ssize_t hot_remove_store(struct class *class, if (dev_id < 0) return -EINVAL; - mutex_lock(&zram_index_mutex); - - zram = idr_find(&zram_index_idr, dev_id); + zram = xa_load(&zram_devs, dev_id); if (zram) { ret = zram_remove(zram); if (!ret) - idr_remove(&zram_index_idr, dev_id); + xa_erase(&zram_devs, dev_id); } else { ret = -ENODEV; } - mutex_unlock(&zram_index_mutex); return ret ? ret : count; } static CLASS_ATTR_WO(hot_remove); @@ -2088,18 +2080,18 @@ static struct class zram_control_class = { .class_groups = zram_control_class_groups, }; -static int zram_remove_cb(int id, void *ptr, void *data) -{ - zram_remove(ptr); - return 0; -} - static void destroy_devices(void) { + struct zram *zram; + unsigned long index; + class_unregister(&zram_control_class); - idr_for_each(&zram_index_idr, &zram_remove_cb, NULL); + xa_for_each(&zram_devs, index, zram) { + zram_remove(zram); + } + xa_destroy(&zram_devs); + zram_debugfs_destroy(); - idr_destroy(&zram_index_idr); unregister_blkdev(zram_major, "zram"); cpuhp_remove_multi_state(CPUHP_ZCOMP_PREPARE); } @@ -2130,9 +2122,7 @@ static int __init zram_init(void) } while (num_devices != 0) { - mutex_lock(&zram_index_mutex); ret = zram_add(); - mutex_unlock(&zram_index_mutex); if (ret < 0) goto out_error; num_devices--; -- 2.20.1