summaryrefslogtreecommitdiff
path: root/tests/ext4/android_emmc_perf_tests.sh
blob: 6464312f58e3c32f8c7da77d33ac22fa12da7db2 (plain)
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