linux/include/linux/elevator.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef _LINUX_ELEVATOR_H
   3#define _LINUX_ELEVATOR_H
   4
   5#include <linux/percpu.h>
   6#include <linux/hashtable.h>
   7
   8#ifdef CONFIG_BLOCK
   9
  10struct io_cq;
  11struct elevator_type;
  12#ifdef CONFIG_BLK_DEBUG_FS
  13struct blk_mq_debugfs_attr;
  14#endif
  15
  16/*
  17 * Return values from elevator merger
  18 */
  19enum elv_merge {
  20        ELEVATOR_NO_MERGE       = 0,
  21        ELEVATOR_FRONT_MERGE    = 1,
  22        ELEVATOR_BACK_MERGE     = 2,
  23        ELEVATOR_DISCARD_MERGE  = 3,
  24};
  25
  26typedef enum elv_merge (elevator_merge_fn) (struct request_queue *, struct request **,
  27                                 struct bio *);
  28
  29typedef void (elevator_merge_req_fn) (struct request_queue *, struct request *, struct request *);
  30
  31typedef void (elevator_merged_fn) (struct request_queue *, struct request *, enum elv_merge);
  32
  33typedef int (elevator_allow_bio_merge_fn) (struct request_queue *,
  34                                           struct request *, struct bio *);
  35
  36typedef int (elevator_allow_rq_merge_fn) (struct request_queue *,
  37                                          struct request *, struct request *);
  38
  39typedef void (elevator_bio_merged_fn) (struct request_queue *,
  40                                                struct request *, struct bio *);
  41
  42typedef int (elevator_dispatch_fn) (struct request_queue *, int);
  43
  44typedef void (elevator_add_req_fn) (struct request_queue *, struct request *);
  45typedef struct request *(elevator_request_list_fn) (struct request_queue *, struct request *);
  46typedef void (elevator_completed_req_fn) (struct request_queue *, struct request *);
  47typedef int (elevator_may_queue_fn) (struct request_queue *, unsigned int);
  48
  49typedef void (elevator_init_icq_fn) (struct io_cq *);
  50typedef void (elevator_exit_icq_fn) (struct io_cq *);
  51typedef int (elevator_set_req_fn) (struct request_queue *, struct request *,
  52                                   struct bio *, gfp_t);
  53typedef void (elevator_put_req_fn) (struct request *);
  54typedef void (elevator_activate_req_fn) (struct request_queue *, struct request *);
  55typedef void (elevator_deactivate_req_fn) (struct request_queue *, struct request *);
  56
  57typedef int (elevator_init_fn) (struct request_queue *,
  58                                struct elevator_type *e);
  59typedef void (elevator_exit_fn) (struct elevator_queue *);
  60typedef void (elevator_registered_fn) (struct request_queue *);
  61
  62struct elevator_ops
  63{
  64        elevator_merge_fn *elevator_merge_fn;
  65        elevator_merged_fn *elevator_merged_fn;
  66        elevator_merge_req_fn *elevator_merge_req_fn;
  67        elevator_allow_bio_merge_fn *elevator_allow_bio_merge_fn;
  68        elevator_allow_rq_merge_fn *elevator_allow_rq_merge_fn;
  69        elevator_bio_merged_fn *elevator_bio_merged_fn;
  70
  71        elevator_dispatch_fn *elevator_dispatch_fn;
  72        elevator_add_req_fn *elevator_add_req_fn;
  73        elevator_activate_req_fn *elevator_activate_req_fn;
  74        elevator_deactivate_req_fn *elevator_deactivate_req_fn;
  75
  76        elevator_completed_req_fn *elevator_completed_req_fn;
  77
  78        elevator_request_list_fn *elevator_former_req_fn;
  79        elevator_request_list_fn *elevator_latter_req_fn;
  80
  81        elevator_init_icq_fn *elevator_init_icq_fn;     /* see iocontext.h */
  82        elevator_exit_icq_fn *elevator_exit_icq_fn;     /* ditto */
  83
  84        elevator_set_req_fn *elevator_set_req_fn;
  85        elevator_put_req_fn *elevator_put_req_fn;
  86
  87        elevator_may_queue_fn *elevator_may_queue_fn;
  88
  89        elevator_init_fn *elevator_init_fn;
  90        elevator_exit_fn *elevator_exit_fn;
  91        elevator_registered_fn *elevator_registered_fn;
  92};
  93
  94struct blk_mq_alloc_data;
  95struct blk_mq_hw_ctx;
  96
  97struct elevator_mq_ops {
  98        int (*init_sched)(struct request_queue *, struct elevator_type *);
  99        void (*exit_sched)(struct elevator_queue *);
 100        int (*init_hctx)(struct blk_mq_hw_ctx *, unsigned int);
 101        void (*exit_hctx)(struct blk_mq_hw_ctx *, unsigned int);
 102
 103        bool (*allow_merge)(struct request_queue *, struct request *, struct bio *);
 104        bool (*bio_merge)(struct blk_mq_hw_ctx *, struct bio *);
 105        int (*request_merge)(struct request_queue *q, struct request **, struct bio *);
 106        void (*request_merged)(struct request_queue *, struct request *, enum elv_merge);
 107        void (*requests_merged)(struct request_queue *, struct request *, struct request *);
 108        void (*limit_depth)(unsigned int, struct blk_mq_alloc_data *);
 109        void (*prepare_request)(struct request *, struct bio *bio);
 110        void (*finish_request)(struct request *);
 111        void (*insert_requests)(struct blk_mq_hw_ctx *, struct list_head *, bool);
 112        struct request *(*dispatch_request)(struct blk_mq_hw_ctx *);
 113        bool (*has_work)(struct blk_mq_hw_ctx *);
 114        void (*completed_request)(struct request *);
 115        void (*started_request)(struct request *);
 116        void (*requeue_request)(struct request *);
 117        struct request *(*former_request)(struct request_queue *, struct request *);
 118        struct request *(*next_request)(struct request_queue *, struct request *);
 119        void (*init_icq)(struct io_cq *);
 120        void (*exit_icq)(struct io_cq *);
 121};
 122
 123#define ELV_NAME_MAX    (16)
 124
 125struct elv_fs_entry {
 126        struct attribute attr;
 127        ssize_t (*show)(struct elevator_queue *, char *);
 128        ssize_t (*store)(struct elevator_queue *, const char *, size_t);
 129};
 130
 131/*
 132 * identifies an elevator type, such as AS or deadline
 133 */
 134struct elevator_type
 135{
 136        /* managed by elevator core */
 137        struct kmem_cache *icq_cache;
 138
 139        /* fields provided by elevator implementation */
 140        union {
 141                struct elevator_ops sq;
 142                struct elevator_mq_ops mq;
 143        } ops;
 144        size_t icq_size;        /* see iocontext.h */
 145        size_t icq_align;       /* ditto */
 146        struct elv_fs_entry *elevator_attrs;
 147        char elevator_name[ELV_NAME_MAX];
 148        const char *elevator_alias;
 149        struct module *elevator_owner;
 150        bool uses_mq;
 151#ifdef CONFIG_BLK_DEBUG_FS
 152        const struct blk_mq_debugfs_attr *queue_debugfs_attrs;
 153        const struct blk_mq_debugfs_attr *hctx_debugfs_attrs;
 154#endif
 155
 156        /* managed by elevator core */
 157        char icq_cache_name[ELV_NAME_MAX + 6];  /* elvname + "_io_cq" */
 158        struct list_head list;
 159};
 160
 161#define ELV_HASH_BITS 6
 162
 163void elv_rqhash_del(struct request_queue *q, struct request *rq);
 164void elv_rqhash_add(struct request_queue *q, struct request *rq);
 165void elv_rqhash_reposition(struct request_queue *q, struct request *rq);
 166struct request *elv_rqhash_find(struct request_queue *q, sector_t offset);
 167
 168/*
 169 * each queue has an elevator_queue associated with it
 170 */
 171struct elevator_queue
 172{
 173        struct elevator_type *type;
 174        void *elevator_data;
 175        struct kobject kobj;
 176        struct mutex sysfs_lock;
 177        unsigned int registered:1;
 178        unsigned int uses_mq:1;
 179        DECLARE_HASHTABLE(hash, ELV_HASH_BITS);
 180};
 181
 182/*
 183 * block elevator interface
 184 */
 185extern void elv_dispatch_sort(struct request_queue *, struct request *);
 186extern void elv_dispatch_add_tail(struct request_queue *, struct request *);
 187extern void elv_add_request(struct request_queue *, struct request *, int);
 188extern void __elv_add_request(struct request_queue *, struct request *, int);
 189extern enum elv_merge elv_merge(struct request_queue *, struct request **,
 190                struct bio *);
 191extern void elv_merge_requests(struct request_queue *, struct request *,
 192                               struct request *);
 193extern void elv_merged_request(struct request_queue *, struct request *,
 194                enum elv_merge);
 195extern void elv_bio_merged(struct request_queue *q, struct request *,
 196                                struct bio *);
 197extern bool elv_attempt_insert_merge(struct request_queue *, struct request *);
 198extern void elv_requeue_request(struct request_queue *, struct request *);
 199extern struct request *elv_former_request(struct request_queue *, struct request *);
 200extern struct request *elv_latter_request(struct request_queue *, struct request *);
 201extern int elv_may_queue(struct request_queue *, unsigned int);
 202extern void elv_completed_request(struct request_queue *, struct request *);
 203extern int elv_set_request(struct request_queue *q, struct request *rq,
 204                           struct bio *bio, gfp_t gfp_mask);
 205extern void elv_put_request(struct request_queue *, struct request *);
 206extern void elv_drain_elevator(struct request_queue *);
 207
 208/*
 209 * io scheduler registration
 210 */
 211extern void __init load_default_elevator_module(void);
 212extern int elv_register(struct elevator_type *);
 213extern void elv_unregister(struct elevator_type *);
 214
 215/*
 216 * io scheduler sysfs switching
 217 */
 218extern ssize_t elv_iosched_show(struct request_queue *, char *);
 219extern ssize_t elv_iosched_store(struct request_queue *, const char *, size_t);
 220
 221extern bool elv_bio_merge_ok(struct request *, struct bio *);
 222extern struct elevator_queue *elevator_alloc(struct request_queue *,
 223                                        struct elevator_type *);
 224
 225/*
 226 * Helper functions.
 227 */
 228extern struct request *elv_rb_former_request(struct request_queue *, struct request *);
 229extern struct request *elv_rb_latter_request(struct request_queue *, struct request *);
 230
 231/*
 232 * rb support functions.
 233 */
 234extern void elv_rb_add(struct rb_root *, struct request *);
 235extern void elv_rb_del(struct rb_root *, struct request *);
 236extern struct request *elv_rb_find(struct rb_root *, sector_t);
 237
 238/*
 239 * Insertion selection
 240 */
 241#define ELEVATOR_INSERT_FRONT   1
 242#define ELEVATOR_INSERT_BACK    2
 243#define ELEVATOR_INSERT_SORT    3
 244#define ELEVATOR_INSERT_REQUEUE 4
 245#define ELEVATOR_INSERT_FLUSH   5
 246#define ELEVATOR_INSERT_SORT_MERGE      6
 247
 248/*
 249 * return values from elevator_may_queue_fn
 250 */
 251enum {
 252        ELV_MQUEUE_MAY,
 253        ELV_MQUEUE_NO,
 254        ELV_MQUEUE_MUST,
 255};
 256
 257#define rq_end_sector(rq)       (blk_rq_pos(rq) + blk_rq_sectors(rq))
 258#define rb_entry_rq(node)       rb_entry((node), struct request, rb_node)
 259
 260#define rq_entry_fifo(ptr)      list_entry((ptr), struct request, queuelist)
 261#define rq_fifo_clear(rq)       list_del_init(&(rq)->queuelist)
 262
 263#else /* CONFIG_BLOCK */
 264
 265static inline void load_default_elevator_module(void) { }
 266
 267#endif /* CONFIG_BLOCK */
 268#endif
 269