Commit 274193224cdabd687d804a26e0150bb20f2dd52c
Committed by
Jens Axboe
1 parent
4a0b75c7d0
Exists in
master
and in
6 other branches
block: recursive merge requests
In my workload, thread 1 accesses a, a+2, ..., thread 2 accesses a+1, a+3,.... When the requests are flushed to queue, a and a+1 are merged to (a, a+1), a+2 and a+3 too to (a+2, a+3), but (a, a+1) and (a+2, a+3) aren't merged. With recursive merge below, the workload throughput gets improved 20% and context switch drops 60%. Signed-off-by: Shaohua Li <shaohua.li@intel.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Showing 1 changed file with 12 additions and 4 deletions Side-by-side Diff
block/elevator.c
... | ... | @@ -515,6 +515,7 @@ |
515 | 515 | struct request *rq) |
516 | 516 | { |
517 | 517 | struct request *__rq; |
518 | + bool ret; | |
518 | 519 | |
519 | 520 | if (blk_queue_nomerges(q)) |
520 | 521 | return false; |
521 | 522 | |
522 | 523 | |
... | ... | @@ -528,14 +529,21 @@ |
528 | 529 | if (blk_queue_noxmerges(q)) |
529 | 530 | return false; |
530 | 531 | |
532 | + ret = false; | |
531 | 533 | /* |
532 | 534 | * See if our hash lookup can find a potential backmerge. |
533 | 535 | */ |
534 | - __rq = elv_rqhash_find(q, blk_rq_pos(rq)); | |
535 | - if (__rq && blk_attempt_req_merge(q, __rq, rq)) | |
536 | - return true; | |
536 | + while (1) { | |
537 | + __rq = elv_rqhash_find(q, blk_rq_pos(rq)); | |
538 | + if (!__rq || !blk_attempt_req_merge(q, __rq, rq)) | |
539 | + break; | |
537 | 540 | |
538 | - return false; | |
541 | + /* The merged request could be merged with others, try again */ | |
542 | + ret = true; | |
543 | + rq = __rq; | |
544 | + } | |
545 | + | |
546 | + return ret; | |
539 | 547 | } |
540 | 548 | |
541 | 549 | void elv_merged_request(struct request_queue *q, struct request *rq, int type) |