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 | /* |