diff options
| author | Jens Axboe <axboe@fb.com> | 2017-01-17 08:03:22 -0500 |
|---|---|---|
| committer | Jens Axboe <axboe@fb.com> | 2017-01-17 12:04:20 -0500 |
| commit | bd166ef183c263c5ced656d49ef19c7da4adc774 (patch) | |
| tree | 449bbd3b4e671b370b96e3846b2281116e7089e9 /include/linux/elevator.h | |
| parent | 2af8cbe30531eca73c8f3ba277f155fc0020b01a (diff) | |
blk-mq-sched: add framework for MQ capable IO schedulers
This adds a set of hooks that intercepts the blk-mq path of
allocating/inserting/issuing/completing requests, allowing
us to develop a scheduler within that framework.
We reuse the existing elevator scheduler API on the registration
side, but augment that with the scheduler flagging support for
the blk-mq interfce, and with a separate set of ops hooks for MQ
devices.
We split driver and scheduler tags, so we can run the scheduling
independently of device queue depth.
Signed-off-by: Jens Axboe <axboe@fb.com>
Reviewed-by: Bart Van Assche <bart.vanassche@sandisk.com>
Reviewed-by: Omar Sandoval <osandov@fb.com>
Diffstat (limited to 'include/linux/elevator.h')
| -rw-r--r-- | include/linux/elevator.h | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/include/linux/elevator.h b/include/linux/elevator.h index 2a9e966eed03..ecb96fd67c6d 100644 --- a/include/linux/elevator.h +++ b/include/linux/elevator.h | |||
| @@ -77,6 +77,34 @@ struct elevator_ops | |||
| 77 | elevator_registered_fn *elevator_registered_fn; | 77 | elevator_registered_fn *elevator_registered_fn; |
| 78 | }; | 78 | }; |
| 79 | 79 | ||
| 80 | struct blk_mq_alloc_data; | ||
| 81 | struct blk_mq_hw_ctx; | ||
| 82 | |||
| 83 | struct elevator_mq_ops { | ||
| 84 | int (*init_sched)(struct request_queue *, struct elevator_type *); | ||
| 85 | void (*exit_sched)(struct elevator_queue *); | ||
| 86 | |||
| 87 | bool (*allow_merge)(struct request_queue *, struct request *, struct bio *); | ||
| 88 | bool (*bio_merge)(struct blk_mq_hw_ctx *, struct bio *); | ||
| 89 | int (*request_merge)(struct request_queue *q, struct request **, struct bio *); | ||
| 90 | void (*request_merged)(struct request_queue *, struct request *, int); | ||
| 91 | void (*requests_merged)(struct request_queue *, struct request *, struct request *); | ||
| 92 | struct request *(*get_request)(struct request_queue *, unsigned int, struct blk_mq_alloc_data *); | ||
| 93 | void (*put_request)(struct request *); | ||
| 94 | void (*insert_requests)(struct blk_mq_hw_ctx *, struct list_head *, bool); | ||
| 95 | void (*dispatch_requests)(struct blk_mq_hw_ctx *, struct list_head *); | ||
| 96 | bool (*has_work)(struct blk_mq_hw_ctx *); | ||
| 97 | void (*completed_request)(struct blk_mq_hw_ctx *, struct request *); | ||
| 98 | void (*started_request)(struct request *); | ||
| 99 | void (*requeue_request)(struct request *); | ||
| 100 | struct request *(*former_request)(struct request_queue *, struct request *); | ||
| 101 | struct request *(*next_request)(struct request_queue *, struct request *); | ||
| 102 | int (*get_rq_priv)(struct request_queue *, struct request *); | ||
| 103 | void (*put_rq_priv)(struct request_queue *, struct request *); | ||
| 104 | void (*init_icq)(struct io_cq *); | ||
| 105 | void (*exit_icq)(struct io_cq *); | ||
| 106 | }; | ||
| 107 | |||
| 80 | #define ELV_NAME_MAX (16) | 108 | #define ELV_NAME_MAX (16) |
| 81 | 109 | ||
| 82 | struct elv_fs_entry { | 110 | struct elv_fs_entry { |
| @@ -96,12 +124,14 @@ struct elevator_type | |||
| 96 | /* fields provided by elevator implementation */ | 124 | /* fields provided by elevator implementation */ |
| 97 | union { | 125 | union { |
| 98 | struct elevator_ops sq; | 126 | struct elevator_ops sq; |
| 127 | struct elevator_mq_ops mq; | ||
| 99 | } ops; | 128 | } ops; |
| 100 | size_t icq_size; /* see iocontext.h */ | 129 | size_t icq_size; /* see iocontext.h */ |
| 101 | size_t icq_align; /* ditto */ | 130 | size_t icq_align; /* ditto */ |
| 102 | struct elv_fs_entry *elevator_attrs; | 131 | struct elv_fs_entry *elevator_attrs; |
| 103 | char elevator_name[ELV_NAME_MAX]; | 132 | char elevator_name[ELV_NAME_MAX]; |
| 104 | struct module *elevator_owner; | 133 | struct module *elevator_owner; |
| 134 | bool uses_mq; | ||
| 105 | 135 | ||
| 106 | /* managed by elevator core */ | 136 | /* managed by elevator core */ |
| 107 | char icq_cache_name[ELV_NAME_MAX + 5]; /* elvname + "_io_cq" */ | 137 | char icq_cache_name[ELV_NAME_MAX + 5]; /* elvname + "_io_cq" */ |
| @@ -125,6 +155,7 @@ struct elevator_queue | |||
| 125 | struct kobject kobj; | 155 | struct kobject kobj; |
| 126 | struct mutex sysfs_lock; | 156 | struct mutex sysfs_lock; |
| 127 | unsigned int registered:1; | 157 | unsigned int registered:1; |
| 158 | unsigned int uses_mq:1; | ||
| 128 | DECLARE_HASHTABLE(hash, ELV_HASH_BITS); | 159 | DECLARE_HASHTABLE(hash, ELV_HASH_BITS); |
| 129 | }; | 160 | }; |
| 130 | 161 | ||
| @@ -141,6 +172,7 @@ extern void elv_merge_requests(struct request_queue *, struct request *, | |||
| 141 | extern void elv_merged_request(struct request_queue *, struct request *, int); | 172 | extern void elv_merged_request(struct request_queue *, struct request *, int); |
| 142 | extern void elv_bio_merged(struct request_queue *q, struct request *, | 173 | extern void elv_bio_merged(struct request_queue *q, struct request *, |
| 143 | struct bio *); | 174 | struct bio *); |
| 175 | extern bool elv_attempt_insert_merge(struct request_queue *, struct request *); | ||
| 144 | extern void elv_requeue_request(struct request_queue *, struct request *); | 176 | extern void elv_requeue_request(struct request_queue *, struct request *); |
| 145 | extern struct request *elv_former_request(struct request_queue *, struct request *); | 177 | extern struct request *elv_former_request(struct request_queue *, struct request *); |
| 146 | extern struct request *elv_latter_request(struct request_queue *, struct request *); | 178 | extern struct request *elv_latter_request(struct request_queue *, struct request *); |
