aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/blk-core.c19
-rw-r--r--block/cfq-iosched.c15
-rw-r--r--include/linux/elevator.h6
3 files changed, 13 insertions, 27 deletions
diff --git a/block/blk-core.c b/block/blk-core.c
index fa697bf691eb..3a78b00edd71 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1212,7 +1212,6 @@ static bool bio_attempt_back_merge(struct request_queue *q, struct request *req,
1212 req->ioprio = ioprio_best(req->ioprio, bio_prio(bio)); 1212 req->ioprio = ioprio_best(req->ioprio, bio_prio(bio));
1213 1213
1214 drive_stat_acct(req, 0); 1214 drive_stat_acct(req, 0);
1215 elv_bio_merged(q, req, bio);
1216 return true; 1215 return true;
1217} 1216}
1218 1217
@@ -1243,7 +1242,6 @@ static bool bio_attempt_front_merge(struct request_queue *q,
1243 req->ioprio = ioprio_best(req->ioprio, bio_prio(bio)); 1242 req->ioprio = ioprio_best(req->ioprio, bio_prio(bio));
1244 1243
1245 drive_stat_acct(req, 0); 1244 drive_stat_acct(req, 0);
1246 elv_bio_merged(q, req, bio);
1247 return true; 1245 return true;
1248} 1246}
1249 1247
@@ -1257,13 +1255,12 @@ static bool bio_attempt_front_merge(struct request_queue *q,
1257 * on %current's plugged list. Returns %true if merge was successful, 1255 * on %current's plugged list. Returns %true if merge was successful,
1258 * otherwise %false. 1256 * otherwise %false.
1259 * 1257 *
1260 * This function is called without @q->queue_lock; however, elevator is 1258 * Plugging coalesces IOs from the same issuer for the same purpose without
1261 * accessed iff there already are requests on the plugged list which in 1259 * going through @q->queue_lock. As such it's more of an issuing mechanism
1262 * turn guarantees validity of the elevator. 1260 * than scheduling, and the request, while may have elvpriv data, is not
1263 * 1261 * added on the elevator at this point. In addition, we don't have
1264 * Note that, on successful merge, elevator operation 1262 * reliable access to the elevator outside queue lock. Only check basic
1265 * elevator_bio_merged_fn() will be called without queue lock. Elevator 1263 * merging parameters without querying the elevator.
1266 * must be ready for this.
1267 */ 1264 */
1268static bool attempt_plug_merge(struct request_queue *q, struct bio *bio, 1265static bool attempt_plug_merge(struct request_queue *q, struct bio *bio,
1269 unsigned int *request_count) 1266 unsigned int *request_count)
@@ -1282,7 +1279,7 @@ static bool attempt_plug_merge(struct request_queue *q, struct bio *bio,
1282 1279
1283 (*request_count)++; 1280 (*request_count)++;
1284 1281
1285 if (rq->q != q || !elv_rq_merge_ok(rq, bio)) 1282 if (rq->q != q || !blk_rq_merge_ok(rq, bio))
1286 continue; 1283 continue;
1287 1284
1288 el_ret = blk_try_merge(rq, bio); 1285 el_ret = blk_try_merge(rq, bio);
@@ -1347,12 +1344,14 @@ void blk_queue_bio(struct request_queue *q, struct bio *bio)
1347 el_ret = elv_merge(q, &req, bio); 1344 el_ret = elv_merge(q, &req, bio);
1348 if (el_ret == ELEVATOR_BACK_MERGE) { 1345 if (el_ret == ELEVATOR_BACK_MERGE) {
1349 if (bio_attempt_back_merge(q, req, bio)) { 1346 if (bio_attempt_back_merge(q, req, bio)) {
1347 elv_bio_merged(q, req, bio);
1350 if (!attempt_back_merge(q, req)) 1348 if (!attempt_back_merge(q, req))
1351 elv_merged_request(q, req, el_ret); 1349 elv_merged_request(q, req, el_ret);
1352 goto out_unlock; 1350 goto out_unlock;
1353 } 1351 }
1354 } else if (el_ret == ELEVATOR_FRONT_MERGE) { 1352 } else if (el_ret == ELEVATOR_FRONT_MERGE) {
1355 if (bio_attempt_front_merge(q, req, bio)) { 1353 if (bio_attempt_front_merge(q, req, bio)) {
1354 elv_bio_merged(q, req, bio);
1356 if (!attempt_front_merge(q, req)) 1355 if (!attempt_front_merge(q, req))
1357 elv_merged_request(q, req, el_ret); 1356 elv_merged_request(q, req, el_ret);
1358 goto out_unlock; 1357 goto out_unlock;
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 5684df6848bc..d0ba50533668 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -1699,18 +1699,11 @@ static int cfq_allow_merge(struct request_queue *q, struct request *rq,
1699 1699
1700 /* 1700 /*
1701 * Lookup the cfqq that this bio will be queued with and allow 1701 * Lookup the cfqq that this bio will be queued with and allow
1702 * merge only if rq is queued there. This function can be called 1702 * merge only if rq is queued there.
1703 * from plug merge without queue_lock. In such cases, ioc of @rq
1704 * and %current are guaranteed to be equal. Avoid lookup which
1705 * requires queue_lock by using @rq's cic.
1706 */ 1703 */
1707 if (current->io_context == RQ_CIC(rq)->icq.ioc) { 1704 cic = cfq_cic_lookup(cfqd, current->io_context);
1708 cic = RQ_CIC(rq); 1705 if (!cic)
1709 } else { 1706 return false;
1710 cic = cfq_cic_lookup(cfqd, current->io_context);
1711 if (!cic)
1712 return false;
1713 }
1714 1707
1715 cfqq = cic_to_cfqq(cic, cfq_bio_sync(bio)); 1708 cfqq = cic_to_cfqq(cic, cfq_bio_sync(bio));
1716 return cfqq == RQ_CFQQ(rq); 1709 return cfqq == RQ_CFQQ(rq);
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index d6dfb65c8885..7d4e0356f329 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -42,12 +42,6 @@ struct elevator_ops
42 elevator_merged_fn *elevator_merged_fn; 42 elevator_merged_fn *elevator_merged_fn;
43 elevator_merge_req_fn *elevator_merge_req_fn; 43 elevator_merge_req_fn *elevator_merge_req_fn;
44 elevator_allow_merge_fn *elevator_allow_merge_fn; 44 elevator_allow_merge_fn *elevator_allow_merge_fn;
45
46 /*
47 * Used for both plugged list and elevator merging and in the
48 * former case called without queue_lock. Read comment on top of
49 * attempt_plug_merge() for details.
50 */
51 elevator_bio_merged_fn *elevator_bio_merged_fn; 45 elevator_bio_merged_fn *elevator_bio_merged_fn;
52 46
53 elevator_dispatch_fn *elevator_dispatch_fn; 47 elevator_dispatch_fn *elevator_dispatch_fn;