12633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall/* 22633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall * Copyright (C) 2010 The Android Open Source Project 32633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall * 42633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall * Licensed under the Apache License, Version 2.0 (the "License"); 52633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall * you may not use this file except in compliance with the License. 62633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall * You may obtain a copy of the License at 72633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall * 82633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall * http://www.apache.org/licenses/LICENSE-2.0 92633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall * 102633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall * Unless required by applicable law or agreed to in writing, software 112633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall * distributed under the License is distributed on an "AS IS" BASIS, 122633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall * See the License for the specific language governing permissions and 142633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall * limitations under the License. 152633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall */ 162633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall 172633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall/* A simple test of emmc random read and write performance. When testing write 182633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall * performance, try it twice, once with O_SYNC compiled in, and once with it commented 192633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall * out. Without O_SYNC, the close(2) blocks until all the dirty buffers are written 202633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall * out, but the numbers tend to be higher. 212633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall */ 2232243fadeab8cf244861e3df89744b78ba3eff92Ken Sumrall 2332243fadeab8cf244861e3df89744b78ba3eff92Ken Sumrall#define _LARGEFILE64_SOURCE 242633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall#include <string.h> 252633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall#include <stdio.h> 262633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall#include <sys/types.h> 272633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall#include <sys/stat.h> 282633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall#include <fcntl.h> 292633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall#include <sys/time.h> 302633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall#include <stdlib.h> 3132243fadeab8cf244861e3df89744b78ba3eff92Ken Sumrall#include <unistd.h> 322633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall 332633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall#define TST_BLK_SIZE 4096 342633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall/* Number of seconds to run the test */ 352633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall#define TEST_LEN 10 362633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall 372633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrallstatic void usage(void) { 382633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall fprintf(stderr, "Usage: rand_emmc_perf [ -r | -w ] [-o] <size_in_mb> <block_dev>\n"); 392633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall exit(1); 402633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall} 412633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall 422633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrallint main(int argc, char *argv[]) 432633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall{ 44ecb600d0d9de4eacfd619dfe380a94af1abee0ddKen Sumrall unsigned long long max_blocks; 452633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall int fd, fd2, write_mode = 0, iops = 0; 462633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall struct timeval start, end, res; 472633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall unsigned int seed; 482633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall char buf[TST_BLK_SIZE] = { 0 }; 492633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall int c; 502633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall int o_sync = 0; 512633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall 522633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall while ((c = getopt(argc, argv, "+rwo")) != -1) { 532633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall switch (c) { 542633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall case '?': 552633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall default: 562633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall usage(); 572633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall break; 582633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall 592633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall case 'r': 602633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall /* Do nothing, read mode is the default */ 612633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall break; 622633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall 632633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall case 'w': 642633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall write_mode = 1; 652633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall break; 662633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall 672633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall case 'o': 682633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall o_sync = O_SYNC; 692633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall break; 702633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall } 712633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall } 722633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall 732633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall if (o_sync && !write_mode) { 742633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall /* Can only specify o_sync in write mode. Probably doesn't matter, 752633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall * but clear o_sync if in read mode */ 762633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall o_sync = 0; 772633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall } 782633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall 792633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall if ((argc - optind) != 2) { 802633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall usage(); 812633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall } 822633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall 832633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall /* Size is given in megabytes, so compute the number of TST_BLK_SIZE blocks. */ 8432243fadeab8cf244861e3df89744b78ba3eff92Ken Sumrall max_blocks = atol(argv[optind]) * ((1024*1024) / TST_BLK_SIZE); 852633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall 8632243fadeab8cf244861e3df89744b78ba3eff92Ken Sumrall if ((fd = open(argv[optind + 1], O_RDWR | o_sync)) < 0) { 8732243fadeab8cf244861e3df89744b78ba3eff92Ken Sumrall fprintf(stderr, "Cannot open block device %s\n", argv[optind + 1]); 882633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall exit(1); 892633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall } 902633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall 9132243fadeab8cf244861e3df89744b78ba3eff92Ken Sumrall fd2 = open("/dev/urandom", O_RDONLY); 922633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall if (fd2 < 0) { 932633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall fprintf(stderr, "Cannot open /dev/urandom\n"); 942633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall } 952633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall if (read(fd2, &seed, sizeof(seed)) != sizeof(seed)) { 962633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall fprintf(stderr, "Cannot read /dev/urandom\n"); 972633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall } 982633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall close(fd2); 992633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall srand(seed); 1002633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall 1012633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall res.tv_sec = 0; 1022633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall gettimeofday(&start, 0); 1032633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall while (res.tv_sec < TEST_LEN) { 1042633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall if (lseek64(fd, (rand() % max_blocks) * TST_BLK_SIZE, SEEK_SET) < 0) { 1052633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall fprintf(stderr, "lseek64 failed\n"); 1062633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall } 1072633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall if (write_mode) { 1082633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall if (write(fd, buf, sizeof(buf)) != sizeof(buf)) { 1092633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall fprintf(stderr, "Short write\n"); 1102633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall } 1112633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall } else { 1122633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall if (read(fd, buf, sizeof(buf)) != sizeof(buf)) { 1132633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall fprintf(stderr, "Short read\n"); 1142633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall } 1152633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall } 1162633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall iops++; 1172633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall gettimeofday(&end, 0); 1182633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall timersub(&end, &start, &res); 1192633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall } 1202633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall close(fd); 1212633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall 1222633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall /* The close can take a while when in write_mode as buffers are flushed. 1232633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall * So get the time again. */ 1242633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall gettimeofday(&end, 0); 1252633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall timersub(&end, &start, &res); 1262633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall 1272633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall printf("%d iops/sec\n", iops / (int) res.tv_sec); 1282633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall 1292633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall exit(0); 1302633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall} 1312633ce5ca5024d5565c9068c29ec39a8c3ed10e9Ken Sumrall 132