diff options
Diffstat (limited to 'tests/mtd-tests/flash_speed.c')
| -rw-r--r-- | tests/mtd-tests/flash_speed.c | 117 |
1 files changed, 59 insertions, 58 deletions
diff --git a/tests/mtd-tests/flash_speed.c b/tests/mtd-tests/flash_speed.c index 3489233..3319452 100644 --- a/tests/mtd-tests/flash_speed.c +++ b/tests/mtd-tests/flash_speed.c @@ -23,6 +23,7 @@ * Author: Adrian Hunter <adrian.hunter@nokia.com> */ #define DESTRUCTIVE 0x01 +#define CONTINOUS 0x02 #define PROGRAM_NAME "flash_speed" @@ -47,7 +48,9 @@ static const char *mtddev; static libmtd_t mtd_desc; static int fd; +static int npages = 1; static int peb=-1, count=-1, skip=-1, flags=0, speb=-1; +static bool continuous = false; static struct timespec start, finish; static int pgsize, pgcnt; static int goodebcnt; @@ -59,6 +62,7 @@ static const struct option options[] = { { "count", required_argument, NULL, 'c' }, { "skip", required_argument, NULL, 's' }, { "sec-peb", required_argument, NULL, 'k' }, + { "continuous", no_argument, NULL, 'C' }, { NULL, 0, NULL, 0 }, }; @@ -72,7 +76,8 @@ static NORETURN void usage(int status) " -c, --count <num> Number of erase blocks to use (default: all)\n" " -s, --skip <num> Number of blocks to skip\n" " -d, --destructive Run destructive (erase and write speed) tests\n" - " -k, --sec-peb <num> Start of secondary block to measure RWW latency (requires -d)\n", + " -k, --sec-peb <num> Start of secondary block to measure RWW latency (requires -d)\n" + " -C, --continuous Increase the number of consecutive pages gradually\n", status==EXIT_SUCCESS ? stdout : stderr); exit(status); } @@ -96,7 +101,7 @@ static void process_options(int argc, char **argv) int c; while (1) { - c = getopt_long(argc, argv, "hb:c:s:dk:", options, NULL); + c = getopt_long(argc, argv, "hb:c:s:dk:C", options, NULL); if (c == -1) break; @@ -136,6 +141,9 @@ static void process_options(int argc, char **argv) if (speb < 0) goto failarg; break; + case 'C': + continuous = true; + break; default: exit(EXIT_FAILURE); } @@ -182,7 +190,7 @@ static int read_eraseblock(int ebnum) { int err = mtd_read(&mtd, fd, ebnum, 0, iobuf, mtd.eb_size); if (err) - fprintf(stderr, "Error writing block %d!\n", ebnum); + fprintf(stderr, "Error reading block %d!\n", ebnum); return err; } @@ -232,46 +240,21 @@ static int write_eraseblock_by_2pages(int ebnum) return err; } -static int read_eraseblock_by_page(int ebnum) +static int read_eraseblock_by_npages(int ebnum) { - void *buf = iobuf; - int i, err = 0; - - for (i = 0; i < pgcnt; ++i) { - err = mtd_read(&mtd, fd, ebnum, i * pgsize, iobuf, pgsize); - if (err) { - fprintf(stderr, "Error reading block %d, page %d!\n", - ebnum, i); - break; - } - buf += pgsize; - } - - return err; -} - -static int read_eraseblock_by_2pages(int ebnum) -{ - int i, n = pgcnt / 2, err = 0; - size_t sz = pgsize * 2; + int i, n = pgcnt / npages, err = 0; + size_t sz = pgsize * npages; void *buf = iobuf; for (i = 0; i < n; ++i) { err = mtd_read(&mtd, fd, ebnum, i * sz, iobuf, sz); if (err) { - fprintf(stderr, "Error reading block %d, page %d + %d!\n", - ebnum, i*2, i*2+1); + fprintf(stderr, "Error reading block %d, page [%d-%d]!\n", + ebnum, i*npages, (i*npages) + npages- 1); return err; } buf += sz; } - if (pgcnt % 2) { - err = mtd_read(&mtd, fd, ebnum, i * sz, iobuf, pgsize); - if (err) { - fprintf(stderr, "Error reading block %d, page %d!\n", - ebnum, i*2); - } - } return err; } @@ -296,14 +279,17 @@ static long calc_duration(struct timespec *start, struct timespec *finish) return ms; } -static long calc_speed(struct timespec *start, struct timespec *finish) +static long calc_speed(struct timespec *start, struct timespec *finish, + int pages_per_set) { long ms = calc_duration(start, finish); + int sets_in_eb = pgcnt / pages_per_set; + size_t sz = pgsize * pages_per_set * sets_in_eb; if (ms <= 0) return 0; - return ((long)goodebcnt * (mtd.eb_size / 1024L) * 1000L) / ms; + return ((long)goodebcnt * (sz / 1024L) * 1000L) / ms; } static void scan_for_bad_eraseblocks(unsigned int eb, int ebcnt, int ebskip) @@ -364,7 +350,7 @@ static void *op_thread(void *ptr) return (void *)err; } -#define TIME_OP_PER_PEB( op )\ +#define TIME_OP_PER_PEB( op, npages ) \ start_timing(&start);\ for (i = 0; i < count; ++i) {\ if (bbt[i])\ @@ -374,7 +360,7 @@ static void *op_thread(void *ptr) goto out;\ }\ stop_timing(&finish);\ - speed = calc_speed(&start, &finish) + speed = calc_speed(&start, &finish, npages) int main(int argc, char **argv) { @@ -435,13 +421,13 @@ int main(int argc, char **argv) goto out; puts("testing eraseblock write speed"); - TIME_OP_PER_PEB(write_eraseblock); + TIME_OP_PER_PEB(write_eraseblock, 1); printf("eraseblock write speed is %ld KiB/s\n", speed); } /* Read all eraseblocks, 1 eraseblock at a time */ puts("testing eraseblock read speed"); - TIME_OP_PER_PEB(read_eraseblock); + TIME_OP_PER_PEB(read_eraseblock, 1); printf("eraseblock read speed is %ld KiB/s\n", speed); /* Write all eraseblocks, 1 page at a time */ @@ -451,30 +437,45 @@ int main(int argc, char **argv) goto out; puts("testing page write speed"); - TIME_OP_PER_PEB(write_eraseblock_by_page); + TIME_OP_PER_PEB(write_eraseblock_by_page, 1); printf("page write speed is %ld KiB/s\n", speed); } /* Read all eraseblocks, 1 page at a time */ puts("testing page read speed"); - TIME_OP_PER_PEB(read_eraseblock_by_page); + npages = 1; + TIME_OP_PER_PEB(read_eraseblock_by_npages, npages); printf("page read speed is %ld KiB/s\n", speed); - /* Write all eraseblocks, 2 pages at a time */ - if (flags & DESTRUCTIVE) { - err = erase_good_eraseblocks(peb, count, skip); - if (err) - goto out; + if (continuous) { + /* Write all eraseblocks, 2 pages at a time */ + if (flags & DESTRUCTIVE) { + err = erase_good_eraseblocks(peb, count, skip); + if (err) + goto out; - puts("testing 2 page write speed"); - TIME_OP_PER_PEB(write_eraseblock_by_2pages); - printf("2 page write speed is %ld KiB/s\n", speed); - } + puts("testing 2 page write speed"); + TIME_OP_PER_PEB(write_eraseblock_by_2pages, 2); + printf("2 page write speed is %ld KiB/s\n", speed); + } - /* Read all eraseblocks, 2 pages at a time */ - puts("testing 2 page read speed"); - TIME_OP_PER_PEB(read_eraseblock_by_2pages); - printf("2 page read speed is %ld KiB/s\n", speed); + /* Read all eraseblocks, N pages at a time */ + puts("testing multiple pages read speed"); + for (npages = 2; npages <= 16 && npages <= pgcnt; npages++) { + TIME_OP_PER_PEB(read_eraseblock_by_npages, npages); + printf("%d page read speed is %ld KiB/s\n", npages, speed); + } + if (pgcnt >= 32) { + npages = 32; + TIME_OP_PER_PEB(read_eraseblock_by_npages, npages); + printf("%d page read speed is %ld KiB/s\n", npages, speed); + } + if (pgcnt >= 64) { + npages = 64; + TIME_OP_PER_PEB(read_eraseblock_by_npages, npages); + printf("%d page read speed is %ld KiB/s\n", npages, speed); + } + } /* Erase all eraseblocks */ if (flags & DESTRUCTIVE) { @@ -484,12 +485,12 @@ int main(int argc, char **argv) if (err) goto out; stop_timing(&finish); - speed = calc_speed(&start, &finish); + speed = calc_speed(&start, &finish, 1); printf("erase speed is %ld KiB/s\n", speed); } /* Multi-block erase all eraseblocks */ - if (!skip) { + if (flags & DESTRUCTIVE && !skip) { for (k = 1; k < 7; ++k) { blocks = 1 << k; printf("Testing %dx multi-block erase speed\n", blocks); @@ -508,7 +509,7 @@ int main(int argc, char **argv) i += j; } stop_timing(&finish); - speed = calc_speed(&start, &finish); + speed = calc_speed(&start, &finish, 1); printf("%dx multi-block erase speed is %ld KiB/s\n", blocks, speed); } @@ -517,7 +518,7 @@ int main(int argc, char **argv) /* Write a page and immediately after try to read another page. Report * the latency difference when performed on different banks (NOR only). */ - if (speb >= 0 && mtd.subpage_size == 1) { + if (flags & DESTRUCTIVE && speb >= 0 && mtd.subpage_size == 1) { long rww_duration_w, rww_latency_end; long rww_duration_rnw, rww_duration_r_end; bool rww_r_end_first; |
