aboutsummaryrefslogtreecommitdiffstats
path: root/block/as-iosched.c
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2008-01-29 16:25:18 -0500
committerJens Axboe <jens.axboe@oracle.com>2008-01-30 03:11:10 -0500
commit149a051f82d2b3860fe32fa182dbc83a66274894 (patch)
tree4ca660bb2ee8ac25661a38587d785cd9f78b2125 /block/as-iosched.c
parent5b10ca19ea4859d3884d10a3eb8495de92089792 (diff)
as-iosched: fix double locking bug in as_merged_requests()
If the two requests belong to the same io context, we will attempt to lock the same lock twice. But swapping contexts is pointless in that case, so just check for rioc == nioc before doing the double lock and copy. Tested-by: Olof Johansson <olof@lixom.net> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'block/as-iosched.c')
-rw-r--r--block/as-iosched.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/block/as-iosched.c b/block/as-iosched.c
index b201d16a7102..96036846a001 100644
--- a/block/as-iosched.c
+++ b/block/as-iosched.c
@@ -1275,9 +1275,13 @@ static void as_merged_requests(struct request_queue *q, struct request *req,
1275 * Don't copy here but swap, because when anext is 1275 * Don't copy here but swap, because when anext is
1276 * removed below, it must contain the unused context 1276 * removed below, it must contain the unused context
1277 */ 1277 */
1278 double_spin_lock(&rioc->lock, &nioc->lock, rioc < nioc); 1278 if (rioc != nioc) {
1279 swap_io_context(&rioc, &nioc); 1279 double_spin_lock(&rioc->lock, &nioc->lock,
1280 double_spin_unlock(&rioc->lock, &nioc->lock, rioc < nioc); 1280 rioc < nioc);
1281 swap_io_context(&rioc, &nioc);
1282 double_spin_unlock(&rioc->lock, &nioc->lock,
1283 rioc < nioc);
1284 }
1281 } 1285 }
1282 } 1286 }
1283 1287