aboutsummaryrefslogtreecommitdiffstats
path: root/block/elevator.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-12-13 18:33:42 -0500
committerJens Axboe <axboe@kernel.dk>2011-12-13 18:33:42 -0500
commit3d3c2379feb177a5fd55bb0ed76776dc9d4f3243 (patch)
treefafebbef8f0fb5b73ac4db24bff20dcd40b8bf12 /block/elevator.c
parent47fdd4ca96bf4b28ac4d05d7a6e382df31d3d758 (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.c37
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}
887EXPORT_SYMBOL(elv_unregister_queue); 887EXPORT_SYMBOL(elv_unregister_queue);
888 888
889void elv_register(struct elevator_type *e) 889int 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}
906EXPORT_SYMBOL_GPL(elv_register); 928EXPORT_SYMBOL_GPL(elv_register);
907 929
908void elv_unregister(struct elevator_type *e) 930void 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}
914EXPORT_SYMBOL_GPL(elv_unregister); 947EXPORT_SYMBOL_GPL(elv_unregister);
915 948