diff options
author | Mark Brown <broonie@linaro.org> | 2013-12-08 21:51:13 +0000 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-12-08 21:51:13 +0000 |
commit | 925b33756551cb5304774d2e2b39e26e82308a68 (patch) | |
tree | 92c8b41c6dec82d205a7407916e5461a1d1c8c19 /block | |
parent | dffe2a3eed105c631500778dfaba0998d7bf8512 (diff) | |
parent | 184c20bbc978eb7a2e1d3637b7864208822c7ebc (diff) |
Merge tag 'v3.10.23' into linux-linaro-lsk
This is the 3.10.23 stable release
Diffstat (limited to 'block')
-rw-r--r-- | block/blk-core.c | 10 | ||||
-rw-r--r-- | block/elevator.c | 22 |
2 files changed, 29 insertions, 3 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index 76e0b0d79a1..3d37cdec5c6 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -741,9 +741,17 @@ blk_init_allocated_queue(struct request_queue *q, request_fn_proc *rfn, q->sg_reserved_size = INT_MAX; + /* Protect q->elevator from elevator_change */ + mutex_lock(&q->sysfs_lock); + /* init elevator */ - if (elevator_init(q, NULL)) + if (elevator_init(q, NULL)) { + mutex_unlock(&q->sysfs_lock); return NULL; + } + + mutex_unlock(&q->sysfs_lock); + return q; } EXPORT_SYMBOL(blk_init_allocated_queue); diff --git a/block/elevator.c b/block/elevator.c index 668394d1858..6d765f7e2b2 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -186,6 +186,12 @@ int elevator_init(struct request_queue *q, char *name) struct elevator_type *e = NULL; int err; + /* + * q->sysfs_lock must be held to provide mutual exclusion between + * elevator_switch() and here. + */ + lockdep_assert_held(&q->sysfs_lock); + if (unlikely(q->elevator)) return 0; @@ -959,7 +965,7 @@ fail_init: /* * Switch this queue to the given IO scheduler. */ -int elevator_change(struct request_queue *q, const char *name) +static int __elevator_change(struct request_queue *q, const char *name) { char elevator_name[ELV_NAME_MAX]; struct elevator_type *e; @@ -981,6 +987,18 @@ int elevator_change(struct request_queue *q, const char *name) return elevator_switch(q, e); } + +int elevator_change(struct request_queue *q, const char *name) +{ + int ret; + + /* Protect q->elevator from elevator_init() */ + mutex_lock(&q->sysfs_lock); + ret = __elevator_change(q, name); + mutex_unlock(&q->sysfs_lock); + + return ret; +} EXPORT_SYMBOL(elevator_change); ssize_t elv_iosched_store(struct request_queue *q, const char *name, @@ -991,7 +1009,7 @@ ssize_t elv_iosched_store(struct request_queue *q, const char *name, if (!q->elevator) return count; - ret = elevator_change(q, name); + ret = __elevator_change(q, name); if (!ret) return count; |