|
@@ -100,14 +100,14 @@ static void elevator_put(struct elevator_type *e)
|
|
|
module_put(e->elevator_owner);
|
|
|
}
|
|
|
|
|
|
-static struct elevator_type *elevator_get(const char *name)
|
|
|
+static struct elevator_type *elevator_get(const char *name, bool try_loading)
|
|
|
{
|
|
|
struct elevator_type *e;
|
|
|
|
|
|
spin_lock(&elv_list_lock);
|
|
|
|
|
|
e = elevator_find(name);
|
|
|
- if (!e) {
|
|
|
+ if (!e && try_loading) {
|
|
|
spin_unlock(&elv_list_lock);
|
|
|
request_module("%s-iosched", name);
|
|
|
spin_lock(&elv_list_lock);
|
|
@@ -207,25 +207,30 @@ int elevator_init(struct request_queue *q, char *name)
|
|
|
q->boundary_rq = NULL;
|
|
|
|
|
|
if (name) {
|
|
|
- e = elevator_get(name);
|
|
|
+ e = elevator_get(name, true);
|
|
|
if (!e)
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * Use the default elevator specified by config boot param or
|
|
|
+ * config option. Don't try to load modules as we could be running
|
|
|
+ * off async and request_module() isn't allowed from async.
|
|
|
+ */
|
|
|
if (!e && *chosen_elevator) {
|
|
|
- e = elevator_get(chosen_elevator);
|
|
|
+ e = elevator_get(chosen_elevator, false);
|
|
|
if (!e)
|
|
|
printk(KERN_ERR "I/O scheduler %s not found\n",
|
|
|
chosen_elevator);
|
|
|
}
|
|
|
|
|
|
if (!e) {
|
|
|
- e = elevator_get(CONFIG_DEFAULT_IOSCHED);
|
|
|
+ e = elevator_get(CONFIG_DEFAULT_IOSCHED, false);
|
|
|
if (!e) {
|
|
|
printk(KERN_ERR
|
|
|
"Default I/O scheduler not found. " \
|
|
|
"Using noop.\n");
|
|
|
- e = elevator_get("noop");
|
|
|
+ e = elevator_get("noop", false);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -967,7 +972,7 @@ int elevator_change(struct request_queue *q, const char *name)
|
|
|
return -ENXIO;
|
|
|
|
|
|
strlcpy(elevator_name, name, sizeof(elevator_name));
|
|
|
- e = elevator_get(strstrip(elevator_name));
|
|
|
+ e = elevator_get(strstrip(elevator_name), true);
|
|
|
if (!e) {
|
|
|
printk(KERN_ERR "elevator: type %s not found\n", elevator_name);
|
|
|
return -EINVAL;
|