aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/elevator.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/elevator.c')
-rw-r--r--drivers/block/elevator.c50
1 files changed, 33 insertions, 17 deletions
diff --git a/drivers/block/elevator.c b/drivers/block/elevator.c
index 55621d5c5774..36f1057084b0 100644
--- a/drivers/block/elevator.c
+++ b/drivers/block/elevator.c
@@ -147,24 +147,17 @@ static void elevator_setup_default(void)
147 struct elevator_type *e; 147 struct elevator_type *e;
148 148
149 /* 149 /*
150 * check if default is set and exists 150 * If default has not been set, use the compiled-in selection.
151 */ 151 */
152 if (chosen_elevator[0] && (e = elevator_get(chosen_elevator))) { 152 if (!chosen_elevator[0])
153 elevator_put(e); 153 strcpy(chosen_elevator, CONFIG_DEFAULT_IOSCHED);
154 return;
155 }
156 154
157#if defined(CONFIG_IOSCHED_AS) 155 /*
158 strcpy(chosen_elevator, "anticipatory"); 156 * If the given scheduler is not available, fall back to no-op.
159#elif defined(CONFIG_IOSCHED_DEADLINE) 157 */
160 strcpy(chosen_elevator, "deadline"); 158 if (!(e = elevator_find(chosen_elevator)))
161#elif defined(CONFIG_IOSCHED_CFQ) 159 strcpy(chosen_elevator, "noop");
162 strcpy(chosen_elevator, "cfq"); 160 elevator_put(e);
163#elif defined(CONFIG_IOSCHED_NOOP)
164 strcpy(chosen_elevator, "noop");
165#else
166#error "You must build at least 1 IO scheduler into the kernel"
167#endif
168} 161}
169 162
170static int __init elevator_setup(char *str) 163static int __init elevator_setup(char *str)
@@ -642,6 +635,27 @@ EXPORT_SYMBOL_GPL(elv_register);
642 635
643void elv_unregister(struct elevator_type *e) 636void elv_unregister(struct elevator_type *e)
644{ 637{
638 struct task_struct *g, *p;
639
640 /*
641 * Iterate every thread in the process to remove the io contexts.
642 */
643 read_lock(&tasklist_lock);
644 do_each_thread(g, p) {
645 struct io_context *ioc = p->io_context;
646 if (ioc && ioc->cic) {
647 ioc->cic->exit(ioc->cic);
648 ioc->cic->dtor(ioc->cic);
649 ioc->cic = NULL;
650 }
651 if (ioc && ioc->aic) {
652 ioc->aic->exit(ioc->aic);
653 ioc->aic->dtor(ioc->aic);
654 ioc->aic = NULL;
655 }
656 } while_each_thread(g, p);
657 read_unlock(&tasklist_lock);
658
645 spin_lock_irq(&elv_list_lock); 659 spin_lock_irq(&elv_list_lock);
646 list_del_init(&e->list); 660 list_del_init(&e->list);
647 spin_unlock_irq(&elv_list_lock); 661 spin_unlock_irq(&elv_list_lock);
@@ -739,8 +753,10 @@ ssize_t elv_iosched_store(request_queue_t *q, const char *name, size_t count)
739 return -EINVAL; 753 return -EINVAL;
740 } 754 }
741 755
742 if (!strcmp(elevator_name, q->elevator->elevator_type->elevator_name)) 756 if (!strcmp(elevator_name, q->elevator->elevator_type->elevator_name)) {
757 elevator_put(e);
743 return count; 758 return count;
759 }
744 760
745 elevator_switch(q, e); 761 elevator_switch(q, e);
746 return count; 762 return count;