aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
Diffstat (limited to 'block')
-rw-r--r--block/elevator.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/block/elevator.c b/block/elevator.c
index c2d61d56e0b7..603b2c178740 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -100,14 +100,14 @@ static void elevator_put(struct elevator_type *e)
100 module_put(e->elevator_owner); 100 module_put(e->elevator_owner);
101} 101}
102 102
103static struct elevator_type *elevator_get(const char *name) 103static struct elevator_type *elevator_get(const char *name, bool try_loading)
104{ 104{
105 struct elevator_type *e; 105 struct elevator_type *e;
106 106
107 spin_lock(&elv_list_lock); 107 spin_lock(&elv_list_lock);
108 108
109 e = elevator_find(name); 109 e = elevator_find(name);
110 if (!e) { 110 if (!e && try_loading) {
111 spin_unlock(&elv_list_lock); 111 spin_unlock(&elv_list_lock);
112 request_module("%s-iosched", name); 112 request_module("%s-iosched", name);
113 spin_lock(&elv_list_lock); 113 spin_lock(&elv_list_lock);
@@ -207,25 +207,30 @@ int elevator_init(struct request_queue *q, char *name)
207 q->boundary_rq = NULL; 207 q->boundary_rq = NULL;
208 208
209 if (name) { 209 if (name) {
210 e = elevator_get(name); 210 e = elevator_get(name, true);
211 if (!e) 211 if (!e)
212 return -EINVAL; 212 return -EINVAL;
213 } 213 }
214 214
215 /*
216 * Use the default elevator specified by config boot param or
217 * config option. Don't try to load modules as we could be running
218 * off async and request_module() isn't allowed from async.
219 */
215 if (!e && *chosen_elevator) { 220 if (!e && *chosen_elevator) {
216 e = elevator_get(chosen_elevator); 221 e = elevator_get(chosen_elevator, false);
217 if (!e) 222 if (!e)
218 printk(KERN_ERR "I/O scheduler %s not found\n", 223 printk(KERN_ERR "I/O scheduler %s not found\n",
219 chosen_elevator); 224 chosen_elevator);
220 } 225 }
221 226
222 if (!e) { 227 if (!e) {
223 e = elevator_get(CONFIG_DEFAULT_IOSCHED); 228 e = elevator_get(CONFIG_DEFAULT_IOSCHED, false);
224 if (!e) { 229 if (!e) {
225 printk(KERN_ERR 230 printk(KERN_ERR
226 "Default I/O scheduler not found. " \ 231 "Default I/O scheduler not found. " \
227 "Using noop.\n"); 232 "Using noop.\n");
228 e = elevator_get("noop"); 233 e = elevator_get("noop", false);
229 } 234 }
230 } 235 }
231 236
@@ -967,7 +972,7 @@ int elevator_change(struct request_queue *q, const char *name)
967 return -ENXIO; 972 return -ENXIO;
968 973
969 strlcpy(elevator_name, name, sizeof(elevator_name)); 974 strlcpy(elevator_name, name, sizeof(elevator_name));
970 e = elevator_get(strstrip(elevator_name)); 975 e = elevator_get(strstrip(elevator_name), true);
971 if (!e) { 976 if (!e) {
972 printk(KERN_ERR "elevator: type %s not found\n", elevator_name); 977 printk(KERN_ERR "elevator: type %s not found\n", elevator_name);
973 return -EINVAL; 978 return -EINVAL;