Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _ELEVATOR_H
0003 #define _ELEVATOR_H
0004 
0005 #include <linux/percpu.h>
0006 #include <linux/hashtable.h>
0007 
0008 struct io_cq;
0009 struct elevator_type;
0010 struct blk_mq_debugfs_attr;
0011 
0012 /*
0013  * Return values from elevator merger
0014  */
0015 enum elv_merge {
0016     ELEVATOR_NO_MERGE   = 0,
0017     ELEVATOR_FRONT_MERGE    = 1,
0018     ELEVATOR_BACK_MERGE = 2,
0019     ELEVATOR_DISCARD_MERGE  = 3,
0020 };
0021 
0022 struct blk_mq_alloc_data;
0023 struct blk_mq_hw_ctx;
0024 
0025 struct elevator_mq_ops {
0026     int (*init_sched)(struct request_queue *, struct elevator_type *);
0027     void (*exit_sched)(struct elevator_queue *);
0028     int (*init_hctx)(struct blk_mq_hw_ctx *, unsigned int);
0029     void (*exit_hctx)(struct blk_mq_hw_ctx *, unsigned int);
0030     void (*depth_updated)(struct blk_mq_hw_ctx *);
0031 
0032     bool (*allow_merge)(struct request_queue *, struct request *, struct bio *);
0033     bool (*bio_merge)(struct request_queue *, struct bio *, unsigned int);
0034     int (*request_merge)(struct request_queue *q, struct request **, struct bio *);
0035     void (*request_merged)(struct request_queue *, struct request *, enum elv_merge);
0036     void (*requests_merged)(struct request_queue *, struct request *, struct request *);
0037     void (*limit_depth)(blk_opf_t, struct blk_mq_alloc_data *);
0038     void (*prepare_request)(struct request *);
0039     void (*finish_request)(struct request *);
0040     void (*insert_requests)(struct blk_mq_hw_ctx *, struct list_head *, bool);
0041     struct request *(*dispatch_request)(struct blk_mq_hw_ctx *);
0042     bool (*has_work)(struct blk_mq_hw_ctx *);
0043     void (*completed_request)(struct request *, u64);
0044     void (*requeue_request)(struct request *);
0045     struct request *(*former_request)(struct request_queue *, struct request *);
0046     struct request *(*next_request)(struct request_queue *, struct request *);
0047     void (*init_icq)(struct io_cq *);
0048     void (*exit_icq)(struct io_cq *);
0049 };
0050 
0051 #define ELV_NAME_MAX    (16)
0052 
0053 struct elv_fs_entry {
0054     struct attribute attr;
0055     ssize_t (*show)(struct elevator_queue *, char *);
0056     ssize_t (*store)(struct elevator_queue *, const char *, size_t);
0057 };
0058 
0059 /*
0060  * identifies an elevator type, such as AS or deadline
0061  */
0062 struct elevator_type
0063 {
0064     /* managed by elevator core */
0065     struct kmem_cache *icq_cache;
0066 
0067     /* fields provided by elevator implementation */
0068     struct elevator_mq_ops ops;
0069 
0070     size_t icq_size;    /* see iocontext.h */
0071     size_t icq_align;   /* ditto */
0072     struct elv_fs_entry *elevator_attrs;
0073     const char *elevator_name;
0074     const char *elevator_alias;
0075     const unsigned int elevator_features;
0076     struct module *elevator_owner;
0077 #ifdef CONFIG_BLK_DEBUG_FS
0078     const struct blk_mq_debugfs_attr *queue_debugfs_attrs;
0079     const struct blk_mq_debugfs_attr *hctx_debugfs_attrs;
0080 #endif
0081 
0082     /* managed by elevator core */
0083     char icq_cache_name[ELV_NAME_MAX + 6];  /* elvname + "_io_cq" */
0084     struct list_head list;
0085 };
0086 
0087 #define ELV_HASH_BITS 6
0088 
0089 void elv_rqhash_del(struct request_queue *q, struct request *rq);
0090 void elv_rqhash_add(struct request_queue *q, struct request *rq);
0091 void elv_rqhash_reposition(struct request_queue *q, struct request *rq);
0092 struct request *elv_rqhash_find(struct request_queue *q, sector_t offset);
0093 
0094 /*
0095  * each queue has an elevator_queue associated with it
0096  */
0097 struct elevator_queue
0098 {
0099     struct elevator_type *type;
0100     void *elevator_data;
0101     struct kobject kobj;
0102     struct mutex sysfs_lock;
0103     unsigned int registered:1;
0104     DECLARE_HASHTABLE(hash, ELV_HASH_BITS);
0105 };
0106 
0107 /*
0108  * block elevator interface
0109  */
0110 extern enum elv_merge elv_merge(struct request_queue *, struct request **,
0111         struct bio *);
0112 extern void elv_merge_requests(struct request_queue *, struct request *,
0113                    struct request *);
0114 extern void elv_merged_request(struct request_queue *, struct request *,
0115         enum elv_merge);
0116 extern bool elv_attempt_insert_merge(struct request_queue *, struct request *,
0117                      struct list_head *);
0118 extern struct request *elv_former_request(struct request_queue *, struct request *);
0119 extern struct request *elv_latter_request(struct request_queue *, struct request *);
0120 void elevator_init_mq(struct request_queue *q);
0121 
0122 /*
0123  * io scheduler registration
0124  */
0125 extern int elv_register(struct elevator_type *);
0126 extern void elv_unregister(struct elevator_type *);
0127 
0128 /*
0129  * io scheduler sysfs switching
0130  */
0131 extern ssize_t elv_iosched_show(struct request_queue *, char *);
0132 extern ssize_t elv_iosched_store(struct request_queue *, const char *, size_t);
0133 
0134 extern bool elv_bio_merge_ok(struct request *, struct bio *);
0135 extern struct elevator_queue *elevator_alloc(struct request_queue *,
0136                     struct elevator_type *);
0137 
0138 /*
0139  * Helper functions.
0140  */
0141 extern struct request *elv_rb_former_request(struct request_queue *, struct request *);
0142 extern struct request *elv_rb_latter_request(struct request_queue *, struct request *);
0143 
0144 /*
0145  * rb support functions.
0146  */
0147 extern void elv_rb_add(struct rb_root *, struct request *);
0148 extern void elv_rb_del(struct rb_root *, struct request *);
0149 extern struct request *elv_rb_find(struct rb_root *, sector_t);
0150 
0151 /*
0152  * Insertion selection
0153  */
0154 #define ELEVATOR_INSERT_FRONT   1
0155 #define ELEVATOR_INSERT_BACK    2
0156 #define ELEVATOR_INSERT_SORT    3
0157 #define ELEVATOR_INSERT_REQUEUE 4
0158 #define ELEVATOR_INSERT_FLUSH   5
0159 #define ELEVATOR_INSERT_SORT_MERGE  6
0160 
0161 #define rb_entry_rq(node)   rb_entry((node), struct request, rb_node)
0162 
0163 #define rq_entry_fifo(ptr)  list_entry((ptr), struct request, queuelist)
0164 #define rq_fifo_clear(rq)   list_del_init(&(rq)->queuelist)
0165 
0166 #endif /* _ELEVATOR_H */