diff options
author | Tejun Heo <tj@kernel.org> | 2011-12-13 18:33:42 -0500 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2011-12-13 18:33:42 -0500 |
commit | 3d3c2379feb177a5fd55bb0ed76776dc9d4f3243 (patch) | |
tree | fafebbef8f0fb5b73ac4db24bff20dcd40b8bf12 /block/elevator.c | |
parent | 47fdd4ca96bf4b28ac4d05d7a6e382df31d3d758 (diff) |
block, cfq: move icq cache management to block core
Let elevators set ->icq_size and ->icq_align in elevator_type and
elv_register() and elv_unregister() respectively create and destroy
kmem_cache for icq.
* elv_register() now can return failure. All callers updated.
* icq caches are automatically named "ELVNAME_io_cq".
* cfq_slab_setup/kill() are collapsed into cfq_init/exit().
* While at it, minor indentation change for iosched_cfq.elevator_name
for consistency.
This will help moving icq management to block core. This doesn't
introduce any functional change.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/elevator.c')
-rw-r--r-- | block/elevator.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/block/elevator.c b/block/elevator.c index c5c6214829cb..cca049fb45c8 100644 --- a/block/elevator.c +++ b/block/elevator.c | |||
@@ -886,15 +886,36 @@ void elv_unregister_queue(struct request_queue *q) | |||
886 | } | 886 | } |
887 | EXPORT_SYMBOL(elv_unregister_queue); | 887 | EXPORT_SYMBOL(elv_unregister_queue); |
888 | 888 | ||
889 | void elv_register(struct elevator_type *e) | 889 | int elv_register(struct elevator_type *e) |
890 | { | 890 | { |
891 | char *def = ""; | 891 | char *def = ""; |
892 | 892 | ||
893 | /* create icq_cache if requested */ | ||
894 | if (e->icq_size) { | ||
895 | if (WARN_ON(e->icq_size < sizeof(struct io_cq)) || | ||
896 | WARN_ON(e->icq_align < __alignof__(struct io_cq))) | ||
897 | return -EINVAL; | ||
898 | |||
899 | snprintf(e->icq_cache_name, sizeof(e->icq_cache_name), | ||
900 | "%s_io_cq", e->elevator_name); | ||
901 | e->icq_cache = kmem_cache_create(e->icq_cache_name, e->icq_size, | ||
902 | e->icq_align, 0, NULL); | ||
903 | if (!e->icq_cache) | ||
904 | return -ENOMEM; | ||
905 | } | ||
906 | |||
907 | /* register, don't allow duplicate names */ | ||
893 | spin_lock(&elv_list_lock); | 908 | spin_lock(&elv_list_lock); |
894 | BUG_ON(elevator_find(e->elevator_name)); | 909 | if (elevator_find(e->elevator_name)) { |
910 | spin_unlock(&elv_list_lock); | ||
911 | if (e->icq_cache) | ||
912 | kmem_cache_destroy(e->icq_cache); | ||
913 | return -EBUSY; | ||
914 | } | ||
895 | list_add_tail(&e->list, &elv_list); | 915 | list_add_tail(&e->list, &elv_list); |
896 | spin_unlock(&elv_list_lock); | 916 | spin_unlock(&elv_list_lock); |
897 | 917 | ||
918 | /* print pretty message */ | ||
898 | if (!strcmp(e->elevator_name, chosen_elevator) || | 919 | if (!strcmp(e->elevator_name, chosen_elevator) || |
899 | (!*chosen_elevator && | 920 | (!*chosen_elevator && |
900 | !strcmp(e->elevator_name, CONFIG_DEFAULT_IOSCHED))) | 921 | !strcmp(e->elevator_name, CONFIG_DEFAULT_IOSCHED))) |
@@ -902,14 +923,26 @@ void elv_register(struct elevator_type *e) | |||
902 | 923 | ||
903 | printk(KERN_INFO "io scheduler %s registered%s\n", e->elevator_name, | 924 | printk(KERN_INFO "io scheduler %s registered%s\n", e->elevator_name, |
904 | def); | 925 | def); |
926 | return 0; | ||
905 | } | 927 | } |
906 | EXPORT_SYMBOL_GPL(elv_register); | 928 | EXPORT_SYMBOL_GPL(elv_register); |
907 | 929 | ||
908 | void elv_unregister(struct elevator_type *e) | 930 | void elv_unregister(struct elevator_type *e) |
909 | { | 931 | { |
932 | /* unregister */ | ||
910 | spin_lock(&elv_list_lock); | 933 | spin_lock(&elv_list_lock); |
911 | list_del_init(&e->list); | 934 | list_del_init(&e->list); |
912 | spin_unlock(&elv_list_lock); | 935 | spin_unlock(&elv_list_lock); |
936 | |||
937 | /* | ||
938 | * Destroy icq_cache if it exists. icq's are RCU managed. Make | ||
939 | * sure all RCU operations are complete before proceeding. | ||
940 | */ | ||
941 | if (e->icq_cache) { | ||
942 | rcu_barrier(); | ||
943 | kmem_cache_destroy(e->icq_cache); | ||
944 | e->icq_cache = NULL; | ||
945 | } | ||
913 | } | 946 | } |
914 | EXPORT_SYMBOL_GPL(elv_unregister); | 947 | EXPORT_SYMBOL_GPL(elv_unregister); |
915 | 948 | ||