aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/card/mmc_test.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/mmc/card/mmc_test.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/mmc/card/mmc_test.c')
-rw-r--r--drivers/mmc/card/mmc_test.c811
1 files changed, 671 insertions, 140 deletions
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c
index 5dd8576b5c18..233cdfae92f4 100644
--- a/drivers/mmc/card/mmc_test.c
+++ b/drivers/mmc/card/mmc_test.c
@@ -17,6 +17,11 @@
17 17
18#include <linux/scatterlist.h> 18#include <linux/scatterlist.h>
19#include <linux/swap.h> /* For nr_free_buffer_pages() */ 19#include <linux/swap.h> /* For nr_free_buffer_pages() */
20#include <linux/list.h>
21
22#include <linux/debugfs.h>
23#include <linux/uaccess.h>
24#include <linux/seq_file.h>
20 25
21#define RESULT_OK 0 26#define RESULT_OK 0
22#define RESULT_FAIL 1 27#define RESULT_FAIL 1
@@ -56,7 +61,9 @@ struct mmc_test_mem {
56 * struct mmc_test_area - information for performance tests. 61 * struct mmc_test_area - information for performance tests.
57 * @max_sz: test area size (in bytes) 62 * @max_sz: test area size (in bytes)
58 * @dev_addr: address on card at which to do performance tests 63 * @dev_addr: address on card at which to do performance tests
59 * @max_segs: maximum segments in scatterlist @sg 64 * @max_tfr: maximum transfer size allowed by driver (in bytes)
65 * @max_segs: maximum segments allowed by driver in scatterlist @sg
66 * @max_seg_sz: maximum segment size allowed by driver
60 * @blocks: number of (512 byte) blocks currently mapped by @sg 67 * @blocks: number of (512 byte) blocks currently mapped by @sg
61 * @sg_len: length of currently mapped scatterlist @sg 68 * @sg_len: length of currently mapped scatterlist @sg
62 * @mem: allocated memory 69 * @mem: allocated memory
@@ -65,7 +72,9 @@ struct mmc_test_mem {
65struct mmc_test_area { 72struct mmc_test_area {
66 unsigned long max_sz; 73 unsigned long max_sz;
67 unsigned int dev_addr; 74 unsigned int dev_addr;
75 unsigned int max_tfr;
68 unsigned int max_segs; 76 unsigned int max_segs;
77 unsigned int max_seg_sz;
69 unsigned int blocks; 78 unsigned int blocks;
70 unsigned int sg_len; 79 unsigned int sg_len;
71 struct mmc_test_mem *mem; 80 struct mmc_test_mem *mem;
@@ -73,12 +82,59 @@ struct mmc_test_area {
73}; 82};
74 83
75/** 84/**
85 * struct mmc_test_transfer_result - transfer results for performance tests.
86 * @link: double-linked list
87 * @count: amount of group of sectors to check
88 * @sectors: amount of sectors to check in one group
89 * @ts: time values of transfer
90 * @rate: calculated transfer rate
91 * @iops: I/O operations per second (times 100)
92 */
93struct mmc_test_transfer_result {
94 struct list_head link;
95 unsigned int count;
96 unsigned int sectors;
97 struct timespec ts;
98 unsigned int rate;
99 unsigned int iops;
100};
101
102/**
103 * struct mmc_test_general_result - results for tests.
104 * @link: double-linked list
105 * @card: card under test
106 * @testcase: number of test case
107 * @result: result of test run
108 * @tr_lst: transfer measurements if any as mmc_test_transfer_result
109 */
110struct mmc_test_general_result {
111 struct list_head link;
112 struct mmc_card *card;
113 int testcase;
114 int result;
115 struct list_head tr_lst;
116};
117
118/**
119 * struct mmc_test_dbgfs_file - debugfs related file.
120 * @link: double-linked list
121 * @card: card under test
122 * @file: file created under debugfs
123 */
124struct mmc_test_dbgfs_file {
125 struct list_head link;
126 struct mmc_card *card;
127 struct dentry *file;
128};
129
130/**
76 * struct mmc_test_card - test information. 131 * struct mmc_test_card - test information.
77 * @card: card under test 132 * @card: card under test
78 * @scratch: transfer buffer 133 * @scratch: transfer buffer
79 * @buffer: transfer buffer 134 * @buffer: transfer buffer
80 * @highmem: buffer for highmem tests 135 * @highmem: buffer for highmem tests
81 * @area: information for performance tests 136 * @area: information for performance tests
137 * @gr: pointer to results of current testcase
82 */ 138 */
83struct mmc_test_card { 139struct mmc_test_card {
84 struct mmc_card *card; 140 struct mmc_card *card;
@@ -88,7 +144,8 @@ struct mmc_test_card {
88#ifdef CONFIG_HIGHMEM 144#ifdef CONFIG_HIGHMEM
89 struct page *highmem; 145 struct page *highmem;
90#endif 146#endif
91 struct mmc_test_area area; 147 struct mmc_test_area area;
148 struct mmc_test_general_result *gr;
92}; 149};
93 150
94/*******************************************************************/ 151/*******************************************************************/
@@ -100,17 +157,7 @@ struct mmc_test_card {
100 */ 157 */
101static int mmc_test_set_blksize(struct mmc_test_card *test, unsigned size) 158static int mmc_test_set_blksize(struct mmc_test_card *test, unsigned size)
102{ 159{
103 struct mmc_command cmd; 160 return mmc_set_blocklen(test->card, size);
104 int ret;
105
106 cmd.opcode = MMC_SET_BLOCKLEN;
107 cmd.arg = size;
108 cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
109 ret = mmc_wait_for_cmd(test->card->host, &cmd, 0);
110 if (ret)
111 return ret;
112
113 return 0;
114} 161}
115 162
116/* 163/*
@@ -165,7 +212,7 @@ static int mmc_test_busy(struct mmc_command *cmd)
165static int mmc_test_wait_busy(struct mmc_test_card *test) 212static int mmc_test_wait_busy(struct mmc_test_card *test)
166{ 213{
167 int ret, busy; 214 int ret, busy;
168 struct mmc_command cmd; 215 struct mmc_command cmd = {0};
169 216
170 busy = 0; 217 busy = 0;
171 do { 218 do {
@@ -181,9 +228,10 @@ static int mmc_test_wait_busy(struct mmc_test_card *test)
181 228
182 if (!busy && mmc_test_busy(&cmd)) { 229 if (!busy && mmc_test_busy(&cmd)) {
183 busy = 1; 230 busy = 1;
184 printk(KERN_INFO "%s: Warning: Host did not " 231 if (test->card->host->caps & MMC_CAP_WAIT_WHILE_BUSY)
185 "wait for busy state to end.\n", 232 printk(KERN_INFO "%s: Warning: Host did not "
186 mmc_hostname(test->card->host)); 233 "wait for busy state to end.\n",
234 mmc_hostname(test->card->host));
187 } 235 }
188 } while (mmc_test_busy(&cmd)); 236 } while (mmc_test_busy(&cmd));
189 237
@@ -198,18 +246,13 @@ static int mmc_test_buffer_transfer(struct mmc_test_card *test,
198{ 246{
199 int ret; 247 int ret;
200 248
201 struct mmc_request mrq; 249 struct mmc_request mrq = {0};
202 struct mmc_command cmd; 250 struct mmc_command cmd = {0};
203 struct mmc_command stop; 251 struct mmc_command stop = {0};
204 struct mmc_data data; 252 struct mmc_data data = {0};
205 253
206 struct scatterlist sg; 254 struct scatterlist sg;
207 255
208 memset(&mrq, 0, sizeof(struct mmc_request));
209 memset(&cmd, 0, sizeof(struct mmc_command));
210 memset(&data, 0, sizeof(struct mmc_data));
211 memset(&stop, 0, sizeof(struct mmc_command));
212
213 mrq.cmd = &cmd; 256 mrq.cmd = &cmd;
214 mrq.data = &data; 257 mrq.data = &data;
215 mrq.stop = &stop; 258 mrq.stop = &stop;
@@ -244,28 +287,39 @@ static void mmc_test_free_mem(struct mmc_test_mem *mem)
244} 287}
245 288
246/* 289/*
247 * Allocate a lot of memory, preferrably max_sz but at least min_sz. In case 290 * Allocate a lot of memory, preferably max_sz but at least min_sz. In case
248 * there isn't much memory do not exceed 1/16th total lowmem pages. 291 * there isn't much memory do not exceed 1/16th total lowmem pages. Also do
292 * not exceed a maximum number of segments and try not to make segments much
293 * bigger than maximum segment size.
249 */ 294 */
250static struct mmc_test_mem *mmc_test_alloc_mem(unsigned long min_sz, 295static struct mmc_test_mem *mmc_test_alloc_mem(unsigned long min_sz,
251 unsigned long max_sz) 296 unsigned long max_sz,
297 unsigned int max_segs,
298 unsigned int max_seg_sz)
252{ 299{
253 unsigned long max_page_cnt = DIV_ROUND_UP(max_sz, PAGE_SIZE); 300 unsigned long max_page_cnt = DIV_ROUND_UP(max_sz, PAGE_SIZE);
254 unsigned long min_page_cnt = DIV_ROUND_UP(min_sz, PAGE_SIZE); 301 unsigned long min_page_cnt = DIV_ROUND_UP(min_sz, PAGE_SIZE);
302 unsigned long max_seg_page_cnt = DIV_ROUND_UP(max_seg_sz, PAGE_SIZE);
255 unsigned long page_cnt = 0; 303 unsigned long page_cnt = 0;
256 unsigned long limit = nr_free_buffer_pages() >> 4; 304 unsigned long limit = nr_free_buffer_pages() >> 4;
257 struct mmc_test_mem *mem; 305 struct mmc_test_mem *mem;
258 306
259 if (max_page_cnt > limit) 307 if (max_page_cnt > limit)
260 max_page_cnt = limit; 308 max_page_cnt = limit;
261 if (max_page_cnt < min_page_cnt) 309 if (min_page_cnt > max_page_cnt)
262 max_page_cnt = min_page_cnt; 310 min_page_cnt = max_page_cnt;
311
312 if (max_seg_page_cnt > max_page_cnt)
313 max_seg_page_cnt = max_page_cnt;
314
315 if (max_segs > max_page_cnt)
316 max_segs = max_page_cnt;
263 317
264 mem = kzalloc(sizeof(struct mmc_test_mem), GFP_KERNEL); 318 mem = kzalloc(sizeof(struct mmc_test_mem), GFP_KERNEL);
265 if (!mem) 319 if (!mem)
266 return NULL; 320 return NULL;
267 321
268 mem->arr = kzalloc(sizeof(struct mmc_test_pages) * max_page_cnt, 322 mem->arr = kzalloc(sizeof(struct mmc_test_pages) * max_segs,
269 GFP_KERNEL); 323 GFP_KERNEL);
270 if (!mem->arr) 324 if (!mem->arr)
271 goto out_free; 325 goto out_free;
@@ -276,7 +330,7 @@ static struct mmc_test_mem *mmc_test_alloc_mem(unsigned long min_sz,
276 gfp_t flags = GFP_KERNEL | GFP_DMA | __GFP_NOWARN | 330 gfp_t flags = GFP_KERNEL | GFP_DMA | __GFP_NOWARN |
277 __GFP_NORETRY; 331 __GFP_NORETRY;
278 332
279 order = get_order(max_page_cnt << PAGE_SHIFT); 333 order = get_order(max_seg_page_cnt << PAGE_SHIFT);
280 while (1) { 334 while (1) {
281 page = alloc_pages(flags, order); 335 page = alloc_pages(flags, order);
282 if (page || !order) 336 if (page || !order)
@@ -295,6 +349,11 @@ static struct mmc_test_mem *mmc_test_alloc_mem(unsigned long min_sz,
295 break; 349 break;
296 max_page_cnt -= 1UL << order; 350 max_page_cnt -= 1UL << order;
297 page_cnt += 1UL << order; 351 page_cnt += 1UL << order;
352 if (mem->cnt >= max_segs) {
353 if (page_cnt < min_page_cnt)
354 goto out_free;
355 break;
356 }
298 } 357 }
299 358
300 return mem; 359 return mem;
@@ -310,7 +369,8 @@ out_free:
310 */ 369 */
311static int mmc_test_map_sg(struct mmc_test_mem *mem, unsigned long sz, 370static int mmc_test_map_sg(struct mmc_test_mem *mem, unsigned long sz,
312 struct scatterlist *sglist, int repeat, 371 struct scatterlist *sglist, int repeat,
313 unsigned int max_segs, unsigned int *sg_len) 372 unsigned int max_segs, unsigned int max_seg_sz,
373 unsigned int *sg_len)
314{ 374{
315 struct scatterlist *sg = NULL; 375 struct scatterlist *sg = NULL;
316 unsigned int i; 376 unsigned int i;
@@ -322,8 +382,10 @@ static int mmc_test_map_sg(struct mmc_test_mem *mem, unsigned long sz,
322 for (i = 0; i < mem->cnt; i++) { 382 for (i = 0; i < mem->cnt; i++) {
323 unsigned long len = PAGE_SIZE << mem->arr[i].order; 383 unsigned long len = PAGE_SIZE << mem->arr[i].order;
324 384
325 if (sz < len) 385 if (len > sz)
326 len = sz; 386 len = sz;
387 if (len > max_seg_sz)
388 len = max_seg_sz;
327 if (sg) 389 if (sg)
328 sg = sg_next(sg); 390 sg = sg_next(sg);
329 else 391 else
@@ -355,6 +417,7 @@ static int mmc_test_map_sg_max_scatter(struct mmc_test_mem *mem,
355 unsigned long sz, 417 unsigned long sz,
356 struct scatterlist *sglist, 418 struct scatterlist *sglist,
357 unsigned int max_segs, 419 unsigned int max_segs,
420 unsigned int max_seg_sz,
358 unsigned int *sg_len) 421 unsigned int *sg_len)
359{ 422{
360 struct scatterlist *sg = NULL; 423 struct scatterlist *sg = NULL;
@@ -365,7 +428,7 @@ static int mmc_test_map_sg_max_scatter(struct mmc_test_mem *mem,
365 sg_init_table(sglist, max_segs); 428 sg_init_table(sglist, max_segs);
366 429
367 *sg_len = 0; 430 *sg_len = 0;
368 while (sz && i) { 431 while (sz) {
369 base = page_address(mem->arr[--i].page); 432 base = page_address(mem->arr[--i].page);
370 cnt = 1 << mem->arr[i].order; 433 cnt = 1 << mem->arr[i].order;
371 while (sz && cnt) { 434 while (sz && cnt) {
@@ -374,7 +437,9 @@ static int mmc_test_map_sg_max_scatter(struct mmc_test_mem *mem,
374 continue; 437 continue;
375 last_addr = addr; 438 last_addr = addr;
376 len = PAGE_SIZE; 439 len = PAGE_SIZE;
377 if (sz < len) 440 if (len > max_seg_sz)
441 len = max_seg_sz;
442 if (len > sz)
378 len = sz; 443 len = sz;
379 if (sg) 444 if (sg)
380 sg = sg_next(sg); 445 sg = sg_next(sg);
@@ -386,6 +451,8 @@ static int mmc_test_map_sg_max_scatter(struct mmc_test_mem *mem,
386 sz -= len; 451 sz -= len;
387 *sg_len += 1; 452 *sg_len += 1;
388 } 453 }
454 if (i == 0)
455 i = mem->cnt;
389 } 456 }
390 457
391 if (sg) 458 if (sg)
@@ -421,23 +488,52 @@ static unsigned int mmc_test_rate(uint64_t bytes, struct timespec *ts)
421} 488}
422 489
423/* 490/*
491 * Save transfer results for future usage
492 */
493static void mmc_test_save_transfer_result(struct mmc_test_card *test,
494 unsigned int count, unsigned int sectors, struct timespec ts,
495 unsigned int rate, unsigned int iops)
496{
497 struct mmc_test_transfer_result *tr;
498
499 if (!test->gr)
500 return;
501
502 tr = kmalloc(sizeof(struct mmc_test_transfer_result), GFP_KERNEL);
503 if (!tr)
504 return;
505
506 tr->count = count;
507 tr->sectors = sectors;
508 tr->ts = ts;
509 tr->rate = rate;
510 tr->iops = iops;
511
512 list_add_tail(&tr->link, &test->gr->tr_lst);
513}
514
515/*
424 * Print the transfer rate. 516 * Print the transfer rate.
425 */ 517 */
426static void mmc_test_print_rate(struct mmc_test_card *test, uint64_t bytes, 518static void mmc_test_print_rate(struct mmc_test_card *test, uint64_t bytes,
427 struct timespec *ts1, struct timespec *ts2) 519 struct timespec *ts1, struct timespec *ts2)
428{ 520{
429 unsigned int rate, sectors = bytes >> 9; 521 unsigned int rate, iops, sectors = bytes >> 9;
430 struct timespec ts; 522 struct timespec ts;
431 523
432 ts = timespec_sub(*ts2, *ts1); 524 ts = timespec_sub(*ts2, *ts1);
433 525
434 rate = mmc_test_rate(bytes, &ts); 526 rate = mmc_test_rate(bytes, &ts);
527 iops = mmc_test_rate(100, &ts); /* I/O ops per sec x 100 */
435 528
436 printk(KERN_INFO "%s: Transfer of %u sectors (%u%s KiB) took %lu.%09lu " 529 printk(KERN_INFO "%s: Transfer of %u sectors (%u%s KiB) took %lu.%09lu "
437 "seconds (%u kB/s, %u KiB/s)\n", 530 "seconds (%u kB/s, %u KiB/s, %u.%02u IOPS)\n",
438 mmc_hostname(test->card->host), sectors, sectors >> 1, 531 mmc_hostname(test->card->host), sectors, sectors >> 1,
439 (sectors == 1 ? ".5" : ""), (unsigned long)ts.tv_sec, 532 (sectors & 1 ? ".5" : ""), (unsigned long)ts.tv_sec,
440 (unsigned long)ts.tv_nsec, rate / 1000, rate / 1024); 533 (unsigned long)ts.tv_nsec, rate / 1000, rate / 1024,
534 iops / 100, iops % 100);
535
536 mmc_test_save_transfer_result(test, 1, sectors, ts, rate, iops);
441} 537}
442 538
443/* 539/*
@@ -447,20 +543,24 @@ static void mmc_test_print_avg_rate(struct mmc_test_card *test, uint64_t bytes,
447 unsigned int count, struct timespec *ts1, 543 unsigned int count, struct timespec *ts1,
448 struct timespec *ts2) 544 struct timespec *ts2)
449{ 545{
450 unsigned int rate, sectors = bytes >> 9; 546 unsigned int rate, iops, sectors = bytes >> 9;
451 uint64_t tot = bytes * count; 547 uint64_t tot = bytes * count;
452 struct timespec ts; 548 struct timespec ts;
453 549
454 ts = timespec_sub(*ts2, *ts1); 550 ts = timespec_sub(*ts2, *ts1);
455 551
456 rate = mmc_test_rate(tot, &ts); 552 rate = mmc_test_rate(tot, &ts);
553 iops = mmc_test_rate(count * 100, &ts); /* I/O ops per sec x 100 */
457 554
458 printk(KERN_INFO "%s: Transfer of %u x %u sectors (%u x %u%s KiB) took " 555 printk(KERN_INFO "%s: Transfer of %u x %u sectors (%u x %u%s KiB) took "
459 "%lu.%09lu seconds (%u kB/s, %u KiB/s)\n", 556 "%lu.%09lu seconds (%u kB/s, %u KiB/s, "
557 "%u.%02u IOPS)\n",
460 mmc_hostname(test->card->host), count, sectors, count, 558 mmc_hostname(test->card->host), count, sectors, count,
461 sectors >> 1, (sectors == 1 ? ".5" : ""), 559 sectors >> 1, (sectors & 1 ? ".5" : ""),
462 (unsigned long)ts.tv_sec, (unsigned long)ts.tv_nsec, 560 (unsigned long)ts.tv_sec, (unsigned long)ts.tv_nsec,
463 rate / 1000, rate / 1024); 561 rate / 1000, rate / 1024, iops / 100, iops % 100);
562
563 mmc_test_save_transfer_result(test, count, sectors, ts, rate, iops);
464} 564}
465 565
466/* 566/*
@@ -626,15 +726,10 @@ static int mmc_test_simple_transfer(struct mmc_test_card *test,
626 struct scatterlist *sg, unsigned sg_len, unsigned dev_addr, 726 struct scatterlist *sg, unsigned sg_len, unsigned dev_addr,
627 unsigned blocks, unsigned blksz, int write) 727 unsigned blocks, unsigned blksz, int write)
628{ 728{
629 struct mmc_request mrq; 729 struct mmc_request mrq = {0};
630 struct mmc_command cmd; 730 struct mmc_command cmd = {0};
631 struct mmc_command stop; 731 struct mmc_command stop = {0};
632 struct mmc_data data; 732 struct mmc_data data = {0};
633
634 memset(&mrq, 0, sizeof(struct mmc_request));
635 memset(&cmd, 0, sizeof(struct mmc_command));
636 memset(&data, 0, sizeof(struct mmc_data));
637 memset(&stop, 0, sizeof(struct mmc_command));
638 733
639 mrq.cmd = &cmd; 734 mrq.cmd = &cmd;
640 mrq.data = &data; 735 mrq.data = &data;
@@ -656,18 +751,13 @@ static int mmc_test_simple_transfer(struct mmc_test_card *test,
656static int mmc_test_broken_transfer(struct mmc_test_card *test, 751static int mmc_test_broken_transfer(struct mmc_test_card *test,
657 unsigned blocks, unsigned blksz, int write) 752 unsigned blocks, unsigned blksz, int write)
658{ 753{
659 struct mmc_request mrq; 754 struct mmc_request mrq = {0};
660 struct mmc_command cmd; 755 struct mmc_command cmd = {0};
661 struct mmc_command stop; 756 struct mmc_command stop = {0};
662 struct mmc_data data; 757 struct mmc_data data = {0};
663 758
664 struct scatterlist sg; 759 struct scatterlist sg;
665 760
666 memset(&mrq, 0, sizeof(struct mmc_request));
667 memset(&cmd, 0, sizeof(struct mmc_command));
668 memset(&data, 0, sizeof(struct mmc_data));
669 memset(&stop, 0, sizeof(struct mmc_command));
670
671 mrq.cmd = &cmd; 761 mrq.cmd = &cmd;
672 mrq.data = &data; 762 mrq.data = &data;
673 mrq.stop = &stop; 763 mrq.stop = &stop;
@@ -1215,16 +1305,22 @@ static int mmc_test_area_map(struct mmc_test_card *test, unsigned long sz,
1215 int max_scatter) 1305 int max_scatter)
1216{ 1306{
1217 struct mmc_test_area *t = &test->area; 1307 struct mmc_test_area *t = &test->area;
1308 int err;
1218 1309
1219 t->blocks = sz >> 9; 1310 t->blocks = sz >> 9;
1220 1311
1221 if (max_scatter) { 1312 if (max_scatter) {
1222 return mmc_test_map_sg_max_scatter(t->mem, sz, t->sg, 1313 err = mmc_test_map_sg_max_scatter(t->mem, sz, t->sg,
1223 t->max_segs, &t->sg_len); 1314 t->max_segs, t->max_seg_sz,
1224 } else {
1225 return mmc_test_map_sg(t->mem, sz, t->sg, 1, t->max_segs,
1226 &t->sg_len); 1315 &t->sg_len);
1316 } else {
1317 err = mmc_test_map_sg(t->mem, sz, t->sg, 1, t->max_segs,
1318 t->max_seg_sz, &t->sg_len);
1227 } 1319 }
1320 if (err)
1321 printk(KERN_INFO "%s: Failed to map sg list\n",
1322 mmc_hostname(test->card->host));
1323 return err;
1228} 1324}
1229 1325
1230/* 1326/*
@@ -1249,6 +1345,22 @@ static int mmc_test_area_io(struct mmc_test_card *test, unsigned long sz,
1249 struct timespec ts1, ts2; 1345 struct timespec ts1, ts2;
1250 int ret; 1346 int ret;
1251 1347
1348 /*
1349 * In the case of a maximally scattered transfer, the maximum transfer
1350 * size is further limited by using PAGE_SIZE segments.
1351 */
1352 if (max_scatter) {
1353 struct mmc_test_area *t = &test->area;
1354 unsigned long max_tfr;
1355
1356 if (t->max_seg_sz >= PAGE_SIZE)
1357 max_tfr = t->max_segs * PAGE_SIZE;
1358 else
1359 max_tfr = t->max_segs * t->max_seg_sz;
1360 if (sz > max_tfr)
1361 sz = max_tfr;
1362 }
1363
1252 ret = mmc_test_area_map(test, sz, max_scatter); 1364 ret = mmc_test_area_map(test, sz, max_scatter);
1253 if (ret) 1365 if (ret)
1254 return ret; 1366 return ret;
@@ -1274,8 +1386,9 @@ static int mmc_test_area_io(struct mmc_test_card *test, unsigned long sz,
1274 */ 1386 */
1275static int mmc_test_area_fill(struct mmc_test_card *test) 1387static int mmc_test_area_fill(struct mmc_test_card *test)
1276{ 1388{
1277 return mmc_test_area_io(test, test->area.max_sz, test->area.dev_addr, 1389 struct mmc_test_area *t = &test->area;
1278 1, 0, 0); 1390
1391 return mmc_test_area_io(test, t->max_tfr, t->dev_addr, 1, 0, 0);
1279} 1392}
1280 1393
1281/* 1394/*
@@ -1288,7 +1401,7 @@ static int mmc_test_area_erase(struct mmc_test_card *test)
1288 if (!mmc_can_erase(test->card)) 1401 if (!mmc_can_erase(test->card))
1289 return 0; 1402 return 0;
1290 1403
1291 return mmc_erase(test->card, t->dev_addr, test->area.max_sz >> 9, 1404 return mmc_erase(test->card, t->dev_addr, t->max_sz >> 9,
1292 MMC_ERASE_ARG); 1405 MMC_ERASE_ARG);
1293} 1406}
1294 1407
@@ -1306,38 +1419,52 @@ static int mmc_test_area_cleanup(struct mmc_test_card *test)
1306} 1419}
1307 1420
1308/* 1421/*
1309 * Initialize an area for testing large transfers. The size of the area is the 1422 * Initialize an area for testing large transfers. The test area is set to the
1310 * preferred erase size which is a good size for optimal transfer speed. Note 1423 * middle of the card because cards may have different charateristics at the
1311 * that is typically 4MiB for modern cards. The test area is set to the middle 1424 * front (for FAT file system optimization). Optionally, the area is erased
1312 * of the card because cards may have different charateristics at the front 1425 * (if the card supports it) which may improve write performance. Optionally,
1313 * (for FAT file system optimization). Optionally, the area is erased (if the 1426 * the area is filled with data for subsequent read tests.
1314 * card supports it) which may improve write performance. Optionally, the area
1315 * is filled with data for subsequent read tests.
1316 */ 1427 */
1317static int mmc_test_area_init(struct mmc_test_card *test, int erase, int fill) 1428static int mmc_test_area_init(struct mmc_test_card *test, int erase, int fill)
1318{ 1429{
1319 struct mmc_test_area *t = &test->area; 1430 struct mmc_test_area *t = &test->area;
1320 unsigned long min_sz = 64 * 1024; 1431 unsigned long min_sz = 64 * 1024, sz;
1321 int ret; 1432 int ret;
1322 1433
1323 ret = mmc_test_set_blksize(test, 512); 1434 ret = mmc_test_set_blksize(test, 512);
1324 if (ret) 1435 if (ret)
1325 return ret; 1436 return ret;
1326 1437
1327 if (test->card->pref_erase > TEST_AREA_MAX_SIZE >> 9) 1438 /* Make the test area size about 4MiB */
1328 t->max_sz = TEST_AREA_MAX_SIZE; 1439 sz = (unsigned long)test->card->pref_erase << 9;
1329 else 1440 t->max_sz = sz;
1330 t->max_sz = (unsigned long)test->card->pref_erase << 9; 1441 while (t->max_sz < 4 * 1024 * 1024)
1442 t->max_sz += sz;
1443 while (t->max_sz > TEST_AREA_MAX_SIZE && t->max_sz > sz)
1444 t->max_sz -= sz;
1445
1446 t->max_segs = test->card->host->max_segs;
1447 t->max_seg_sz = test->card->host->max_seg_size;
1448
1449 t->max_tfr = t->max_sz;
1450 if (t->max_tfr >> 9 > test->card->host->max_blk_count)
1451 t->max_tfr = test->card->host->max_blk_count << 9;
1452 if (t->max_tfr > test->card->host->max_req_size)
1453 t->max_tfr = test->card->host->max_req_size;
1454 if (t->max_tfr / t->max_seg_sz > t->max_segs)
1455 t->max_tfr = t->max_segs * t->max_seg_sz;
1456
1331 /* 1457 /*
1332 * Try to allocate enough memory for the whole area. Less is OK 1458 * Try to allocate enough memory for a max. sized transfer. Less is OK
1333 * because the same memory can be mapped into the scatterlist more than 1459 * because the same memory can be mapped into the scatterlist more than
1334 * once. 1460 * once. Also, take into account the limits imposed on scatterlist
1461 * segments by the host driver.
1335 */ 1462 */
1336 t->mem = mmc_test_alloc_mem(min_sz, t->max_sz); 1463 t->mem = mmc_test_alloc_mem(min_sz, t->max_tfr, t->max_segs,
1464 t->max_seg_sz);
1337 if (!t->mem) 1465 if (!t->mem)
1338 return -ENOMEM; 1466 return -ENOMEM;
1339 1467
1340 t->max_segs = DIV_ROUND_UP(t->max_sz, PAGE_SIZE);
1341 t->sg = kmalloc(sizeof(struct scatterlist) * t->max_segs, GFP_KERNEL); 1468 t->sg = kmalloc(sizeof(struct scatterlist) * t->max_segs, GFP_KERNEL);
1342 if (!t->sg) { 1469 if (!t->sg) {
1343 ret = -ENOMEM; 1470 ret = -ENOMEM;
@@ -1401,8 +1528,10 @@ static int mmc_test_area_prepare_fill(struct mmc_test_card *test)
1401static int mmc_test_best_performance(struct mmc_test_card *test, int write, 1528static int mmc_test_best_performance(struct mmc_test_card *test, int write,
1402 int max_scatter) 1529 int max_scatter)
1403{ 1530{
1404 return mmc_test_area_io(test, test->area.max_sz, test->area.dev_addr, 1531 struct mmc_test_area *t = &test->area;
1405 write, max_scatter, 1); 1532
1533 return mmc_test_area_io(test, t->max_tfr, t->dev_addr, write,
1534 max_scatter, 1);
1406} 1535}
1407 1536
1408/* 1537/*
@@ -1442,17 +1571,19 @@ static int mmc_test_best_write_perf_max_scatter(struct mmc_test_card *test)
1442 */ 1571 */
1443static int mmc_test_profile_read_perf(struct mmc_test_card *test) 1572static int mmc_test_profile_read_perf(struct mmc_test_card *test)
1444{ 1573{
1574 struct mmc_test_area *t = &test->area;
1445 unsigned long sz; 1575 unsigned long sz;
1446 unsigned int dev_addr; 1576 unsigned int dev_addr;
1447 int ret; 1577 int ret;
1448 1578
1449 for (sz = 512; sz < test->area.max_sz; sz <<= 1) { 1579 for (sz = 512; sz < t->max_tfr; sz <<= 1) {
1450 dev_addr = test->area.dev_addr + (sz >> 9); 1580 dev_addr = t->dev_addr + (sz >> 9);
1451 ret = mmc_test_area_io(test, sz, dev_addr, 0, 0, 1); 1581 ret = mmc_test_area_io(test, sz, dev_addr, 0, 0, 1);
1452 if (ret) 1582 if (ret)
1453 return ret; 1583 return ret;
1454 } 1584 }
1455 dev_addr = test->area.dev_addr; 1585 sz = t->max_tfr;
1586 dev_addr = t->dev_addr;
1456 return mmc_test_area_io(test, sz, dev_addr, 0, 0, 1); 1587 return mmc_test_area_io(test, sz, dev_addr, 0, 0, 1);
1457} 1588}
1458 1589
@@ -1461,6 +1592,7 @@ static int mmc_test_profile_read_perf(struct mmc_test_card *test)
1461 */ 1592 */
1462static int mmc_test_profile_write_perf(struct mmc_test_card *test) 1593static int mmc_test_profile_write_perf(struct mmc_test_card *test)
1463{ 1594{
1595 struct mmc_test_area *t = &test->area;
1464 unsigned long sz; 1596 unsigned long sz;
1465 unsigned int dev_addr; 1597 unsigned int dev_addr;
1466 int ret; 1598 int ret;
@@ -1468,8 +1600,8 @@ static int mmc_test_profile_write_perf(struct mmc_test_card *test)
1468 ret = mmc_test_area_erase(test); 1600 ret = mmc_test_area_erase(test);
1469 if (ret) 1601 if (ret)
1470 return ret; 1602 return ret;
1471 for (sz = 512; sz < test->area.max_sz; sz <<= 1) { 1603 for (sz = 512; sz < t->max_tfr; sz <<= 1) {
1472 dev_addr = test->area.dev_addr + (sz >> 9); 1604 dev_addr = t->dev_addr + (sz >> 9);
1473 ret = mmc_test_area_io(test, sz, dev_addr, 1, 0, 1); 1605 ret = mmc_test_area_io(test, sz, dev_addr, 1, 0, 1);
1474 if (ret) 1606 if (ret)
1475 return ret; 1607 return ret;
@@ -1477,7 +1609,8 @@ static int mmc_test_profile_write_perf(struct mmc_test_card *test)
1477 ret = mmc_test_area_erase(test); 1609 ret = mmc_test_area_erase(test);
1478 if (ret) 1610 if (ret)
1479 return ret; 1611 return ret;
1480 dev_addr = test->area.dev_addr; 1612 sz = t->max_tfr;
1613 dev_addr = t->dev_addr;
1481 return mmc_test_area_io(test, sz, dev_addr, 1, 0, 1); 1614 return mmc_test_area_io(test, sz, dev_addr, 1, 0, 1);
1482} 1615}
1483 1616
@@ -1486,6 +1619,7 @@ static int mmc_test_profile_write_perf(struct mmc_test_card *test)
1486 */ 1619 */
1487static int mmc_test_profile_trim_perf(struct mmc_test_card *test) 1620static int mmc_test_profile_trim_perf(struct mmc_test_card *test)
1488{ 1621{
1622 struct mmc_test_area *t = &test->area;
1489 unsigned long sz; 1623 unsigned long sz;
1490 unsigned int dev_addr; 1624 unsigned int dev_addr;
1491 struct timespec ts1, ts2; 1625 struct timespec ts1, ts2;
@@ -1497,8 +1631,8 @@ static int mmc_test_profile_trim_perf(struct mmc_test_card *test)
1497 if (!mmc_can_erase(test->card)) 1631 if (!mmc_can_erase(test->card))
1498 return RESULT_UNSUP_HOST; 1632 return RESULT_UNSUP_HOST;
1499 1633
1500 for (sz = 512; sz < test->area.max_sz; sz <<= 1) { 1634 for (sz = 512; sz < t->max_sz; sz <<= 1) {
1501 dev_addr = test->area.dev_addr + (sz >> 9); 1635 dev_addr = t->dev_addr + (sz >> 9);
1502 getnstimeofday(&ts1); 1636 getnstimeofday(&ts1);
1503 ret = mmc_erase(test->card, dev_addr, sz >> 9, MMC_TRIM_ARG); 1637 ret = mmc_erase(test->card, dev_addr, sz >> 9, MMC_TRIM_ARG);
1504 if (ret) 1638 if (ret)
@@ -1506,7 +1640,7 @@ static int mmc_test_profile_trim_perf(struct mmc_test_card *test)
1506 getnstimeofday(&ts2); 1640 getnstimeofday(&ts2);
1507 mmc_test_print_rate(test, sz, &ts1, &ts2); 1641 mmc_test_print_rate(test, sz, &ts1, &ts2);
1508 } 1642 }
1509 dev_addr = test->area.dev_addr; 1643 dev_addr = t->dev_addr;
1510 getnstimeofday(&ts1); 1644 getnstimeofday(&ts1);
1511 ret = mmc_erase(test->card, dev_addr, sz >> 9, MMC_TRIM_ARG); 1645 ret = mmc_erase(test->card, dev_addr, sz >> 9, MMC_TRIM_ARG);
1512 if (ret) 1646 if (ret)
@@ -1516,29 +1650,66 @@ static int mmc_test_profile_trim_perf(struct mmc_test_card *test)
1516 return 0; 1650 return 0;
1517} 1651}
1518 1652
1653static int mmc_test_seq_read_perf(struct mmc_test_card *test, unsigned long sz)
1654{
1655 struct mmc_test_area *t = &test->area;
1656 unsigned int dev_addr, i, cnt;
1657 struct timespec ts1, ts2;
1658 int ret;
1659
1660 cnt = t->max_sz / sz;
1661 dev_addr = t->dev_addr;
1662 getnstimeofday(&ts1);
1663 for (i = 0; i < cnt; i++) {
1664 ret = mmc_test_area_io(test, sz, dev_addr, 0, 0, 0);
1665 if (ret)
1666 return ret;
1667 dev_addr += (sz >> 9);
1668 }
1669 getnstimeofday(&ts2);
1670 mmc_test_print_avg_rate(test, sz, cnt, &ts1, &ts2);
1671 return 0;
1672}
1673
1519/* 1674/*
1520 * Consecutive read performance by transfer size. 1675 * Consecutive read performance by transfer size.
1521 */ 1676 */
1522static int mmc_test_profile_seq_read_perf(struct mmc_test_card *test) 1677static int mmc_test_profile_seq_read_perf(struct mmc_test_card *test)
1523{ 1678{
1679 struct mmc_test_area *t = &test->area;
1524 unsigned long sz; 1680 unsigned long sz;
1681 int ret;
1682
1683 for (sz = 512; sz < t->max_tfr; sz <<= 1) {
1684 ret = mmc_test_seq_read_perf(test, sz);
1685 if (ret)
1686 return ret;
1687 }
1688 sz = t->max_tfr;
1689 return mmc_test_seq_read_perf(test, sz);
1690}
1691
1692static int mmc_test_seq_write_perf(struct mmc_test_card *test, unsigned long sz)
1693{
1694 struct mmc_test_area *t = &test->area;
1525 unsigned int dev_addr, i, cnt; 1695 unsigned int dev_addr, i, cnt;
1526 struct timespec ts1, ts2; 1696 struct timespec ts1, ts2;
1527 int ret; 1697 int ret;
1528 1698
1529 for (sz = 512; sz <= test->area.max_sz; sz <<= 1) { 1699 ret = mmc_test_area_erase(test);
1530 cnt = test->area.max_sz / sz; 1700 if (ret)
1531 dev_addr = test->area.dev_addr; 1701 return ret;
1532 getnstimeofday(&ts1); 1702 cnt = t->max_sz / sz;
1533 for (i = 0; i < cnt; i++) { 1703 dev_addr = t->dev_addr;
1534 ret = mmc_test_area_io(test, sz, dev_addr, 0, 0, 0); 1704 getnstimeofday(&ts1);
1535 if (ret) 1705 for (i = 0; i < cnt; i++) {
1536 return ret; 1706 ret = mmc_test_area_io(test, sz, dev_addr, 1, 0, 0);
1537 dev_addr += (sz >> 9); 1707 if (ret)
1538 } 1708 return ret;
1539 getnstimeofday(&ts2); 1709 dev_addr += (sz >> 9);
1540 mmc_test_print_avg_rate(test, sz, cnt, &ts1, &ts2);
1541 } 1710 }
1711 getnstimeofday(&ts2);
1712 mmc_test_print_avg_rate(test, sz, cnt, &ts1, &ts2);
1542 return 0; 1713 return 0;
1543} 1714}
1544 1715
@@ -1547,28 +1718,17 @@ static int mmc_test_profile_seq_read_perf(struct mmc_test_card *test)
1547 */ 1718 */
1548static int mmc_test_profile_seq_write_perf(struct mmc_test_card *test) 1719static int mmc_test_profile_seq_write_perf(struct mmc_test_card *test)
1549{ 1720{
1721 struct mmc_test_area *t = &test->area;
1550 unsigned long sz; 1722 unsigned long sz;
1551 unsigned int dev_addr, i, cnt;
1552 struct timespec ts1, ts2;
1553 int ret; 1723 int ret;
1554 1724
1555 for (sz = 512; sz <= test->area.max_sz; sz <<= 1) { 1725 for (sz = 512; sz < t->max_tfr; sz <<= 1) {
1556 ret = mmc_test_area_erase(test); 1726 ret = mmc_test_seq_write_perf(test, sz);
1557 if (ret) 1727 if (ret)
1558 return ret; 1728 return ret;
1559 cnt = test->area.max_sz / sz;
1560 dev_addr = test->area.dev_addr;
1561 getnstimeofday(&ts1);
1562 for (i = 0; i < cnt; i++) {
1563 ret = mmc_test_area_io(test, sz, dev_addr, 1, 0, 0);
1564 if (ret)
1565 return ret;
1566 dev_addr += (sz >> 9);
1567 }
1568 getnstimeofday(&ts2);
1569 mmc_test_print_avg_rate(test, sz, cnt, &ts1, &ts2);
1570 } 1729 }
1571 return 0; 1730 sz = t->max_tfr;
1731 return mmc_test_seq_write_perf(test, sz);
1572} 1732}
1573 1733
1574/* 1734/*
@@ -1576,6 +1736,7 @@ static int mmc_test_profile_seq_write_perf(struct mmc_test_card *test)
1576 */ 1736 */
1577static int mmc_test_profile_seq_trim_perf(struct mmc_test_card *test) 1737static int mmc_test_profile_seq_trim_perf(struct mmc_test_card *test)
1578{ 1738{
1739 struct mmc_test_area *t = &test->area;
1579 unsigned long sz; 1740 unsigned long sz;
1580 unsigned int dev_addr, i, cnt; 1741 unsigned int dev_addr, i, cnt;
1581 struct timespec ts1, ts2; 1742 struct timespec ts1, ts2;
@@ -1587,15 +1748,15 @@ static int mmc_test_profile_seq_trim_perf(struct mmc_test_card *test)
1587 if (!mmc_can_erase(test->card)) 1748 if (!mmc_can_erase(test->card))
1588 return RESULT_UNSUP_HOST; 1749 return RESULT_UNSUP_HOST;
1589 1750
1590 for (sz = 512; sz <= test->area.max_sz; sz <<= 1) { 1751 for (sz = 512; sz <= t->max_sz; sz <<= 1) {
1591 ret = mmc_test_area_erase(test); 1752 ret = mmc_test_area_erase(test);
1592 if (ret) 1753 if (ret)
1593 return ret; 1754 return ret;
1594 ret = mmc_test_area_fill(test); 1755 ret = mmc_test_area_fill(test);
1595 if (ret) 1756 if (ret)
1596 return ret; 1757 return ret;
1597 cnt = test->area.max_sz / sz; 1758 cnt = t->max_sz / sz;
1598 dev_addr = test->area.dev_addr; 1759 dev_addr = t->dev_addr;
1599 getnstimeofday(&ts1); 1760 getnstimeofday(&ts1);
1600 for (i = 0; i < cnt; i++) { 1761 for (i = 0; i < cnt; i++) {
1601 ret = mmc_erase(test->card, dev_addr, sz >> 9, 1762 ret = mmc_erase(test->card, dev_addr, sz >> 9,
@@ -1610,6 +1771,189 @@ static int mmc_test_profile_seq_trim_perf(struct mmc_test_card *test)
1610 return 0; 1771 return 0;
1611} 1772}
1612 1773
1774static unsigned int rnd_next = 1;
1775
1776static unsigned int mmc_test_rnd_num(unsigned int rnd_cnt)
1777{
1778 uint64_t r;
1779
1780 rnd_next = rnd_next * 1103515245 + 12345;
1781 r = (rnd_next >> 16) & 0x7fff;
1782 return (r * rnd_cnt) >> 15;
1783}
1784
1785static int mmc_test_rnd_perf(struct mmc_test_card *test, int write, int print,
1786 unsigned long sz)
1787{
1788 unsigned int dev_addr, cnt, rnd_addr, range1, range2, last_ea = 0, ea;
1789 unsigned int ssz;
1790 struct timespec ts1, ts2, ts;
1791 int ret;
1792
1793 ssz = sz >> 9;
1794
1795 rnd_addr = mmc_test_capacity(test->card) / 4;
1796 range1 = rnd_addr / test->card->pref_erase;
1797 range2 = range1 / ssz;
1798
1799 getnstimeofday(&ts1);
1800 for (cnt = 0; cnt < UINT_MAX; cnt++) {
1801 getnstimeofday(&ts2);
1802 ts = timespec_sub(ts2, ts1);
1803 if (ts.tv_sec >= 10)
1804 break;
1805 ea = mmc_test_rnd_num(range1);
1806 if (ea == last_ea)
1807 ea -= 1;
1808 last_ea = ea;
1809 dev_addr = rnd_addr + test->card->pref_erase * ea +
1810 ssz * mmc_test_rnd_num(range2);
1811 ret = mmc_test_area_io(test, sz, dev_addr, write, 0, 0);
1812 if (ret)
1813 return ret;
1814 }
1815 if (print)
1816 mmc_test_print_avg_rate(test, sz, cnt, &ts1, &ts2);
1817 return 0;
1818}
1819
1820static int mmc_test_random_perf(struct mmc_test_card *test, int write)
1821{
1822 struct mmc_test_area *t = &test->area;
1823 unsigned int next;
1824 unsigned long sz;
1825 int ret;
1826
1827 for (sz = 512; sz < t->max_tfr; sz <<= 1) {
1828 /*
1829 * When writing, try to get more consistent results by running
1830 * the test twice with exactly the same I/O but outputting the
1831 * results only for the 2nd run.
1832 */
1833 if (write) {
1834 next = rnd_next;
1835 ret = mmc_test_rnd_perf(test, write, 0, sz);
1836 if (ret)
1837 return ret;
1838 rnd_next = next;
1839 }
1840 ret = mmc_test_rnd_perf(test, write, 1, sz);
1841 if (ret)
1842 return ret;
1843 }
1844 sz = t->max_tfr;
1845 if (write) {
1846 next = rnd_next;
1847 ret = mmc_test_rnd_perf(test, write, 0, sz);
1848 if (ret)
1849 return ret;
1850 rnd_next = next;
1851 }
1852 return mmc_test_rnd_perf(test, write, 1, sz);
1853}
1854
1855/*
1856 * Random read performance by transfer size.
1857 */
1858static int mmc_test_random_read_perf(struct mmc_test_card *test)
1859{
1860 return mmc_test_random_perf(test, 0);
1861}
1862
1863/*
1864 * Random write performance by transfer size.
1865 */
1866static int mmc_test_random_write_perf(struct mmc_test_card *test)
1867{
1868 return mmc_test_random_perf(test, 1);
1869}
1870
1871static int mmc_test_seq_perf(struct mmc_test_card *test, int write,
1872 unsigned int tot_sz, int max_scatter)
1873{
1874 struct mmc_test_area *t = &test->area;
1875 unsigned int dev_addr, i, cnt, sz, ssz;
1876 struct timespec ts1, ts2;
1877 int ret;
1878
1879 sz = t->max_tfr;
1880
1881 /*
1882 * In the case of a maximally scattered transfer, the maximum transfer
1883 * size is further limited by using PAGE_SIZE segments.
1884 */
1885 if (max_scatter) {
1886 unsigned long max_tfr;
1887
1888 if (t->max_seg_sz >= PAGE_SIZE)
1889 max_tfr = t->max_segs * PAGE_SIZE;
1890 else
1891 max_tfr = t->max_segs * t->max_seg_sz;
1892 if (sz > max_tfr)
1893 sz = max_tfr;
1894 }
1895
1896 ssz = sz >> 9;
1897 dev_addr = mmc_test_capacity(test->card) / 4;
1898 if (tot_sz > dev_addr << 9)
1899 tot_sz = dev_addr << 9;
1900 cnt = tot_sz / sz;
1901 dev_addr &= 0xffff0000; /* Round to 64MiB boundary */
1902
1903 getnstimeofday(&ts1);
1904 for (i = 0; i < cnt; i++) {
1905 ret = mmc_test_area_io(test, sz, dev_addr, write,
1906 max_scatter, 0);
1907 if (ret)
1908 return ret;
1909 dev_addr += ssz;
1910 }
1911 getnstimeofday(&ts2);
1912
1913 mmc_test_print_avg_rate(test, sz, cnt, &ts1, &ts2);
1914
1915 return 0;
1916}
1917
1918static int mmc_test_large_seq_perf(struct mmc_test_card *test, int write)
1919{
1920 int ret, i;
1921
1922 for (i = 0; i < 10; i++) {
1923 ret = mmc_test_seq_perf(test, write, 10 * 1024 * 1024, 1);
1924 if (ret)
1925 return ret;
1926 }
1927 for (i = 0; i < 5; i++) {
1928 ret = mmc_test_seq_perf(test, write, 100 * 1024 * 1024, 1);
1929 if (ret)
1930 return ret;
1931 }
1932 for (i = 0; i < 3; i++) {
1933 ret = mmc_test_seq_perf(test, write, 1000 * 1024 * 1024, 1);
1934 if (ret)
1935 return ret;
1936 }
1937
1938 return ret;
1939}
1940
1941/*
1942 * Large sequential read performance.
1943 */
1944static int mmc_test_large_seq_read_perf(struct mmc_test_card *test)
1945{
1946 return mmc_test_large_seq_perf(test, 0);
1947}
1948
1949/*
1950 * Large sequential write performance.
1951 */
1952static int mmc_test_large_seq_write_perf(struct mmc_test_card *test)
1953{
1954 return mmc_test_large_seq_perf(test, 1);
1955}
1956
1613static const struct mmc_test_case mmc_test_cases[] = { 1957static const struct mmc_test_case mmc_test_cases[] = {
1614 { 1958 {
1615 .name = "Basic write (no data verification)", 1959 .name = "Basic write (no data verification)",
@@ -1849,10 +2193,40 @@ static const struct mmc_test_case mmc_test_cases[] = {
1849 .cleanup = mmc_test_area_cleanup, 2193 .cleanup = mmc_test_area_cleanup,
1850 }, 2194 },
1851 2195
2196 {
2197 .name = "Random read performance by transfer size",
2198 .prepare = mmc_test_area_prepare,
2199 .run = mmc_test_random_read_perf,
2200 .cleanup = mmc_test_area_cleanup,
2201 },
2202
2203 {
2204 .name = "Random write performance by transfer size",
2205 .prepare = mmc_test_area_prepare,
2206 .run = mmc_test_random_write_perf,
2207 .cleanup = mmc_test_area_cleanup,
2208 },
2209
2210 {
2211 .name = "Large sequential read into scattered pages",
2212 .prepare = mmc_test_area_prepare,
2213 .run = mmc_test_large_seq_read_perf,
2214 .cleanup = mmc_test_area_cleanup,
2215 },
2216
2217 {
2218 .name = "Large sequential write from scattered pages",
2219 .prepare = mmc_test_area_prepare,
2220 .run = mmc_test_large_seq_write_perf,
2221 .cleanup = mmc_test_area_cleanup,
2222 },
2223
1852}; 2224};
1853 2225
1854static DEFINE_MUTEX(mmc_test_lock); 2226static DEFINE_MUTEX(mmc_test_lock);
1855 2227
2228static LIST_HEAD(mmc_test_result);
2229
1856static void mmc_test_run(struct mmc_test_card *test, int testcase) 2230static void mmc_test_run(struct mmc_test_card *test, int testcase)
1857{ 2231{
1858 int i, ret; 2232 int i, ret;
@@ -1863,6 +2237,8 @@ static void mmc_test_run(struct mmc_test_card *test, int testcase)
1863 mmc_claim_host(test->card->host); 2237 mmc_claim_host(test->card->host);
1864 2238
1865 for (i = 0;i < ARRAY_SIZE(mmc_test_cases);i++) { 2239 for (i = 0;i < ARRAY_SIZE(mmc_test_cases);i++) {
2240 struct mmc_test_general_result *gr;
2241
1866 if (testcase && ((i + 1) != testcase)) 2242 if (testcase && ((i + 1) != testcase))
1867 continue; 2243 continue;
1868 2244
@@ -1881,6 +2257,25 @@ static void mmc_test_run(struct mmc_test_card *test, int testcase)
1881 } 2257 }
1882 } 2258 }
1883 2259
2260 gr = kzalloc(sizeof(struct mmc_test_general_result),
2261 GFP_KERNEL);
2262 if (gr) {
2263 INIT_LIST_HEAD(&gr->tr_lst);
2264
2265 /* Assign data what we know already */
2266 gr->card = test->card;
2267 gr->testcase = i;
2268
2269 /* Append container to global one */
2270 list_add_tail(&gr->link, &mmc_test_result);
2271
2272 /*
2273 * Save the pointer to created container in our private
2274 * structure.
2275 */
2276 test->gr = gr;
2277 }
2278
1884 ret = mmc_test_cases[i].run(test); 2279 ret = mmc_test_cases[i].run(test);
1885 switch (ret) { 2280 switch (ret) {
1886 case RESULT_OK: 2281 case RESULT_OK:
@@ -1906,6 +2301,10 @@ static void mmc_test_run(struct mmc_test_card *test, int testcase)
1906 mmc_hostname(test->card->host), ret); 2301 mmc_hostname(test->card->host), ret);
1907 } 2302 }
1908 2303
2304 /* Save the result */
2305 if (gr)
2306 gr->result = ret;
2307
1909 if (mmc_test_cases[i].cleanup) { 2308 if (mmc_test_cases[i].cleanup) {
1910 ret = mmc_test_cases[i].cleanup(test); 2309 ret = mmc_test_cases[i].cleanup(test);
1911 if (ret) { 2310 if (ret) {
@@ -1923,30 +2322,95 @@ static void mmc_test_run(struct mmc_test_card *test, int testcase)
1923 mmc_hostname(test->card->host)); 2322 mmc_hostname(test->card->host));
1924} 2323}
1925 2324
1926static ssize_t mmc_test_show(struct device *dev, 2325static void mmc_test_free_result(struct mmc_card *card)
1927 struct device_attribute *attr, char *buf) 2326{
2327 struct mmc_test_general_result *gr, *grs;
2328
2329 mutex_lock(&mmc_test_lock);
2330
2331 list_for_each_entry_safe(gr, grs, &mmc_test_result, link) {
2332 struct mmc_test_transfer_result *tr, *trs;
2333
2334 if (card && gr->card != card)
2335 continue;
2336
2337 list_for_each_entry_safe(tr, trs, &gr->tr_lst, link) {
2338 list_del(&tr->link);
2339 kfree(tr);
2340 }
2341
2342 list_del(&gr->link);
2343 kfree(gr);
2344 }
2345
2346 mutex_unlock(&mmc_test_lock);
2347}
2348
2349static LIST_HEAD(mmc_test_file_test);
2350
2351static int mtf_test_show(struct seq_file *sf, void *data)
1928{ 2352{
2353 struct mmc_card *card = (struct mmc_card *)sf->private;
2354 struct mmc_test_general_result *gr;
2355
1929 mutex_lock(&mmc_test_lock); 2356 mutex_lock(&mmc_test_lock);
2357
2358 list_for_each_entry(gr, &mmc_test_result, link) {
2359 struct mmc_test_transfer_result *tr;
2360
2361 if (gr->card != card)
2362 continue;
2363
2364 seq_printf(sf, "Test %d: %d\n", gr->testcase + 1, gr->result);
2365
2366 list_for_each_entry(tr, &gr->tr_lst, link) {
2367 seq_printf(sf, "%u %d %lu.%09lu %u %u.%02u\n",
2368 tr->count, tr->sectors,
2369 (unsigned long)tr->ts.tv_sec,
2370 (unsigned long)tr->ts.tv_nsec,
2371 tr->rate, tr->iops / 100, tr->iops % 100);
2372 }
2373 }
2374
1930 mutex_unlock(&mmc_test_lock); 2375 mutex_unlock(&mmc_test_lock);
1931 2376
1932 return 0; 2377 return 0;
1933} 2378}
1934 2379
1935static ssize_t mmc_test_store(struct device *dev, 2380static int mtf_test_open(struct inode *inode, struct file *file)
1936 struct device_attribute *attr, const char *buf, size_t count)
1937{ 2381{
1938 struct mmc_card *card; 2382 return single_open(file, mtf_test_show, inode->i_private);
2383}
2384
2385static ssize_t mtf_test_write(struct file *file, const char __user *buf,
2386 size_t count, loff_t *pos)
2387{
2388 struct seq_file *sf = (struct seq_file *)file->private_data;
2389 struct mmc_card *card = (struct mmc_card *)sf->private;
1939 struct mmc_test_card *test; 2390 struct mmc_test_card *test;
1940 int testcase; 2391 char lbuf[12];
2392 long testcase;
2393
2394 if (count >= sizeof(lbuf))
2395 return -EINVAL;
1941 2396
1942 card = container_of(dev, struct mmc_card, dev); 2397 if (copy_from_user(lbuf, buf, count))
2398 return -EFAULT;
2399 lbuf[count] = '\0';
1943 2400
1944 testcase = simple_strtol(buf, NULL, 10); 2401 if (strict_strtol(lbuf, 10, &testcase))
2402 return -EINVAL;
1945 2403
1946 test = kzalloc(sizeof(struct mmc_test_card), GFP_KERNEL); 2404 test = kzalloc(sizeof(struct mmc_test_card), GFP_KERNEL);
1947 if (!test) 2405 if (!test)
1948 return -ENOMEM; 2406 return -ENOMEM;
1949 2407
2408 /*
2409 * Remove all test cases associated with given card. Thus we have only
2410 * actual data of the last run.
2411 */
2412 mmc_test_free_result(card);
2413
1950 test->card = card; 2414 test->card = card;
1951 2415
1952 test->buffer = kzalloc(BUFFER_SIZE, GFP_KERNEL); 2416 test->buffer = kzalloc(BUFFER_SIZE, GFP_KERNEL);
@@ -1973,16 +2437,78 @@ static ssize_t mmc_test_store(struct device *dev,
1973 return count; 2437 return count;
1974} 2438}
1975 2439
1976static DEVICE_ATTR(test, S_IWUSR | S_IRUGO, mmc_test_show, mmc_test_store); 2440static const struct file_operations mmc_test_fops_test = {
2441 .open = mtf_test_open,
2442 .read = seq_read,
2443 .write = mtf_test_write,
2444 .llseek = seq_lseek,
2445 .release = single_release,
2446};
2447
2448static void mmc_test_free_file_test(struct mmc_card *card)
2449{
2450 struct mmc_test_dbgfs_file *df, *dfs;
2451
2452 mutex_lock(&mmc_test_lock);
2453
2454 list_for_each_entry_safe(df, dfs, &mmc_test_file_test, link) {
2455 if (card && df->card != card)
2456 continue;
2457 debugfs_remove(df->file);
2458 list_del(&df->link);
2459 kfree(df);
2460 }
2461
2462 mutex_unlock(&mmc_test_lock);
2463}
2464
2465static int mmc_test_register_file_test(struct mmc_card *card)
2466{
2467 struct dentry *file = NULL;
2468 struct mmc_test_dbgfs_file *df;
2469 int ret = 0;
2470
2471 mutex_lock(&mmc_test_lock);
2472
2473 if (card->debugfs_root)
2474 file = debugfs_create_file("test", S_IWUSR | S_IRUGO,
2475 card->debugfs_root, card, &mmc_test_fops_test);
2476
2477 if (IS_ERR_OR_NULL(file)) {
2478 dev_err(&card->dev,
2479 "Can't create file. Perhaps debugfs is disabled.\n");
2480 ret = -ENODEV;
2481 goto err;
2482 }
2483
2484 df = kmalloc(sizeof(struct mmc_test_dbgfs_file), GFP_KERNEL);
2485 if (!df) {
2486 debugfs_remove(file);
2487 dev_err(&card->dev,
2488 "Can't allocate memory for internal usage.\n");
2489 ret = -ENOMEM;
2490 goto err;
2491 }
2492
2493 df->card = card;
2494 df->file = file;
2495
2496 list_add(&df->link, &mmc_test_file_test);
2497
2498err:
2499 mutex_unlock(&mmc_test_lock);
2500
2501 return ret;
2502}
1977 2503
1978static int mmc_test_probe(struct mmc_card *card) 2504static int mmc_test_probe(struct mmc_card *card)
1979{ 2505{
1980 int ret; 2506 int ret;
1981 2507
1982 if ((card->type != MMC_TYPE_MMC) && (card->type != MMC_TYPE_SD)) 2508 if (!mmc_card_mmc(card) && !mmc_card_sd(card))
1983 return -ENODEV; 2509 return -ENODEV;
1984 2510
1985 ret = device_create_file(&card->dev, &dev_attr_test); 2511 ret = mmc_test_register_file_test(card);
1986 if (ret) 2512 if (ret)
1987 return ret; 2513 return ret;
1988 2514
@@ -1993,7 +2519,8 @@ static int mmc_test_probe(struct mmc_card *card)
1993 2519
1994static void mmc_test_remove(struct mmc_card *card) 2520static void mmc_test_remove(struct mmc_card *card)
1995{ 2521{
1996 device_remove_file(&card->dev, &dev_attr_test); 2522 mmc_test_free_result(card);
2523 mmc_test_free_file_test(card);
1997} 2524}
1998 2525
1999static struct mmc_driver mmc_driver = { 2526static struct mmc_driver mmc_driver = {
@@ -2011,6 +2538,10 @@ static int __init mmc_test_init(void)
2011 2538
2012static void __exit mmc_test_exit(void) 2539static void __exit mmc_test_exit(void)
2013{ 2540{
2541 /* Clear stalled data if card is still plugged */
2542 mmc_test_free_result(NULL);
2543 mmc_test_free_file_test(NULL);
2544
2014 mmc_unregister_driver(&mmc_driver); 2545 mmc_unregister_driver(&mmc_driver);
2015} 2546}
2016 2547