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