blob: 5b05b7ad4f0f7bbd853c6a6d647f0abfb44211c9 [file] [log] [blame]
Devendra Patel70671872013-01-18 11:04:02 -08001/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
Maya Erez60181552012-06-27 11:25:26 +03002 *
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.
6 *
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.
11 *
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
16 * the debugfs file.
17 *
18 */
19
20#ifndef _LINUX_TEST_IOSCHED_H
21#define _LINUX_TEST_IOSCHED_H
22
23/*
24 * Patterns definitions for read/write requests data
25 */
Dolev Ravivf7a895172013-02-12 17:10:32 +020026#define TEST_PATTERN_SEQUENTIAL 0x12345678
Maya Erez60181552012-06-27 11:25:26 +030027#define TEST_PATTERN_5A 0x5A5A5A5A
28#define TEST_PATTERN_FF 0xFFFFFFFF
29#define TEST_NO_PATTERN 0xDEADBEEF
30#define BIO_U32_SIZE 1024
31
32struct test_data;
33
34typedef int (prepare_test_fn) (struct test_data *);
35typedef int (run_test_fn) (struct test_data *);
36typedef int (check_test_result_fn) (struct test_data *);
37typedef int (post_test_fn) (struct test_data *);
38typedef char* (get_test_case_str_fn) (struct test_data *);
39typedef void (blk_dev_test_init_fn) (void);
40typedef void (blk_dev_test_exit_fn) (void);
Dolev Raviv50032382013-01-09 12:00:02 +020041typedef struct gendisk* (get_rq_disk_fn) (void);
Maya Erez60181552012-06-27 11:25:26 +030042
43/**
44 * enum test_state - defines the state of the test
45 */
46enum test_state {
47 TEST_IDLE,
48 TEST_RUNNING,
49 TEST_COMPLETED,
50};
51
52/**
53 * enum test_results - defines the success orfailure of the test
54 */
55enum test_results {
56 TEST_NO_RESULT,
57 TEST_FAILED,
58 TEST_PASSED,
59 TEST_NOT_SUPPORTED,
60};
61
62/**
63 * enum req_unique_type - defines a unique request type
64 */
65enum req_unique_type {
66 REQ_UNIQUE_NONE,
67 REQ_UNIQUE_DISCARD,
68 REQ_UNIQUE_FLUSH,
Maya Erez22f7abf2012-07-18 21:52:33 +030069 REQ_UNIQUE_SANITIZE,
Maya Erez60181552012-06-27 11:25:26 +030070};
71
72/**
73 * struct test_debug - debugfs directories
74 * @debug_root: The test-iosched debugfs root directory
75 * @debug_utils_root: test-iosched debugfs utils root
76 * directory
77 * @debug_tests_root: test-iosched debugfs tests root
78 * directory
79 * @debug_test_result: Exposes the test result to the user
80 * space
81 * @start_sector: The start sector for read/write requests
82 */
83struct test_debug {
84 struct dentry *debug_root;
85 struct dentry *debug_utils_root;
86 struct dentry *debug_tests_root;
87 struct dentry *debug_test_result;
88 struct dentry *start_sector;
89};
90
91/**
92 * struct test_request - defines a test request
93 * @queuelist: The test requests list
94 * @bios_buffer: Write/read requests data buffer
95 * @buf_size: Write/read requests data buffer size (in
96 * bytes)
97 * @rq: A block request, to be dispatched
98 * @req_completed: A flag to indicate if the request was
99 * completed
100 * @req_result: Keeps the error code received in the
101 * request completion callback
102 * @is_err_expected: A flag to indicate if the request should
103 * fail
104 * @wr_rd_data_pattern: A pattern written to the write data
105 * buffer. Can be used in read requests to
106 * verify the data
107 * @req_id: A unique ID to identify a test request
108 * to ease the debugging of the test cases
109 */
110struct test_request {
111 struct list_head queuelist;
112 unsigned int *bios_buffer;
113 int buf_size;
114 struct request *rq;
115 bool req_completed;
116 int req_result;
117 int is_err_expected;
118 int wr_rd_data_pattern;
119 int req_id;
120};
121
122/**
123 * struct test_info - specific test information
124 * @testcase: The current running test case
125 * @timeout_msec: Test specific test timeout
126 * @buf_size: Write/read requests data buffer size (in
127 * bytes)
128 * @prepare_test_fn: Test specific test preparation callback
129 * @run_test_fn: Test specific test running callback
130 * @check_test_result_fn: Test specific test result checking
131 * callback
132 * @get_test_case_str_fn: Test specific function to get the test name
Lee Susman9cb6eda2013-07-02 15:12:24 +0300133 * @test_duration: A ktime value saved for timing
Lee Susmanf18263a2012-10-24 14:14:37 +0200134 * calculations
Maya Erez60181552012-06-27 11:25:26 +0300135 * @data: Test specific private data
Lee Susman70160bb2013-01-06 10:57:30 +0200136 * @test_byte_count: Total number of bytes dispatched in
137 * the test
Maya Erez60181552012-06-27 11:25:26 +0300138 */
139struct test_info {
140 int testcase;
141 unsigned timeout_msec;
142 prepare_test_fn *prepare_test_fn;
143 run_test_fn *run_test_fn;
144 check_test_result_fn *check_test_result_fn;
145 post_test_fn *post_test_fn;
146 get_test_case_str_fn *get_test_case_str_fn;
Lee Susmanec0b8212013-06-27 11:35:20 +0300147 ktime_t test_duration;
Dolev Raviv50032382013-01-09 12:00:02 +0200148 get_rq_disk_fn *get_rq_disk_fn;
Maya Erez60181552012-06-27 11:25:26 +0300149 void *data;
Lee Susman70160bb2013-01-06 10:57:30 +0200150 unsigned long test_byte_count;
Maya Erez60181552012-06-27 11:25:26 +0300151};
152
153/**
154 * struct blk_dev_test_type - identifies block device test
155 * @list: list head pointer
156 * @init_fn: block device test init callback
157 * @exit_fn: block device test exit callback
158 */
159struct blk_dev_test_type {
160 struct list_head list;
161 blk_dev_test_init_fn *init_fn;
162 blk_dev_test_exit_fn *exit_fn;
163};
164
165/**
166 * struct test_data - global test iosched data
167 * @queue: The test IO scheduler requests list
168 * @test_queue: The test requests list
Lee Susman1199b4c2012-12-19 14:19:30 +0200169 * @dispatched_queue: The queue contains requests dispatched
170 * from @test_queue
171 * @reinsert_queue: The queue contains reinserted from underlying
172 * driver requests
173 * @urgent_queue: The queue contains requests for urgent delivery
174 * These requests will be delivered before @test_queue
175 * and @reinsert_queue requests
176 * @test_count: Number of requests in the @test_queue
177 * @dispatched_count: Number of requests in the @dispatched_queue
178 * @reinsert_count: Number of requests in the @reinsert_queue
179 * @urgent_count: Number of requests in the @urgent_queue
Maya Erez60181552012-06-27 11:25:26 +0300180 * @wait_q: A wait queue for waiting for the test
181 * requests completion
182 * @test_state: Indicates if there is a running test.
183 * Used for dispatch function
184 * @test_result: Indicates if the test passed or failed
185 * @debug: The test debugfs entries
186 * @req_q: The block layer request queue
187 * @num_of_write_bios: The number of write BIOs added to the test requests.
188 * Used to calcualte the sector number of
189 * new BIOs.
190 * @start_sector: The address of the first sector that can
191 * be accessed by the test
192 * @timeout_timer: A timer to verify test completion in
193 * case of non-completed requests
194 * @wr_rd_next_req_id: A unique ID to identify WRITE/READ
195 * request to ease the debugging of the
196 * test cases
197 * @unique_next_req_id: A unique ID to identify
198 * FLUSH/DISCARD/SANITIZE request to ease
199 * the debugging of the test cases
200 * @lock: A lock to verify running a single test
201 * at a time
202 * @test_info: A specific test data to be set by the
203 * test invokation function
204 * @ignore_round: A boolean variable indicating that a
205 * test round was disturbed by an external
206 * flush request, therefore disqualifying
207 * the results
208 */
209struct test_data {
210 struct list_head queue;
211 struct list_head test_queue;
Lee Susman1199b4c2012-12-19 14:19:30 +0200212 struct list_head dispatched_queue;
213 struct list_head reinsert_queue;
214 struct list_head urgent_queue;
215 unsigned int test_count;
216 unsigned int dispatched_count;
217 unsigned int reinsert_count;
218 unsigned int urgent_count;
Maya Erez60181552012-06-27 11:25:26 +0300219 wait_queue_head_t wait_q;
220 enum test_state test_state;
221 enum test_results test_result;
222 struct test_debug debug;
223 struct request_queue *req_q;
224 int num_of_write_bios;
225 u32 start_sector;
226 struct timer_list timeout_timer;
227 int wr_rd_next_req_id;
228 int unique_next_req_id;
229 spinlock_t lock;
230 struct test_info test_info;
231 bool fs_wr_reqs_during_test;
232 bool ignore_round;
233};
234
235extern int test_iosched_start_test(struct test_info *t_info);
236extern void test_iosched_mark_test_completion(void);
Lee Susman70160bb2013-01-06 10:57:30 +0200237extern void check_test_completion(void);
Maya Erez60181552012-06-27 11:25:26 +0300238extern int test_iosched_add_unique_test_req(int is_err_expcted,
239 enum req_unique_type req_unique,
240 int start_sec, int nr_sects, rq_end_io_fn *end_req_io);
241extern int test_iosched_add_wr_rd_test_req(int is_err_expcted,
242 int direction, int start_sec,
243 int num_bios, int pattern, rq_end_io_fn *end_req_io);
Lee Susman1199b4c2012-12-19 14:19:30 +0200244extern struct test_request *test_iosched_create_test_req(int is_err_expcted,
245 int direction, int start_sec,
246 int num_bios, int pattern, rq_end_io_fn *end_req_io);
Maya Erez60181552012-06-27 11:25:26 +0300247
248extern struct dentry *test_iosched_get_debugfs_tests_root(void);
249extern struct dentry *test_iosched_get_debugfs_utils_root(void);
250
251extern struct request_queue *test_iosched_get_req_queue(void);
252
253extern void test_iosched_set_test_result(int);
254
255void test_iosched_set_ignore_round(bool ignore_round);
256
257void test_iosched_register(struct blk_dev_test_type *bdt);
258
259void test_iosched_unregister(struct blk_dev_test_type *bdt);
260
Lee Susman1199b4c2012-12-19 14:19:30 +0200261extern struct test_data *test_get_test_data(void);
262
263void test_iosched_add_urgent_req(struct test_request *test_rq);
264
265int test_is_req_urgent(struct request *rq);
Lee Susman9cb6eda2013-07-02 15:12:24 +0300266
267void check_test_completion(void);
Maya Erez60181552012-06-27 11:25:26 +0300268#endif /* _LINUX_TEST_IOSCHED_H */