1#!/bin/bash
2
3PERF="rand_emmc_perf"
4PERF_LOC=/dev
5STATS_FILE="/data/local/tmp/stats_test"
6STATS_MODE=0
7USERBUILD_MODE=0
8
9if [ "$1" = "-s" ]
10then
11  STATS_MODE=1
12elif [ "$1" = "-u" ]
13then
14  USERBUILD_MODE=1
15fi
16
17if [ ! -r "$PERF" ]
18then
19  echo "Cannot read $PERF test binary"
20fi
21
22if ! adb shell true >/dev/null 2>&1
23then
24  echo "No device detected over adb"
25fi
26
27HARDWARE=`adb shell getprop ro.hardware | tr -d "\r"`
28
29case "$HARDWARE" in
30  tuna | steelhead)
31    CPUFREQ="/sys/devices/system/cpu/cpu0/cpufreq"
32    CACHE="/dev/block/platform/omap/omap_hsmmc.0/by-name/cache"
33    MMCDEV="mmcblk0"
34    ;;
35
36  stingray | wingray)
37    CPUFREQ="/sys/devices/system/cpu/cpu0/cpufreq"
38    CACHE="/dev/block/platform/sdhci-tegra.3/by-name/cache"
39    MMCDEV="mmcblk0"
40    ;;
41
42  herring)
43    echo "This test will wipe the userdata partition on $HARDWARE devices."
44    read -p "Do you want to proceed? " ANSWER
45
46    if [ "$ANSWER" != "yes" ]
47    then
48      echo "aborting test"
49      exit 1
50    fi
51
52    CPUFREQ="/sys/devices/system/cpu/cpu0/cpufreq"
53    CACHE="/dev/block/platform/s3c-sdhci.0/by-name/userdata"
54    MMCDEV="mmcblk0"
55    ;;
56
57  grouper)
58    CPUFREQ="/sys/devices/system/cpu/cpu0/cpufreq"
59    CACHE="/dev/block/platform/sdhci-tegra.3/by-name/CAC"
60    MMCDEV="mmcblk0"
61    ;;
62
63  manta)
64    CPUFREQ="/sys/devices/system/cpu/cpu0/cpufreq"
65    CACHE="/dev/block/platform/dw_mmc.0/by-name/cache"
66    MMCDEV="mmcblk0"
67    ;;
68
69  flo)
70    CPUFREQ="/sys/devices/system/cpu/cpu0/cpufreq"
71    CACHE="dev/block/platform/msm_sdcc.1/by-name/cache"
72    MMCDEV="mmcblk0"
73    ;;
74
75  *)
76    echo "Unknown hardware $HARDWARE.  Exiting."
77    exit 1
78esac
79
80# We cannot stop and unmount stuff in a user build, so don't even try.
81if [ "$USERBUILD_MODE" -eq 0 ]
82then
83  # prepare the device
84  adb root
85  adb wait-for-device
86  adb push "$PERF" /dev
87  adb shell stop
88  adb shell stop sdcard
89  adb shell stop ril-daemon
90  adb shell stop media
91  adb shell stop drm
92  adb shell stop keystore
93  adb shell stop tf_daemon
94  adb shell stop bluetoothd
95  adb shell stop hciattach
96  adb shell stop p2p_supplicant
97  adb shell stop wpa_supplicant
98  adb shell stop mobicore
99  adb shell umount /sdcard >/dev/null 2>&1
100  adb shell umount /mnt/sdcard >/dev/null 2>&1
101  adb shell umount /mnt/shell/sdcard0 >/dev/null 2>&1
102  adb shell umount /mnt/shell/emulated >/dev/null 2>&1
103  adb shell umount /cache >/dev/null 2>&1
104  if [ "$STATS_MODE" -ne 1 ]
105  then
106    adb shell umount /data >/dev/null 2>&1
107  fi
108else
109  # For user builds, put the $PERF binary in /data/local/tmp,
110  # and also setup CACHE to point to a file on /data/local/tmp,
111  # and create that file
112  PERF_LOC=/data/local/tmp
113  adb push "$PERF" "$PERF_LOC"
114  CACHE=/data/local/tmp/testfile
115  echo "Creating testfile for user builds (can take up to 60 seconds)"
116  adb shell dd if=/dev/zero of=$CACHE bs=1048576 count=512
117fi
118
119# Add more services here that other devices need to stop.
120# So far, this list is sufficient for:
121#   Prime
122
123if [ "$USERBUILD_MODE" -eq 0 ]
124then
125  # At this point, the device is quiescent, need to crank up the cpu speed,
126  # then run tests
127  adb shell "cat $CPUFREQ/cpuinfo_max_freq > $CPUFREQ/scaling_max_freq"
128  adb shell "cat $CPUFREQ/cpuinfo_max_freq > $CPUFREQ/scaling_min_freq"
129fi
130
131# Start the tests
132
133if [ "$STATS_MODE" -eq 1 ]
134then
135  # This test looks for the average and max random write times for the emmc
136  # chip.  It should be run with the emmc chip full for worst case numbers,
137  # and after fstrim for best case numbers.  So first fill the chip, twice,
138  # then run the test, then remove the large file, run fstrim, and run the
139  # test again.
140
141  # Remove the test file if it exists, then make it anew.
142  echo "Filling userdata"
143  adb shell rm  -f "$STATS_FILE"
144  adb shell dd if=/dev/zero of="$STATS_FILE" bs=1048576
145  adb shell sync
146
147  # Do it again to make sure to fill up all the reserved blocks used for
148  # wear levelling, plus any unused blocks in the other partitions.  Yes,
149  # this is not precise, just a good heuristic.
150  echo "Filling userdata again"
151  adb shell rm "$STATS_FILE"
152  adb shell sync
153  adb shell dd if=/dev/zero of="$STATS_FILE" bs=1048576
154  adb shell sync
155
156  # Run the test
157  echo "Running stats test after filling emmc chip"
158  adb shell /dev/$PERF -w -o -s 20000 -f /dev/full_stats 400 "$CACHE"
159
160  # Remove the file, and have vold do fstrim
161  adb shell rm "$STATS_FILE"
162  adb shell sync
163  # Make sure fstrim knows there is work to do
164  sleep 10
165
166  # Get the current number of FSTRIM complete lines in thh logcat
167  ORIGCNT=`adb shell logcat -d | grep -c "Finished fstrim work"`
168
169  # Attempt to start fstrim
170  OUT=`adb shell vdc fstrim dotrim | grep "Command not recognized"`
171
172  if [ -z "$OUT" ]
173  then
174    # Wait till we see another fstrim finished line
175    sleep 10
176    let T=10
177    NEWCNT=`adb shell logcat -d |grep -c "Finished fstrim work"`
178    while [ "$NEWCNT" -eq "$ORIGCNT" ]
179    do
180      sleep 10
181      let T=T+10
182      if [ "$T" -ge 300 ]
183      then
184        echo "Error: FSTRIM did not complete in 300 seconds, continuing"
185        break
186      fi
187      NEWCNT=`adb shell logcat -d |grep -c "Finished fstrim work"`
188    done
189
190    echo "FSTRIM took "$T" seconds"
191
192    # Run the test again
193    echo "Running test after fstrim"
194    adb shell /dev/$PERF -w -o -s 20000 -f /dev/fstrimmed_stats 400 "$CACHE"
195
196    # Retrieve the full data logs
197    adb pull /dev/fstrimmed_stats $HARDWARE-fstrimmed_stats
198    adb pull /dev/full_stats $HARDWARE-full_stats
199  else
200    echo "Device doesn't support fstrim, not running test a second time"
201  fi
202
203else
204
205  # Sequential read test
206  if [ "$USERBUILD_MODE" -eq 0 ]
207  then
208    # There is no point in running this in USERBUILD mode, because
209    # we can't drop caches, and the numbers are ludicrously high
210    for I in 1 2 3
211    do
212      adb shell "echo 3 > /proc/sys/vm/drop_caches"
213      echo "Sequential read test $I"
214      adb shell dd if="$CACHE" of=/dev/null bs=1048576 count=200
215    done
216  fi
217
218  # Sequential write test
219  for I in 1 2 3
220  do
221    echo "Sequential write test $I"
222    # It's unclear if this test is useful on USERBUILDS, given the
223    # caching on the filesystem
224    adb shell dd if=/dev/zero conv=notrunc of="$CACHE" bs=1048576 count=200
225  done
226
227  if [ "$USERBUILD_MODE" -eq 0 ]
228  then
229    # Random read tests require that we read from a much larger range of offsets
230    # into the emmc chip than the write test.  If we only read though 100 Megabytes
231    # (and with a read-ahead of 128K), we quickly fill the buffer cache with 100
232    # Megabytes of data, and subsequent reads are nearly instantaneous.  Since
233    # reading is non-destructive, and we've never shipped a device with less than
234    # 8 Gbytes, for this test we read from the raw emmc device, and randomly seek
235    # in the first 6 Gbytes.  That is way more memory than any device we currently
236    # have and it should keep the cache from being poluted with entries from
237    # previous random reads.
238    #
239    # Also, test with the read-ahead set very low at 4K, and at the default
240
241    # Random read test, 4K read-ahead
242    ORIG_READAHEAD=`adb shell cat /sys/block/$MMCDEV/queue/read_ahead_kb | tr -d "\r"`
243    adb shell "echo 4 > /sys/block/$MMCDEV/queue/read_ahead_kb"
244    for I in 1 2 3
245    do
246      adb shell "echo 3 > /proc/sys/vm/drop_caches"
247      echo "Random read (4K read-ahead) test $I"
248      adb shell "$PERF_LOC"/"$PERF" -r 6000 "/dev/block/$MMCDEV"
249    done
250
251    # Random read test, default read-ahead
252    adb shell "echo $ORIG_READAHEAD > /sys/block/$MMCDEV/queue/read_ahead_kb"
253    for I in 1 2 3
254    do
255      adb shell "echo 3 > /proc/sys/vm/drop_caches"
256      echo "Random read (default read-ahead of ${ORIG_READAHEAD}K) test $I"
257      adb shell "$PERF_LOC"/"$PERF" -r 6000 "/dev/block/$MMCDEV"
258    done
259  fi
260
261  # Random write test
262  for I in 1 2 3
263  do
264    echo "Random write test $I"
265    adb shell "$PERF_LOC"/"$PERF" -w 100 "$CACHE"
266  done
267
268  # Random write test with O_SYNC
269  for I in 1 2 3
270  do
271    echo "Random write with o_sync test $I"
272    adb shell "$PERF_LOC"/"$PERF" -w -o 100 "$CACHE"
273  done
274fi
275
276# cleanup
277if [ "$USERBUILD_MODE" -eq 0 ]
278then
279  # Make a new empty /cache filesystem
280  adb shell make_ext4fs -w "$CACHE"
281else
282  adb shell rm -f "$CACHE" "$PERF_LOC"/"$PERF"
283fi
284
285