From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932603AbbBZOKp (ORCPT ); Thu, 26 Feb 2015 09:10:45 -0500 Received: from mail-pd0-f175.google.com ([209.85.192.175]:43595 "EHLO mail-pd0-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932535AbbBZOKm (ORCPT ); Thu, 26 Feb 2015 09:10:42 -0500 From: Sergey Senozhatsky To: Andrew Morton , Minchan Kim Cc: Jerome Marchand , Nitin Gupta , Sergey Senozhatsky , linux-kernel@vger.kernel.org, Sergey Senozhatsky Subject: [PATCH 2/8] zram: use idr instead of `zram_devices' array Date: Thu, 26 Feb 2015 23:10:37 +0900 Message-Id: <1424959843-20409-3-git-send-email-sergey.senozhatsky@gmail.com> X-Mailer: git-send-email 2.3.1.167.g7f4ba4b In-Reply-To: <1424959843-20409-1-git-send-email-sergey.senozhatsky@gmail.com> References: <1424959843-20409-1-git-send-email-sergey.senozhatsky@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch makes some preparations for dynamic device ADD/REMOVE functionality via /dev/zram-control interface. Remove `zram_devices' array and switch to id-to-pointer translation (idr). idr doesn't bloat zram struct with additional members, f.e. list_head, yet still provides ability to match the device_id with the device pointer. No user-space visible changes. Signed-off-by: Sergey Senozhatsky --- drivers/block/zram/zram_drv.c | 81 ++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 35 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 56c9e21..d5e502b 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -32,12 +32,12 @@ #include #include #include +#include #include "zram_drv.h" -/* Globals */ +static DEFINE_IDR(zram_index_idr); static int zram_major; -static struct zram *zram_devices; static const char *default_compressor = "lzo"; /* Module params (documentation at end) */ @@ -1061,18 +1061,28 @@ static struct attribute_group zram_disk_attr_group = { .attrs = zram_disk_attrs, }; -static int create_device(struct zram *zram, int device_id) +static int zram_add(int device_id) { + struct zram *zram; struct request_queue *queue; int ret = -ENOMEM; + zram = kzalloc(sizeof(struct zram), GFP_KERNEL); + if (!zram) + return ret; + + ret = idr_alloc(&zram_index_idr, zram, device_id, + device_id + 1, GFP_KERNEL); + if (ret < 0) + goto out_free_dev; + init_rwsem(&zram->init_lock); queue = blk_alloc_queue(GFP_KERNEL); if (!queue) { pr_err("Error allocating disk queue for device %d\n", device_id); - goto out; + goto out_free_idr; } blk_queue_make_request(queue, zram_make_request); @@ -1141,34 +1151,42 @@ out_free_disk: put_disk(zram->disk); out_free_queue: blk_cleanup_queue(queue); -out: +out_free_idr: + idr_remove(&zram_index_idr, device_id); +out_free_dev: + kfree(zram); return ret; } -static void destroy_devices(unsigned int nr) +static void zram_remove(struct zram *zram) { - struct zram *zram; - unsigned int i; - - for (i = 0; i < nr; i++) { - zram = &zram_devices[i]; - /* - * Remove sysfs first, so no one will perform a disksize - * store while we destroy the devices - */ - sysfs_remove_group(&disk_to_dev(zram->disk)->kobj, - &zram_disk_attr_group); + /* + * Remove sysfs first, so no one will perform a disksize + * store while we destroy the devices + */ + sysfs_remove_group(&disk_to_dev(zram->disk)->kobj, + &zram_disk_attr_group); - zram_reset_device(zram); + zram_reset_device(zram); + idr_remove(&zram_index_idr, zram->disk->first_minor); + blk_cleanup_queue(zram->disk->queue); + del_gendisk(zram->disk); + put_disk(zram->disk); + kfree(zram); +} - blk_cleanup_queue(zram->disk->queue); - del_gendisk(zram->disk); - put_disk(zram->disk); - } +static int zram_exit_cb(int id, void *ptr, void *data) +{ + zram_remove(ptr); + return 0; +} - kfree(zram_devices); +static void destroy_devices(void) +{ + idr_for_each(&zram_index_idr, &zram_exit_cb, NULL); + idr_destroy(&zram_index_idr); unregister_blkdev(zram_major, "zram"); - pr_info("Destroyed %u device(s)\n", nr); + pr_info("Destroyed device(s)\n"); } static int __init zram_init(void) @@ -1187,16 +1205,9 @@ static int __init zram_init(void) return -EBUSY; } - /* Allocate the device array and initialize each one */ - zram_devices = kzalloc(num_devices * sizeof(struct zram), GFP_KERNEL); - if (!zram_devices) { - unregister_blkdev(zram_major, "zram"); - return -ENOMEM; - } - for (dev_id = 0; dev_id < num_devices; dev_id++) { - ret = create_device(&zram_devices[dev_id], dev_id); - if (ret) + ret = zram_add(dev_id); + if (ret != 0) goto out_error; } @@ -1204,13 +1215,13 @@ static int __init zram_init(void) return 0; out_error: - destroy_devices(dev_id); + destroy_devices(); return ret; } static void __exit zram_exit(void) { - destroy_devices(num_devices); + destroy_devices(); } module_init(zram_init); -- 2.3.1.167.g7f4ba4b