summaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2008-01-29 22:25:18 +0100
committerJens Axboe <jens.axboe@oracle.com>2008-01-30 09:11:10 +0100
commit149a051f82d2b3860fe32fa182dbc83a66274894 (patch)
tree4ca660bb2ee8ac25661a38587d785cd9f78b2125 /block
parent5b10ca19ea4859d3884d10a3eb8495de92089792 (diff)
downloadlinux-3.10-149a051f82d2b3860fe32fa182dbc83a66274894.tar.gz
linux-3.10-149a051f82d2b3860fe32fa182dbc83a66274894.tar.bz2
linux-3.10-149a051f82d2b3860fe32fa182dbc83a66274894.zip
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')
-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 b201d16a710..96036846a00 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,
* Don't copy here but swap, because when anext is
* removed below, it must contain the unused context
*/
- double_spin_lock(&rioc->lock, &nioc->lock, rioc < nioc);
- swap_io_context(&rioc, &nioc);
- double_spin_unlock(&rioc->lock, &nioc->lock, rioc < nioc);
+ if (rioc != nioc) {
+ double_spin_lock(&rioc->lock, &nioc->lock,
+ rioc < nioc);
+ swap_io_context(&rioc, &nioc);
+ double_spin_unlock(&rioc->lock, &nioc->lock,
+ rioc < nioc);
+ }
}
}