summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Axboe <axboe@fb.com>2015-06-10 10:01:20 -0400
committerJens Axboe <axboe@fb.com>2015-06-10 10:01:20 -0400
commit0bb979472a7401022109e81dd89d777adea58710 (patch)
tree27cf4730d269d037ad5b0db1f89d5ecf788cb3d0
parentae11f7efda05dc568521924c890c80d0be908d43 (diff)
cfq-iosched: fix the setting of IOPS mode on SSDs
A previous commit wanted to make CFQ default to IOPS mode on non-rotational storage, however it did so when the queue was initialized and the non-rotational flag is only set later on in the probe. Add an elevator hook that gets called off the add_disk() path, at that point we know that feature probing has finished, and we can reliably check for the various flags that drivers can set. Fixes: 41c0126b ("block: Make CFQ default to IOPS mode on SSDs") Tested-by: Romain Francoise <romain@orebokech.com> Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r--block/cfq-iosched.c15
-rw-r--r--block/elevator.c2
-rw-r--r--include/linux/elevator.h2
3 files changed, 18 insertions, 1 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index c808ad87652d..d1d0cb235cd2 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -4508,7 +4508,7 @@ static int cfq_init_queue(struct request_queue *q, struct elevator_type *e)
4508 cfqd->cfq_slice[1] = cfq_slice_sync; 4508 cfqd->cfq_slice[1] = cfq_slice_sync;
4509 cfqd->cfq_target_latency = cfq_target_latency; 4509 cfqd->cfq_target_latency = cfq_target_latency;
4510 cfqd->cfq_slice_async_rq = cfq_slice_async_rq; 4510 cfqd->cfq_slice_async_rq = cfq_slice_async_rq;
4511 cfqd->cfq_slice_idle = blk_queue_nonrot(q) ? 0 : cfq_slice_idle; 4511 cfqd->cfq_slice_idle = cfq_slice_idle;
4512 cfqd->cfq_group_idle = cfq_group_idle; 4512 cfqd->cfq_group_idle = cfq_group_idle;
4513 cfqd->cfq_latency = 1; 4513 cfqd->cfq_latency = 1;
4514 cfqd->hw_tag = -1; 4514 cfqd->hw_tag = -1;
@@ -4525,6 +4525,18 @@ out_free:
4525 return ret; 4525 return ret;
4526} 4526}
4527 4527
4528static void cfq_registered_queue(struct request_queue *q)
4529{
4530 struct elevator_queue *e = q->elevator;
4531 struct cfq_data *cfqd = e->elevator_data;
4532
4533 /*
4534 * Default to IOPS mode with no idling for SSDs
4535 */
4536 if (blk_queue_nonrot(q))
4537 cfqd->cfq_slice_idle = 0;
4538}
4539
4528/* 4540/*
4529 * sysfs parts below --> 4541 * sysfs parts below -->
4530 */ 4542 */
@@ -4640,6 +4652,7 @@ static struct elevator_type iosched_cfq = {
4640 .elevator_may_queue_fn = cfq_may_queue, 4652 .elevator_may_queue_fn = cfq_may_queue,
4641 .elevator_init_fn = cfq_init_queue, 4653 .elevator_init_fn = cfq_init_queue,
4642 .elevator_exit_fn = cfq_exit_queue, 4654 .elevator_exit_fn = cfq_exit_queue,
4655 .elevator_registered_fn = cfq_registered_queue,
4643 }, 4656 },
4644 .icq_size = sizeof(struct cfq_io_cq), 4657 .icq_size = sizeof(struct cfq_io_cq),
4645 .icq_align = __alignof__(struct cfq_io_cq), 4658 .icq_align = __alignof__(struct cfq_io_cq),
diff --git a/block/elevator.c b/block/elevator.c
index 59794d0d38e3..5f0452734a40 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -810,6 +810,8 @@ int elv_register_queue(struct request_queue *q)
810 } 810 }
811 kobject_uevent(&e->kobj, KOBJ_ADD); 811 kobject_uevent(&e->kobj, KOBJ_ADD);
812 e->registered = 1; 812 e->registered = 1;
813 if (e->type->ops.elevator_registered_fn)
814 e->type->ops.elevator_registered_fn(q);
813 } 815 }
814 return error; 816 return error;
815} 817}
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index 45a91474487d..638b324f0291 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -39,6 +39,7 @@ typedef void (elevator_deactivate_req_fn) (struct request_queue *, struct reques
39typedef int (elevator_init_fn) (struct request_queue *, 39typedef int (elevator_init_fn) (struct request_queue *,
40 struct elevator_type *e); 40 struct elevator_type *e);
41typedef void (elevator_exit_fn) (struct elevator_queue *); 41typedef void (elevator_exit_fn) (struct elevator_queue *);
42typedef void (elevator_registered_fn) (struct request_queue *);
42 43
43struct elevator_ops 44struct elevator_ops
44{ 45{
@@ -68,6 +69,7 @@ struct elevator_ops
68 69
69 elevator_init_fn *elevator_init_fn; 70 elevator_init_fn *elevator_init_fn;
70 elevator_exit_fn *elevator_exit_fn; 71 elevator_exit_fn *elevator_exit_fn;
72 elevator_registered_fn *elevator_registered_fn;
71}; 73};
72 74
73#define ELV_NAME_MAX (16) 75#define ELV_NAME_MAX (16)