1 /* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * The test scheduler allows to test the block device by dispatching
13 * specific requests according to the test case and declare PASS/FAIL
14 * according to the requests completion error code.
15 * Each test is exposed via debugfs and can be triggered by writing to
20 #ifndef _LINUX_TEST_IOSCHED_H
21 #define _LINUX_TEST_IOSCHED_H
24 * Patterns definitions for read/write requests data
26 #define TEST_PATTERN_SEQUENTIAL -1
27 #define TEST_PATTERN_5A 0x5A5A5A5A
28 #define TEST_PATTERN_FF 0xFFFFFFFF
29 #define TEST_NO_PATTERN 0xDEADBEEF
30 #define BIO_U32_SIZE 1024
31 #define TEST_BIO_SIZE PAGE_SIZE /* use one page bios */
35 typedef int (prepare_test_fn) (struct test_iosched *);
36 typedef int (run_test_fn) (struct test_iosched *);
37 typedef int (check_test_result_fn) (struct test_iosched *);
38 typedef int (post_test_fn) (struct test_iosched *);
39 typedef char* (get_test_case_str_fn) (int);
40 typedef int (blk_dev_test_init_fn) (struct test_iosched *);
41 typedef void (blk_dev_test_exit_fn) (struct test_iosched *);
42 typedef struct gendisk* (get_rq_disk_fn) (struct test_iosched *);
43 typedef bool (check_test_completion_fn) (struct test_iosched *);
46 * enum test_state - defines the state of the test
55 * enum test_results - defines the success orfailure of the test
65 * enum req_unique_type - defines a unique request type
67 enum req_unique_type {
74 * struct test_debug - debugfs directories
75 * @debug_root: The test-iosched debugfs root directory
76 * @debug_utils_root: test-iosched debugfs utils root
78 * @debug_tests_root: test-iosched debugfs tests root
80 * @debug_test_result: Exposes the test result to the user
82 * @start_sector: The start sector for read/write requests
83 * @sector_range: Range of the test, starting from start_sector
87 struct dentry *debug_root;
88 struct dentry *debug_utils_root;
89 struct dentry *debug_tests_root;
90 struct dentry *debug_test_result;
91 struct dentry *start_sector;
92 struct dentry *sector_range;
96 * struct test_request - defines a test request
97 * @queuelist: The test requests list
98 * @bios_buffer: Write/read requests data buffer, one page per bio
99 * @buf_size: Write/read requests data buffer size (in
101 * @rq: A block request, to be dispatched
102 * @req_completed: A flag to indicate if the request was
104 * @req_result: Keeps the error code received in the
105 * request completion callback
106 * @is_err_expected: A flag to indicate if the request should
108 * @wr_rd_data_pattern: A pattern written to the write data
109 * buffer. Can be used in read requests to
111 * @req_id: A unique ID to identify a test request
112 * to ease the debugging of the test cases
114 struct test_request {
115 struct list_head queuelist;
116 void *bios_buffer[BLK_MAX_SEGMENTS];
122 int wr_rd_data_pattern;
127 * struct test_info - specific test information
128 * @testcase: The current running test case
129 * @timeout_msec: Test specific test timeout
130 * @buf_size: Write/read requests data buffer size (in
132 * @prepare_test_fn: Test specific test preparation callback
133 * @run_test_fn: Test specific test running callback
134 * @check_test_result_fn: Test specific test result checking
136 * @get_test_case_str_fn: Test specific function to get the test name
137 * @test_duration: A ktime value saved for timing
139 * @data: Test specific private data
140 * @test_byte_count: Total number of bytes dispatched in
145 unsigned timeout_msec;
146 prepare_test_fn *prepare_test_fn;
147 run_test_fn *run_test_fn;
148 check_test_result_fn *check_test_result_fn;
149 post_test_fn *post_test_fn;
150 get_test_case_str_fn *get_test_case_str_fn;
151 ktime_t test_duration;
152 get_rq_disk_fn *get_rq_disk_fn;
153 check_test_completion_fn *check_test_completion_fn;
155 unsigned long test_byte_count;
159 * struct blk_dev_test_type - identifies block device test
160 * @list: list head pointer
161 * @type_prefix: prefix of device class name, i.e. "mmc"/ "sd"
162 * @init_fn: block device test init callback
163 * @exit_fn: block device test exit callback
165 struct blk_dev_test_type {
166 struct list_head list;
167 const char *type_prefix;
168 blk_dev_test_init_fn *init_fn;
169 blk_dev_test_exit_fn *exit_fn;
173 * struct test_data - global test iosched data
174 * @queue: The test IO scheduler requests list
175 * @test_queue: The test requests list
176 * @dispatched_queue: The queue contains requests dispatched
178 * @reinsert_queue: The queue contains reinserted from underlying
180 * @urgent_queue: The queue contains requests for urgent delivery
181 * These requests will be delivered before @test_queue
182 * and @reinsert_queue requests
183 * @test_count: Number of requests in the @test_queue
184 * @dispatched_count: Number of requests in the @dispatched_queue
185 * @reinsert_count: Number of requests in the @reinsert_queue
186 * @urgent_count: Number of requests in the @urgent_queue
187 * @wait_q: A wait queue for waiting for the test
188 * requests completion
189 * @test_state: Indicates if there is a running test.
190 * Used for dispatch function
191 * @test_result: Indicates if the test passed or failed
192 * @debug: The test debugfs entries
193 * @req_q: The block layer request queue
194 * @num_of_write_bios: The number of write BIOs added to the test requests.
195 * Used to calcualte the sector number of
197 * @start_sector: The address of the first sector that can
198 * be accessed by the test
199 * @sector_range: Range of the test, starting from start_sector
201 * @wr_rd_next_req_id: A unique ID to identify WRITE/READ
202 * request to ease the debugging of the
204 * @unique_next_req_id: A unique ID to identify
205 * FLUSH/DISCARD/SANITIZE request to ease
206 * the debugging of the test cases
207 * @lock: A lock to verify running a single test
209 * @test_info: A specific test data to be set by the
210 * test invokation function
211 * @ignore_round: A boolean variable indicating that a
212 * test round was disturbed by an external
213 * flush request, therefore disqualifying
215 * @blk_dev_test_data: associated specific block device test utility
217 struct test_iosched {
218 struct list_head queue;
219 struct list_head test_queue;
220 struct list_head dispatched_queue;
221 struct list_head reinsert_queue;
222 struct list_head urgent_queue;
223 unsigned int test_count;
224 unsigned int dispatched_count;
225 unsigned int reinsert_count;
226 unsigned int urgent_count;
227 wait_queue_head_t wait_q;
228 enum test_state test_state;
229 enum test_results test_result;
230 struct test_debug debug;
231 struct request_queue *req_q;
232 int num_of_write_bios;
235 int wr_rd_next_req_id;
236 int unique_next_req_id;
238 struct test_info test_info;
239 bool fs_wr_reqs_during_test;
241 bool notified_urgent;
242 void *blk_dev_test_data;
245 extern int test_iosched_start_test(struct test_iosched *,
246 struct test_info *t_info);
247 extern void test_iosched_mark_test_completion(struct test_iosched *);
248 extern void check_test_completion(struct test_iosched *);
249 extern int test_iosched_add_unique_test_req(struct test_iosched *,
250 int is_err_expcted, enum req_unique_type req_unique,
251 int start_sec, int nr_sects, rq_end_io_fn *end_req_io);
252 extern int test_iosched_add_wr_rd_test_req(struct test_iosched *,
253 int is_err_expcted, int direction, int start_sec, int num_bios,
254 int pattern, rq_end_io_fn *end_req_io);
255 extern struct test_request *test_iosched_create_test_req(struct test_iosched *,
256 int is_err_expcted, int direction, int start_sec, int num_bios,
257 int pattern, rq_end_io_fn *end_req_io);
259 extern void test_iosched_free_test_req_data_buffer(struct test_request *);
261 extern void test_iosched_set_test_result(struct test_iosched*, int test_result);
263 extern void test_iosched_set_ignore_round(struct test_iosched *,
266 extern void test_iosched_register(struct blk_dev_test_type *bdt);
268 extern void test_iosched_unregister(struct blk_dev_test_type *bdt);
270 extern void test_iosched_add_urgent_req(struct test_iosched *,
271 struct test_request *);
273 extern void check_test_completion(struct test_iosched *);
275 extern int compare_buffer_to_pattern(struct test_request *test_rq);
277 #endif /* _LINUX_TEST_IOSCHED_H */