Commit 292b7f27129272c9ec0ee5fa56abb6f9061b1d83

Authored by FUJITA Tomonori
Committed by Jens Axboe
1 parent 4e2872d6b0

improve bsg device allocation

This patch addresses on two issues on bsg device allocation.

- the current maxium number of bsg devices is 256. It's too small if
we allocate bsg devices to all SCSI devices, transport entities, etc.
This increses the maxium number to 32768 (taken from the sg driver).

- SCSI devices are dynamically added and removed. Currently, bsg can't
handle it well since bsd_device->minor is simply increased.

This is dependent on the patchset that I posted yesterday:

http://marc.info/?l=linux-scsi&m=117440208726755&w=2

Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>

Showing 1 changed file with 41 additions and 8 deletions Side-by-side Diff

... ... @@ -58,6 +58,7 @@
58 58 };
59 59  
60 60 #define BSG_DEFAULT_CMDS 64
  61 +#define BSG_MAX_DEVS 32768
61 62  
62 63 #undef BSG_DEBUG
63 64  
... ... @@ -75,7 +76,7 @@
75 76 #define BSG_MAJOR (240)
76 77  
77 78 static DEFINE_MUTEX(bsg_mutex);
78   -static int bsg_device_nr;
  79 +static int bsg_device_nr, bsg_minor_idx;
79 80  
80 81 #define BSG_LIST_SIZE (8)
81 82 #define bsg_list_idx(minor) ((minor) & (BSG_LIST_SIZE - 1))
82 83  
83 84  
... ... @@ -957,14 +958,15 @@
957 958 class_device_destroy(bsg_class, MKDEV(BSG_MAJOR, bcd->minor));
958 959 bcd->class_dev = NULL;
959 960 list_del_init(&bcd->list);
  961 + bsg_device_nr--;
960 962 mutex_unlock(&bsg_mutex);
961 963 }
962 964  
963 965 int bsg_register_queue(struct request_queue *q, char *name)
964 966 {
965   - struct bsg_class_device *bcd;
  967 + struct bsg_class_device *bcd, *__bcd;
966 968 dev_t dev;
967   - int ret;
  969 + int ret = -EMFILE;
968 970 struct class_device *class_dev = NULL;
969 971  
970 972 /*
971 973  
... ... @@ -978,10 +980,27 @@
978 980 INIT_LIST_HEAD(&bcd->list);
979 981  
980 982 mutex_lock(&bsg_mutex);
981   - dev = MKDEV(BSG_MAJOR, bsg_device_nr);
982   - bcd->minor = bsg_device_nr;
983   - bsg_device_nr++;
  983 + if (bsg_device_nr == BSG_MAX_DEVS) {
  984 + printk(KERN_ERR "bsg: too many bsg devices\n");
  985 + goto err;
  986 + }
  987 +
  988 +retry:
  989 + list_for_each_entry(__bcd, &bsg_class_list, list) {
  990 + if (__bcd->minor == bsg_minor_idx) {
  991 + bsg_minor_idx++;
  992 + if (bsg_minor_idx == BSG_MAX_DEVS)
  993 + bsg_minor_idx = 0;
  994 + goto retry;
  995 + }
  996 + }
  997 +
  998 + bcd->minor = bsg_minor_idx++;
  999 + if (bsg_minor_idx == BSG_MAX_DEVS)
  1000 + bsg_minor_idx = 0;
  1001 +
984 1002 bcd->queue = q;
  1003 + dev = MKDEV(BSG_MAJOR, bcd->minor);
985 1004 class_dev = class_device_create(bsg_class, NULL, dev, bcd->dev, "%s", name);
986 1005 if (IS_ERR(class_dev)) {
987 1006 ret = PTR_ERR(class_dev);
988 1007  
... ... @@ -996,11 +1015,11 @@
996 1015 }
997 1016  
998 1017 list_add_tail(&bcd->list, &bsg_class_list);
  1018 + bsg_device_nr++;
999 1019  
1000 1020 mutex_unlock(&bsg_mutex);
1001 1021 return 0;
1002 1022 err:
1003   - bsg_device_nr--;
1004 1023 if (class_dev)
1005 1024 class_device_destroy(bsg_class, MKDEV(BSG_MAJOR, bcd->minor));
1006 1025 mutex_unlock(&bsg_mutex);
... ... @@ -1030,6 +1049,11 @@
1030 1049 .remove = bsg_remove,
1031 1050 };
1032 1051  
  1052 +static struct cdev bsg_cdev = {
  1053 + .kobj = {.name = "bsg", },
  1054 + .owner = THIS_MODULE,
  1055 +};
  1056 +
1033 1057 static int __init bsg_init(void)
1034 1058 {
1035 1059 int ret, i;
1036 1060  
... ... @@ -1050,10 +1074,19 @@
1050 1074 return PTR_ERR(bsg_class);
1051 1075 }
1052 1076  
1053   - ret = register_chrdev(BSG_MAJOR, "bsg", &bsg_fops);
  1077 + ret = register_chrdev_region(MKDEV(BSG_MAJOR, 0), BSG_MAX_DEVS, "bsg");
1054 1078 if (ret) {
1055 1079 kmem_cache_destroy(bsg_cmd_cachep);
1056 1080 class_destroy(bsg_class);
  1081 + return ret;
  1082 + }
  1083 +
  1084 + cdev_init(&bsg_cdev, &bsg_fops);
  1085 + ret = cdev_add(&bsg_cdev, MKDEV(BSG_MAJOR, 0), BSG_MAX_DEVS);
  1086 + if (ret) {
  1087 + kmem_cache_destroy(bsg_cmd_cachep);
  1088 + class_destroy(bsg_class);
  1089 + unregister_chrdev_region(MKDEV(BSG_MAJOR, 0), BSG_MAX_DEVS);
1057 1090 return ret;
1058 1091 }
1059 1092