blob: dbab8084ec0b6df1d86cf919dd2ee9e88744239e [file] [log] [blame]
Dolev Ravivd7c3cbe2013-02-11 11:58:14 +02001/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
2 *
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 */
13
14#include <linux/module.h>
15#include <linux/blkdev.h>
16#include <linux/debugfs.h>
17#include <linux/test-iosched.h>
18#include <scsi/scsi_device.h>
19#include <scsi/scsi_cmnd.h>
20#include <../sd.h>
Lee Susman9cb6eda2013-07-02 15:12:24 +030021#include <linux/delay.h>
Dolev Ravivd7c3cbe2013-02-11 11:58:14 +020022
23#define MODULE_NAME "ufs_test"
24
Lee Susman9cb6eda2013-07-02 15:12:24 +030025#define TEST_MAX_BIOS_PER_REQ 16
Dolev Ravivd7c3cbe2013-02-11 11:58:14 +020026#define LARGE_PRIME_1 1103515367
27#define LARGE_PRIME_2 35757
Lee Susman9cb6eda2013-07-02 15:12:24 +030028#define DEFAULT_NUM_OF_BIOS 2
29
30/* the amount of requests that will be inserted */
31#define LONG_SEQ_TEST_NUM_REQS 256
32/* request queue limitation is 128 requests, and we leave 10 spare requests */
33#define QUEUE_MAX_REQUESTS 118
34#define MB_MSEC_RATIO_APPROXIMATION ((1024 * 1024) / 1000)
35/* actual number of MiB in test multiplied by 10, for single digit precision*/
36#define BYTE_TO_MB_x_10(x) ((x * 10) / (1024 * 1024))
37/* extract integer value */
38#define LONG_TEST_SIZE_INTEGER(x) (BYTE_TO_MB_x_10(x) / 10)
39/* and calculate the MiB value fraction */
40#define LONG_TEST_SIZE_FRACTION(x) (BYTE_TO_MB_x_10(x) - \
41 (LONG_TEST_SIZE_INTEGER(x) * 10))
Dolev Ravivd7c3cbe2013-02-11 11:58:14 +020042
43#define test_pr_debug(fmt, args...) pr_debug("%s: "fmt"\n", MODULE_NAME, args)
44#define test_pr_info(fmt, args...) pr_info("%s: "fmt"\n", MODULE_NAME, args)
45#define test_pr_err(fmt, args...) pr_err("%s: "fmt"\n", MODULE_NAME, args)
46
47enum ufs_test_testcases {
48 UFS_TEST_WRITE_READ_TEST,
Lee Susman9cb6eda2013-07-02 15:12:24 +030049
50 TEST_LONG_SEQUENTIAL_READ,
51 TEST_LONG_SEQUENTIAL_WRITE,
Dolev Ravivd7c3cbe2013-02-11 11:58:14 +020052};
53
54struct ufs_test_debug {
55 struct dentry *write_read_test; /* basic test */
56 struct dentry *random_test_seed; /* parameters in utils */
Lee Susman9cb6eda2013-07-02 15:12:24 +030057 struct dentry *long_sequential_read_test;
58 struct dentry *long_sequential_write_test;
Dolev Ravivd7c3cbe2013-02-11 11:58:14 +020059};
60
61struct ufs_test_data {
62 /* Data structure for debugfs dentrys */
63 struct ufs_test_debug debug;
64 /*
65 * Data structure containing individual test information, including
66 * self-defined specific data
67 */
68 struct test_info test_info;
69 /* device test */
70 struct blk_dev_test_type bdt;
71 /* A wait queue for OPs to complete */
72 wait_queue_head_t wait_q;
73 /* a flag for read compleation */
74 bool read_completed;
75 /* a flag for write compleation */
76 bool write_completed;
77 /*
78 * To determine the number of r/w bios. When seed = 0, random is
79 * disabled and 2 BIOs are written.
80 */
81 unsigned int random_test_seed;
Lee Susman9cb6eda2013-07-02 15:12:24 +030082 /* A counter for the number of test requests completed */
83 unsigned int completed_req_count;
Dolev Ravivd7c3cbe2013-02-11 11:58:14 +020084};
85
86static struct ufs_test_data *utd;
87
88static bool message_repeat;
89
90static char *ufs_test_get_test_case_str(struct test_data *td)
91{
92 if (!td) {
93 test_pr_err("%s: NULL td", __func__);
94 return NULL;
95 }
96
97 switch (td->test_info.testcase) {
98 case UFS_TEST_WRITE_READ_TEST:
99 return "UFS write read test";
100 break;
Lee Susman9cb6eda2013-07-02 15:12:24 +0300101 case TEST_LONG_SEQUENTIAL_READ:
102 return "UFS long sequential read test";
103 break;
104 case TEST_LONG_SEQUENTIAL_WRITE:
105 return "UFS long sequential write test";
106 break;
Dolev Ravivd7c3cbe2013-02-11 11:58:14 +0200107 default:
108 return "Unknown test";
109 }
110}
111
112static unsigned int ufs_test_pseudo_random_seed(unsigned int *seed_number,
113 unsigned int min_val, unsigned int max_val)
114{
115 int ret = 0;
116
117 if (!seed_number)
118 return 0;
119
120 *seed_number = ((unsigned int) (((unsigned long) *seed_number
121 * (unsigned long) LARGE_PRIME_1) + LARGE_PRIME_2));
122 ret = (unsigned int) ((*seed_number) % max_val);
123
124 return (ret > min_val ? ret : min_val);
125}
126
127static void ufs_test_pseudo_rnd_size(unsigned int *seed,
128 unsigned int *num_of_bios)
129{
130 *num_of_bios = ufs_test_pseudo_random_seed(seed, 1,
131 TEST_MAX_BIOS_PER_REQ);
132 if (!(*num_of_bios))
133 *num_of_bios = DEFAULT_NUM_OF_BIOS;
134}
135
136static void ufs_test_write_read_test_end_io_fn(struct request *rq, int err)
137{
138 struct test_request *test_rq = (struct test_request *)rq->elv.priv[0];
139 BUG_ON(!test_rq);
140
141 test_rq->req_completed = 1;
142 test_rq->req_result = err;
143
144 test_pr_info("%s: request %d completed, err=%d",
145 __func__, test_rq->req_id, err);
146
147 utd->write_completed = true;
148 wake_up(&utd->wait_q);
149}
150
151static struct gendisk *ufs_test_get_rq_disk(void)
152{
153 struct request_queue *req_q = test_iosched_get_req_queue();
154 struct scsi_device *sd;
155 struct device *dev;
156 struct scsi_disk *sdkp;
157 struct gendisk *gd;
158
159 if (!req_q) {
160 test_pr_info("%s: Could not fetch request_queue", __func__);
161 gd = NULL;
162 goto exit;
163 }
164
165 sd = (struct scsi_device *)req_q->queuedata;
166
167 dev = &sd->sdev_gendev;
168 sdkp = scsi_disk_get_from_dev(dev);
169 if (!sdkp) {
170 test_pr_info("%s: Could not fatch scsi disk", __func__);
171 gd = NULL;
172 goto exit;
173 }
174
175 gd = sdkp->disk;
176exit:
177 return gd;
178}
179
180static int ufs_test_run_write_read_test(struct test_data *td)
181{
182 int ret = 0;
183 unsigned int start_sec;
184 unsigned int num_bios;
185 struct request_queue *q = td->req_q;
186
187
188 start_sec = td->start_sector + sizeof(int) * BIO_U32_SIZE
189 * td->num_of_write_bios;
190 if (utd->random_test_seed != 0)
191 ufs_test_pseudo_rnd_size(&utd->random_test_seed, &num_bios);
192 else
193 num_bios = DEFAULT_NUM_OF_BIOS;
194
195 /* Adding a write request */
Lee Susman9cb6eda2013-07-02 15:12:24 +0300196 test_pr_info(
197 "%s: Adding a write request with %d bios to Q, req_id=%d"
198 , __func__, num_bios, td->wr_rd_next_req_id);
Dolev Ravivd7c3cbe2013-02-11 11:58:14 +0200199
200 utd->write_completed = false;
201 ret = test_iosched_add_wr_rd_test_req(0, WRITE, start_sec,
202 num_bios, TEST_PATTERN_5A,
203 ufs_test_write_read_test_end_io_fn);
204
205 if (ret) {
206 test_pr_err("%s: failed to add a write request", __func__);
207 return ret;
208 }
209
210 /* waiting for the write request to finish */
211 blk_run_queue(q);
212 wait_event(utd->wait_q, utd->write_completed);
213
214 /* Adding a read request*/
215 test_pr_info("%s: Adding a read request to Q", __func__);
216
217 ret = test_iosched_add_wr_rd_test_req(0, READ, start_sec,
218 num_bios, TEST_PATTERN_5A, NULL);
219
220 if (ret) {
221 test_pr_err("%s: failed to add a read request", __func__);
222 return ret;
223 }
224
225 blk_run_queue(q);
226 return ret;
227}
228
229static
230int ufs_test_write_read_test_open_cb(struct inode *inode, struct file *file)
231{
232 file->private_data = inode->i_private;
233 message_repeat = 1;
234 test_pr_info("%s:UFS test initialized", __func__);
235 return 0;
236}
237
238static ssize_t ufs_test_write_read_test_write_cb(struct file *file,
239 const char __user *buf,
240 size_t count, loff_t *ppos)
241{
242 int ret = 0;
243 int i;
244 int number;
245
246 sscanf(buf, "%d", &number);
247
248 if (number <= 0)
249 number = 1;
250
251 test_pr_info("%s:the test will run for %d iterations.",
252 __func__, number);
253 memset(&utd->test_info, 0, sizeof(struct test_info));
254
255 /* Initializing test */
256 utd->test_info.data = utd;
257 utd->test_info.get_test_case_str_fn = ufs_test_get_test_case_str;
258 utd->test_info.testcase = UFS_TEST_WRITE_READ_TEST;
259 utd->test_info.get_rq_disk_fn = ufs_test_get_rq_disk;
260 utd->test_info.run_test_fn = ufs_test_run_write_read_test;
261
262 /* Running the test multiple times */
263 for (i = 0; i < number; ++i) {
264 ret = test_iosched_start_test(&utd->test_info);
265 if (ret) {
266 test_pr_err("%s: Test failed.", __func__);
267 return ret;
268 }
269 }
270
271 test_pr_info("%s: Completed all the ufs test iterations.", __func__);
272
273 return count;
274}
275
276static ssize_t ufs_test_write_read_test_read_cb(struct file *file,
277 char __user *buffer, size_t count, loff_t *offset)
278{
279 memset((void *) buffer, 0, count);
280
281 snprintf(buffer, count, "\nThis is a UFS write-read test for debug.\n");
282
283 if (message_repeat == 1) {
284 message_repeat = 0;
285 return strnlen(buffer, count);
286 } else
287 return 0;
288}
289
290const struct file_operations write_read_test_ops = {
291 .open = ufs_test_write_read_test_open_cb,
292 .write = ufs_test_write_read_test_write_cb,
293 .read = ufs_test_write_read_test_read_cb,
294};
295
Lee Susman9cb6eda2013-07-02 15:12:24 +0300296static void long_seq_test_free_end_io_fn(struct request *rq, int err)
297{
298 struct test_request *test_rq;
299 struct test_data *ptd = test_get_test_data();
300
301 if (rq)
302 test_rq = (struct test_request *)rq->elv.priv[0];
303 else {
304 test_pr_err("%s: error: NULL request", __func__);
305 return;
306 }
307
308 BUG_ON(!test_rq);
309
310 spin_lock_irq(&ptd->lock);
311 ptd->dispatched_count--;
312 list_del_init(&test_rq->queuelist);
313 __blk_put_request(ptd->req_q, test_rq->rq);
314 spin_unlock_irq(&ptd->lock);
315
316 kfree(test_rq->bios_buffer);
317 kfree(test_rq);
318 utd->completed_req_count++;
319
320 test_pr_err("%s: request %d completed, err=%d",
321 __func__, test_rq->req_id, err);
322
323 check_test_completion();
324
325}
326
327static int run_long_seq_test(struct test_data *td)
328{
329 int ret = 0;
330 int direction;
331 static unsigned int inserted_requests;
332
333 BUG_ON(!td);
334 td->test_count = 0;
335 utd->completed_req_count = 0;
336 inserted_requests = 0;
337
338 if (td->test_info.testcase == TEST_LONG_SEQUENTIAL_READ)
339 direction = READ;
340 else
341 direction = WRITE;
342
343 test_pr_info("%s: Adding %d requests, first req_id=%d",
344 __func__, LONG_SEQ_TEST_NUM_REQS,
345 td->wr_rd_next_req_id);
346
347 do {
348 /*
349 * since our requests come from a pool containing 128
350 * requests, we don't want to exhaust this quantity,
351 * therefore we add up to QUEUE_MAX_REQUESTS (which
352 * includes a safety margin) and then call the mmc layer
353 * to fetch them
354 */
355 if (td->test_count >= QUEUE_MAX_REQUESTS) {
356 blk_run_queue(td->req_q);
357 continue;
358 }
359
360 ret = test_iosched_add_wr_rd_test_req(0, direction,
361 td->start_sector, TEST_MAX_BIOS_PER_REQ,
362 TEST_PATTERN_5A,
363 long_seq_test_free_end_io_fn);
364 if (ret) {
365 test_pr_err("%s: failed to create request" , __func__);
366 break;
367 }
368 inserted_requests++;
369 td->test_info.test_byte_count +=
370 (TEST_MAX_BIOS_PER_REQ * sizeof(unsigned int) *
371 BIO_U32_SIZE);
372
373 } while (inserted_requests < LONG_SEQ_TEST_NUM_REQS);
374
375 /* in this case the queue will not run in the above loop */
376 if (LONG_SEQ_TEST_NUM_REQS < QUEUE_MAX_REQUESTS)
377 blk_run_queue(td->req_q);
378
379 return ret;
380}
381
382
383void long_seq_test_calc_throughput(unsigned long mtime,
384 unsigned long byte_count)
385{
386 unsigned long fraction, integer;
387
388 test_pr_info("%s: time is %lu msec, size is %lu.%lu MiB",
389 __func__, mtime, LONG_TEST_SIZE_INTEGER(byte_count),
390 LONG_TEST_SIZE_FRACTION(byte_count));
391
392 /* we first multiply in order not to lose precision */
393 mtime *= MB_MSEC_RATIO_APPROXIMATION;
394 /* divide values to get a MiB/sec integer value with one
395 digit of precision
396 */
397 fraction = integer = (byte_count * 10) / mtime;
398 integer /= 10;
399 /* and calculate the MiB value fraction */
400 fraction -= integer * 10;
401
402 test_pr_info("%s: Throughput: %lu.%lu MiB/sec\n",
403 __func__, integer, fraction);
404}
405
406static ssize_t long_sequential_read_test_write(struct file *file,
407 const char __user *buf,
408 size_t count,
409 loff_t *ppos)
410{
411 int ret = 0;
412 int i = 0;
413 int number = -1;
414 unsigned long mtime, byte_count;
415
416 test_pr_info("%s: -- UFS Long Sequential Read TEST --", __func__);
417
418 sscanf(buf, "%d", &number);
419
420 if (number <= 0)
421 number = 1;
422
423 memset(&utd->test_info, 0, sizeof(struct test_info));
424
425 utd->test_info.data = utd;
426 utd->test_info.get_rq_disk_fn = ufs_test_get_rq_disk;
427 utd->test_info.run_test_fn = run_long_seq_test;
428 utd->test_info.get_test_case_str_fn = ufs_test_get_test_case_str;
429 utd->test_info.testcase = TEST_LONG_SEQUENTIAL_READ;
430
431 for (i = 0 ; i < number ; ++i) {
432 test_pr_info("%s: Cycle # %d / %d", __func__, i+1, number);
433 test_pr_info("%s: ====================", __func__);
434
435 ret = test_iosched_start_test(&utd->test_info);
436 if (ret)
437 break;
438
439 mtime = ktime_to_ms(utd->test_info.test_duration);
440 byte_count = utd->test_info.test_byte_count;
441
442 long_seq_test_calc_throughput(mtime, byte_count);
443
444 /* Allow FS requests to be dispatched */
445 msleep(1000);
446 }
447
448 return count;
449}
450
451static ssize_t long_sequential_read_test_read(struct file *file,
452 char __user *buffer,
453 size_t count,
454 loff_t *offset)
455{
456 memset((void *)buffer, 0, count);
457
458 snprintf(buffer, count,
459 "\nufs_long_sequential_read_test\n"
460 "=========\n"
461 "Description:\n"
462 "This test runs the following scenarios\n"
463 "- Long Sequential Read Test: this test measures read "
464 "throughput at the driver level by sequentially reading many "
465 "large requests.\n");
466
467 if (message_repeat == 1) {
468 message_repeat = 0;
469 return strnlen(buffer, count);
470 } else
471 return 0;
472}
473
474static bool message_repeat;
475static int test_open(struct inode *inode, struct file *file)
476{
477 file->private_data = inode->i_private;
478 message_repeat = 1;
479 return 0;
480}
481
482const struct file_operations long_sequential_read_test_ops = {
483 .open = test_open,
484 .write = long_sequential_read_test_write,
485 .read = long_sequential_read_test_read,
486};
487
488static ssize_t long_sequential_write_test_write(struct file *file,
489 const char __user *buf,
490 size_t count,
491 loff_t *ppos)
492{
493 int ret = 0;
494 int i = 0;
495 int number = -1;
496 unsigned long mtime, byte_count;
497
498 test_pr_info("%s: -- UFS Long Sequential Write TEST --", __func__);
499
500 sscanf(buf, "%d", &number);
501
502 if (number <= 0)
503 number = 1;
504
505 memset(&utd->test_info, 0, sizeof(struct test_info));
506
507 utd->test_info.data = utd;
508 utd->test_info.get_rq_disk_fn = ufs_test_get_rq_disk;
509 utd->test_info.get_test_case_str_fn = ufs_test_get_test_case_str;
510 utd->test_info.run_test_fn = run_long_seq_test;
511 utd->test_info.testcase = TEST_LONG_SEQUENTIAL_WRITE;
512
513 for (i = 0 ; i < number ; ++i) {
514 test_pr_info("%s: Cycle # %d / %d", __func__, i+1, number);
515 test_pr_info("%s: ====================", __func__);
516
517 utd->test_info.test_byte_count = 0;
518 ret = test_iosched_start_test(&utd->test_info);
519 if (ret)
520 break;
521
522 mtime = ktime_to_ms(utd->test_info.test_duration);
523 byte_count = utd->test_info.test_byte_count;
524
525 long_seq_test_calc_throughput(mtime, byte_count);
526
527 /* Allow FS requests to be dispatched */
528 msleep(1000);
529 }
530
531 return count;
532}
533
534static ssize_t long_sequential_write_test_read(struct file *file,
535 char __user *buffer,
536 size_t count,
537 loff_t *offset)
538{
539 memset((void *)buffer, 0, count);
540
541 snprintf(buffer, count,
542 "\nufs_long_sequential_write_test\n"
543 "=========\n"
544 "Description:\n"
545 "This test runs the following scenarios\n"
546 "- Long Sequential Write Test: this test measures write "
547 "throughput at the driver level by sequentially writing many "
548 "large requests\n");
549
550 if (message_repeat == 1) {
551 message_repeat = 0;
552 return strnlen(buffer, count);
553 } else
554 return 0;
555}
556
557const struct file_operations long_sequential_write_test_ops = {
558 .open = test_open,
559 .write = long_sequential_write_test_write,
560 .read = long_sequential_write_test_read,
561};
562
Dolev Ravivd7c3cbe2013-02-11 11:58:14 +0200563static void ufs_test_debugfs_cleanup(void)
564{
Lee Susman9cb6eda2013-07-02 15:12:24 +0300565 debugfs_remove_recursive(test_iosched_get_debugfs_tests_root());
Dolev Ravivd7c3cbe2013-02-11 11:58:14 +0200566}
567
568static int ufs_test_debugfs_init(void)
569{
570 struct dentry *utils_root, *tests_root;
Lee Susman9cb6eda2013-07-02 15:12:24 +0300571 int ret = 0;
Dolev Ravivd7c3cbe2013-02-11 11:58:14 +0200572
573 utils_root = test_iosched_get_debugfs_utils_root();
574 tests_root = test_iosched_get_debugfs_tests_root();
575
576 if (!utils_root || !tests_root) {
577 test_pr_err("%s: Failed to create debugfs root.", __func__);
Lee Susman9cb6eda2013-07-02 15:12:24 +0300578 ret = -EINVAL;
579 goto exit;
Dolev Ravivd7c3cbe2013-02-11 11:58:14 +0200580 }
581
582 utd->debug.random_test_seed = debugfs_create_u32("random_test_seed",
583 S_IRUGO | S_IWUGO, utils_root, &utd->random_test_seed);
584
585 if (!utd->debug.random_test_seed) {
586 test_pr_err("%s: Could not create debugfs random_test_seed.",
587 __func__);
Lee Susman9cb6eda2013-07-02 15:12:24 +0300588 ret = -ENOMEM;
589 goto exit;
Dolev Ravivd7c3cbe2013-02-11 11:58:14 +0200590 }
591
Lee Susman9cb6eda2013-07-02 15:12:24 +0300592 utd->debug.write_read_test = debugfs_create_file("ufs_write_read_test",
Dolev Ravivd7c3cbe2013-02-11 11:58:14 +0200593 S_IRUGO | S_IWUGO, tests_root,
594 NULL, &write_read_test_ops);
595
596 if (!utd->debug.write_read_test) {
Lee Susman9cb6eda2013-07-02 15:12:24 +0300597 ret = -ENOMEM;
598 goto exit_err;
Dolev Ravivd7c3cbe2013-02-11 11:58:14 +0200599 }
600
Lee Susman9cb6eda2013-07-02 15:12:24 +0300601 utd->debug.long_sequential_read_test = debugfs_create_file(
602 "ufs_long_sequential_read_test",
603 S_IRUGO | S_IWUGO,
604 tests_root,
605 NULL,
606 &long_sequential_read_test_ops);
607
608 if (!utd->debug.long_sequential_read_test) {
609 ret = -ENOMEM;
610 goto exit_err;
611 }
612
613 utd->debug.long_sequential_write_test = debugfs_create_file(
614 "ufs_long_sequential_write_test",
615 S_IRUGO | S_IWUGO,
616 tests_root,
617 NULL,
618 &long_sequential_write_test_ops);
619
620 if (!utd->debug.long_sequential_write_test) {
621 ret = -ENOMEM;
622 goto exit_err;
623 }
624
625 goto exit;
626
627exit_err:
628 debugfs_remove_recursive(tests_root);
629exit:
630 return ret;
Dolev Ravivd7c3cbe2013-02-11 11:58:14 +0200631}
632
633static void ufs_test_probe(void)
634{
635 ufs_test_debugfs_init();
636}
637
638static void ufs_test_remove(void)
639{
640 ufs_test_debugfs_cleanup();
641}
642
643int __init ufs_test_init(void)
644{
645 utd = kzalloc(sizeof(struct ufs_test_data), GFP_KERNEL);
646 if (!utd) {
647 test_pr_err("%s: failed to allocate ufs_test_data", __func__);
648 return -ENODEV;
649 }
650
651 init_waitqueue_head(&utd->wait_q);
652 utd->bdt.init_fn = ufs_test_probe;
653 utd->bdt.exit_fn = ufs_test_remove;
654 INIT_LIST_HEAD(&utd->bdt.list);
655 test_iosched_register(&utd->bdt);
656
657 return 0;
658}
659EXPORT_SYMBOL_GPL(ufs_test_init);
660
661static void __exit ufs_test_exit(void)
662{
663 test_iosched_unregister(&utd->bdt);
664 kfree(utd);
665}
666module_init(ufs_test_init)
667;
668module_exit(ufs_test_exit)
669;
670
671MODULE_LICENSE("GPL v2");
672MODULE_DESCRIPTION("UFC test");
673