aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-10-19 08:33:08 -0400
committerJens Axboe <axboe@kernel.dk>2011-10-19 08:33:08 -0400
commitbd87b5898a72b1aef6acf3705c61c9f6372adf0c (patch)
treea1954f352d16307d0846e42b2246be6b1594fb9b
parentda8303c63b8de73619884382d6e573d44aae0810 (diff)
block: drop @tsk from attempt_plug_merge() and explain sync rules
attempt_plug_merge() accesses elevator without holding queue_lock and may call into ->elevator_bio_merge_fn(). The elvator is guaranteed to be valid because it's accessed iff the plugged list has requests and elevator is never exited with live requests, so as long as the elevator method can deal with unlocked access, this is safe. Explain the sync rules around attempt_plug_merge() and drop the unnecessary @tsk parameter. This patch doesn't introduce any functional change. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--block/blk-core.c28
-rw-r--r--include/linux/elevator.h6
2 files changed, 27 insertions, 7 deletions
diff --git a/block/blk-core.c b/block/blk-core.c
index 3508751c779a..034cbb2024f0 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1203,18 +1203,32 @@ static bool bio_attempt_front_merge(struct request_queue *q,
1203 return true; 1203 return true;
1204} 1204}
1205 1205
1206/* 1206/**
1207 * Attempts to merge with the plugged list in the current process. Returns 1207 * attempt_plug_merge - try to merge with %current's plugged list
1208 * true if merge was successful, otherwise false. 1208 * @q: request_queue new bio is being queued at
1209 * @bio: new bio being queued
1210 * @request_count: out parameter for number of traversed plugged requests
1211 *
1212 * Determine whether @bio being queued on @q can be merged with a request
1213 * on %current's plugged list. Returns %true if merge was successful,
1214 * otherwise %false.
1215 *
1216 * This function is called without @q->queue_lock; however, elevator is
1217 * accessed iff there already are requests on the plugged list which in
1218 * turn guarantees validity of the elevator.
1219 *
1220 * Note that, on successful merge, elevator operation
1221 * elevator_bio_merged_fn() will be called without queue lock. Elevator
1222 * must be ready for this.
1209 */ 1223 */
1210static bool attempt_plug_merge(struct task_struct *tsk, struct request_queue *q, 1224static bool attempt_plug_merge(struct request_queue *q, struct bio *bio,
1211 struct bio *bio, unsigned int *request_count) 1225 unsigned int *request_count)
1212{ 1226{
1213 struct blk_plug *plug; 1227 struct blk_plug *plug;
1214 struct request *rq; 1228 struct request *rq;
1215 bool ret = false; 1229 bool ret = false;
1216 1230
1217 plug = tsk->plug; 1231 plug = current->plug;
1218 if (!plug) 1232 if (!plug)
1219 goto out; 1233 goto out;
1220 *request_count = 0; 1234 *request_count = 0;
@@ -1282,7 +1296,7 @@ void blk_queue_bio(struct request_queue *q, struct bio *bio)
1282 * Check if we can merge with the plugged list before grabbing 1296 * Check if we can merge with the plugged list before grabbing
1283 * any locks. 1297 * any locks.
1284 */ 1298 */
1285 if (attempt_plug_merge(current, q, bio, &request_count)) 1299 if (attempt_plug_merge(q, bio, &request_count))
1286 return; 1300 return;
1287 1301
1288 spin_lock_irq(q->queue_lock); 1302 spin_lock_irq(q->queue_lock);
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index d800d5142184..1d0f7a2ff73b 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -38,6 +38,12 @@ struct elevator_ops
38 elevator_merged_fn *elevator_merged_fn; 38 elevator_merged_fn *elevator_merged_fn;
39 elevator_merge_req_fn *elevator_merge_req_fn; 39 elevator_merge_req_fn *elevator_merge_req_fn;
40 elevator_allow_merge_fn *elevator_allow_merge_fn; 40 elevator_allow_merge_fn *elevator_allow_merge_fn;
41
42 /*
43 * Used for both plugged list and elevator merging and in the
44 * former case called without queue_lock. Read comment on top of
45 * attempt_plug_merge() for details.
46 */
41 elevator_bio_merged_fn *elevator_bio_merged_fn; 47 elevator_bio_merged_fn *elevator_bio_merged_fn;
42 48
43 elevator_dispatch_fn *elevator_dispatch_fn; 49 elevator_dispatch_fn *elevator_dispatch_fn;