diff options
| author | Alan D. Brunelle <Alan.Brunelle@hp.com> | 2010-01-29 03:04:08 -0500 |
|---|---|---|
| committer | Jens Axboe <jens.axboe@oracle.com> | 2010-01-29 03:04:08 -0500 |
| commit | 488991e28e55b4fbca8067edf0259f69d1a6f92c (patch) | |
| tree | fea5e0aca42e338137cc050e66aaeb5f539e3d21 /block | |
| parent | 47483e25205f1f8d79784f0f7c733941bc080ec0 (diff) | |
block: Added in stricter no merge semantics for block I/O
Updated 'nomerges' tunable to accept a value of '2' - indicating that _no_
merges at all are to be attempted (not even the simple one-hit cache).
The following table illustrates the additional benefit - 5 minute runs of
a random I/O load were applied to a dozen devices on a 16-way x86_64 system.
nomerges Throughput %System Improvement (tput / %sys)
-------- ------------ ----------- -------------------------
0 12.45 MB/sec 0.669365609
1 12.50 MB/sec 0.641519199 0.40% / 2.71%
2 12.52 MB/sec 0.639849750 0.56% / 2.96%
Signed-off-by: Alan D. Brunelle <alan.brunelle@hp.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'block')
| -rw-r--r-- | block/blk-sysfs.c | 11 | ||||
| -rw-r--r-- | block/elevator.c | 11 |
2 files changed, 17 insertions, 5 deletions
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index 8606c9543fdd..e85442415db3 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c | |||
| @@ -189,7 +189,8 @@ static ssize_t queue_nonrot_store(struct request_queue *q, const char *page, | |||
| 189 | 189 | ||
| 190 | static ssize_t queue_nomerges_show(struct request_queue *q, char *page) | 190 | static ssize_t queue_nomerges_show(struct request_queue *q, char *page) |
| 191 | { | 191 | { |
| 192 | return queue_var_show(blk_queue_nomerges(q), page); | 192 | return queue_var_show((blk_queue_nomerges(q) << 1) | |
| 193 | blk_queue_noxmerges(q), page); | ||
| 193 | } | 194 | } |
| 194 | 195 | ||
| 195 | static ssize_t queue_nomerges_store(struct request_queue *q, const char *page, | 196 | static ssize_t queue_nomerges_store(struct request_queue *q, const char *page, |
| @@ -199,10 +200,12 @@ static ssize_t queue_nomerges_store(struct request_queue *q, const char *page, | |||
| 199 | ssize_t ret = queue_var_store(&nm, page, count); | 200 | ssize_t ret = queue_var_store(&nm, page, count); |
| 200 | 201 | ||
| 201 | spin_lock_irq(q->queue_lock); | 202 | spin_lock_irq(q->queue_lock); |
| 202 | if (nm) | 203 | queue_flag_clear(QUEUE_FLAG_NOMERGES, q); |
| 204 | queue_flag_clear(QUEUE_FLAG_NOXMERGES, q); | ||
| 205 | if (nm == 2) | ||
| 203 | queue_flag_set(QUEUE_FLAG_NOMERGES, q); | 206 | queue_flag_set(QUEUE_FLAG_NOMERGES, q); |
| 204 | else | 207 | else if (nm) |
| 205 | queue_flag_clear(QUEUE_FLAG_NOMERGES, q); | 208 | queue_flag_set(QUEUE_FLAG_NOXMERGES, q); |
| 206 | spin_unlock_irq(q->queue_lock); | 209 | spin_unlock_irq(q->queue_lock); |
| 207 | 210 | ||
| 208 | return ret; | 211 | return ret; |
diff --git a/block/elevator.c b/block/elevator.c index 9ad5ccc4c5ee..ee3a883840f2 100644 --- a/block/elevator.c +++ b/block/elevator.c | |||
| @@ -474,6 +474,15 @@ int elv_merge(struct request_queue *q, struct request **req, struct bio *bio) | |||
| 474 | int ret; | 474 | int ret; |
| 475 | 475 | ||
| 476 | /* | 476 | /* |
| 477 | * Levels of merges: | ||
| 478 | * nomerges: No merges at all attempted | ||
| 479 | * noxmerges: Only simple one-hit cache try | ||
| 480 | * merges: All merge tries attempted | ||
| 481 | */ | ||
| 482 | if (blk_queue_nomerges(q)) | ||
| 483 | return ELEVATOR_NO_MERGE; | ||
| 484 | |||
| 485 | /* | ||
| 477 | * First try one-hit cache. | 486 | * First try one-hit cache. |
| 478 | */ | 487 | */ |
| 479 | if (q->last_merge) { | 488 | if (q->last_merge) { |
| @@ -484,7 +493,7 @@ int elv_merge(struct request_queue *q, struct request **req, struct bio *bio) | |||
| 484 | } | 493 | } |
| 485 | } | 494 | } |
| 486 | 495 | ||
| 487 | if (blk_queue_nomerges(q)) | 496 | if (blk_queue_noxmerges(q)) |
| 488 | return ELEVATOR_NO_MERGE; | 497 | return ELEVATOR_NO_MERGE; |
| 489 | 498 | ||
| 490 | /* | 499 | /* |
