Commit 292b7f27129272c9ec0ee5fa56abb6f9061b1d83
Committed by
Jens Axboe
1 parent
4e2872d6b0
Exists in
master
and in
20 other branches
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
block/bsg.c
... | ... | @@ -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 |