• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <linux/android_kabi.h>
8 
9 #ifdef CONFIG_BLOCK
10 
11 struct io_cq;
12 struct elevator_type;
13 #ifdef CONFIG_BLK_DEBUG_FS
14 struct blk_mq_debugfs_attr;
15 #endif
16 
17 /*
18  * Return values from elevator merger
19  */
20 enum elv_merge {
21 	ELEVATOR_NO_MERGE	= 0,
22 	ELEVATOR_FRONT_MERGE	= 1,
23 	ELEVATOR_BACK_MERGE	= 2,
24 	ELEVATOR_DISCARD_MERGE	= 3,
25 };
26 
27 struct blk_mq_alloc_data;
28 struct blk_mq_hw_ctx;
29 
30 struct elevator_mq_ops {
31 	int (*init_sched)(struct request_queue *, struct elevator_type *);
32 	void (*exit_sched)(struct elevator_queue *);
33 	int (*init_hctx)(struct blk_mq_hw_ctx *, unsigned int);
34 	void (*exit_hctx)(struct blk_mq_hw_ctx *, unsigned int);
35 	void (*depth_updated)(struct blk_mq_hw_ctx *);
36 
37 	bool (*allow_merge)(struct request_queue *, struct request *, struct bio *);
38 	bool (*bio_merge)(struct request_queue *, struct bio *, unsigned int);
39 	int (*request_merge)(struct request_queue *q, struct request **, struct bio *);
40 	void (*request_merged)(struct request_queue *, struct request *, enum elv_merge);
41 	void (*requests_merged)(struct request_queue *, struct request *, struct request *);
42 	void (*limit_depth)(unsigned int, struct blk_mq_alloc_data *);
43 	void (*prepare_request)(struct request *);
44 	void (*finish_request)(struct request *);
45 	void (*insert_requests)(struct blk_mq_hw_ctx *, struct list_head *, bool);
46 	struct request *(*dispatch_request)(struct blk_mq_hw_ctx *);
47 	bool (*has_work)(struct blk_mq_hw_ctx *);
48 	void (*completed_request)(struct request *, u64);
49 	void (*requeue_request)(struct request *);
50 	struct request *(*former_request)(struct request_queue *, struct request *);
51 	struct request *(*next_request)(struct request_queue *, struct request *);
52 	void (*init_icq)(struct io_cq *);
53 	void (*exit_icq)(struct io_cq *);
54 
55 	ANDROID_KABI_RESERVE(1);
56 	ANDROID_KABI_RESERVE(2);
57 	ANDROID_KABI_RESERVE(3);
58 	ANDROID_KABI_RESERVE(4);
59 };
60 
61 #define ELV_NAME_MAX	(16)
62 
63 struct elv_fs_entry {
64 	struct attribute attr;
65 	ssize_t (*show)(struct elevator_queue *, char *);
66 	ssize_t (*store)(struct elevator_queue *, const char *, size_t);
67 };
68 
69 /*
70  * identifies an elevator type, such as AS or deadline
71  */
72 struct elevator_type
73 {
74 	/* managed by elevator core */
75 	struct kmem_cache *icq_cache;
76 
77 	/* fields provided by elevator implementation */
78 	struct elevator_mq_ops ops;
79 
80 	size_t icq_size;	/* see iocontext.h */
81 	size_t icq_align;	/* ditto */
82 	struct elv_fs_entry *elevator_attrs;
83 	const char *elevator_name;
84 	const char *elevator_alias;
85 	const unsigned int elevator_features;
86 	struct module *elevator_owner;
87 #ifdef CONFIG_BLK_DEBUG_FS
88 	const struct blk_mq_debugfs_attr *queue_debugfs_attrs;
89 	const struct blk_mq_debugfs_attr *hctx_debugfs_attrs;
90 #endif
91 
92 	/* managed by elevator core */
93 	char icq_cache_name[ELV_NAME_MAX + 6];	/* elvname + "_io_cq" */
94 	struct list_head list;
95 
96 	ANDROID_KABI_RESERVE(1);
97 	ANDROID_KABI_RESERVE(2);
98 };
99 
100 #define ELV_HASH_BITS 6
101 
102 void elv_rqhash_del(struct request_queue *q, struct request *rq);
103 void elv_rqhash_add(struct request_queue *q, struct request *rq);
104 void elv_rqhash_reposition(struct request_queue *q, struct request *rq);
105 struct request *elv_rqhash_find(struct request_queue *q, sector_t offset);
106 
107 /*
108  * each queue has an elevator_queue associated with it
109  */
110 struct elevator_queue
111 {
112 	struct elevator_type *type;
113 	void *elevator_data;
114 	struct kobject kobj;
115 	struct mutex sysfs_lock;
116 	unsigned int registered:1;
117 	DECLARE_HASHTABLE(hash, ELV_HASH_BITS);
118 };
119 
120 /*
121  * block elevator interface
122  */
123 extern enum elv_merge elv_merge(struct request_queue *, struct request **,
124 		struct bio *);
125 extern void elv_merge_requests(struct request_queue *, struct request *,
126 			       struct request *);
127 extern void elv_merged_request(struct request_queue *, struct request *,
128 		enum elv_merge);
129 extern bool elv_attempt_insert_merge(struct request_queue *, struct request *);
130 extern struct request *elv_former_request(struct request_queue *, struct request *);
131 extern struct request *elv_latter_request(struct request_queue *, struct request *);
132 
133 /*
134  * io scheduler registration
135  */
136 extern int elv_register(struct elevator_type *);
137 extern void elv_unregister(struct elevator_type *);
138 
139 /*
140  * io scheduler sysfs switching
141  */
142 extern ssize_t elv_iosched_show(struct request_queue *, char *);
143 extern ssize_t elv_iosched_store(struct request_queue *, const char *, size_t);
144 
145 extern bool elv_bio_merge_ok(struct request *, struct bio *);
146 extern struct elevator_queue *elevator_alloc(struct request_queue *,
147 					struct elevator_type *);
148 
149 /*
150  * Helper functions.
151  */
152 extern struct request *elv_rb_former_request(struct request_queue *, struct request *);
153 extern struct request *elv_rb_latter_request(struct request_queue *, struct request *);
154 
155 /*
156  * rb support functions.
157  */
158 extern void elv_rb_add(struct rb_root *, struct request *);
159 extern void elv_rb_del(struct rb_root *, struct request *);
160 extern struct request *elv_rb_find(struct rb_root *, sector_t);
161 
162 /*
163  * Insertion selection
164  */
165 #define ELEVATOR_INSERT_FRONT	1
166 #define ELEVATOR_INSERT_BACK	2
167 #define ELEVATOR_INSERT_SORT	3
168 #define ELEVATOR_INSERT_REQUEUE	4
169 #define ELEVATOR_INSERT_FLUSH	5
170 #define ELEVATOR_INSERT_SORT_MERGE	6
171 
172 #define rq_end_sector(rq)	(blk_rq_pos(rq) + blk_rq_sectors(rq))
173 #define rb_entry_rq(node)	rb_entry((node), struct request, rb_node)
174 
175 #define rq_entry_fifo(ptr)	list_entry((ptr), struct request, queuelist)
176 #define rq_fifo_clear(rq)	list_del_init(&(rq)->queuelist)
177 
178 /*
179  * Elevator features.
180  */
181 
182 /* Supports zoned block devices sequential write constraint */
183 #define ELEVATOR_F_ZBD_SEQ_WRITE	(1U << 0)
184 /* Supports scheduling on multiple hardware queues */
185 #define ELEVATOR_F_MQ_AWARE		(1U << 1)
186 
187 #endif /* CONFIG_BLOCK */
188 #endif
189