Add linux zpios support
[zfs.git] / scripts / zpios-survey.sh
diff --git a/scripts/zpios-survey.sh b/scripts/zpios-survey.sh
new file mode 100755 (executable)
index 0000000..cb751b4
--- /dev/null
@@ -0,0 +1,215 @@
+#!/bin/bash
+#
+# Wrapper script for easily running a survey of zpios based tests
+#
+
+basedir="$(dirname $0)"
+
+SCRIPT_COMMON=common.sh
+if [ -f "${basedir}/${SCRIPT_COMMON}" ]; then
+. "${basedir}/${SCRIPT_COMMON}"
+else
+echo "Missing helper script ${SCRIPT_COMMON}" && exit 1
+fi
+
+PROG=zpios-survey.sh
+
+usage() {
+cat << EOF
+USAGE:
+$0 [hvp] <-c config> <-t test>
+
+DESCRIPTION:
+        Helper script for easy zpios survey benchmarking.
+
+OPTIONS:
+        -h      Show this message
+        -v      Verbose
+        -p      Enable profiling
+        -c      Zpool configuration
+        -t      Zpios test
+        -l      Zpios survey log
+
+EOF
+}
+
+print_header() {
+tee -a ${ZPIOS_SURVEY_LOG} << EOF
+
+================================================================
+Test: $1
+EOF
+}
+
+# Baseline performance for an out of the box config with no manual tuning.
+# Ideally, we want everything to be automatically tuned for your system and
+# for this to perform reasonably well.
+zpios_survey_base() {
+       TEST_NAME="${ZPOOL_CONFIG}+${ZPIOS_TEST}+baseline"
+       print_header ${TEST_NAME}
+
+       ${ZFS_SH} ${VERBOSE_FLAG} | \
+               tee -a ${ZPIOS_SURVEY_LOG}
+       ${ZPIOS_SH} ${VERBOSE_FLAG} -c ${ZPOOL_CONFIG} -t ${ZPIOS_TEST} | \
+               tee -a ${ZPIOS_SURVEY_LOG}
+       ${ZFS_SH} -u ${VERBOSE_FLAG} | \
+               tee -a ${ZPIOS_SURVEY_LOG}
+}
+
+# Disable ZFS's prefetching.  For some reason still not clear to me
+# current prefetching policy is quite bad for a random workload.
+# Allowing the algorithm to detect a random workload and not do 
+# anything may be the way to address this issue.
+zpios_survey_prefetch() {
+       TEST_NAME="${ZPOOL_CONFIG}+${ZPIOS_TEST}+prefetch"
+       print_header ${TEST_NAME}
+
+       ${ZFS_SH} ${VERBOSE_FLAG}               \
+               tee -a ${ZPIOS_SURVEY_LOG}
+       ${ZPIOS_SH} ${VERBOSE_FLAG} -c ${ZPOOL_CONFIG} -t ${ZPIOS_TEST} \
+               -o "--noprefetch" |                                    \
+               tee -a ${ZPIOS_SURVEY_LOG}
+       ${ZFS_SH} -u ${VERBOSE_FLAG} | \
+               tee -a ${ZPIOS_SURVEY_LOG}
+}
+
+# Simulating a zerocopy IO path should improve performance by freeing up
+# lots of CPU which is wasted move data between buffers.
+zpios_survey_zerocopy() {
+       TEST_NAME="${ZPOOL_CONFIG}+${ZPIOS_TEST}+zerocopy"
+       print_header ${TEST_NAME}
+
+       ${ZFS_SH} ${VERBOSE_FLAG} | \
+               tee -a ${ZPIOS_SURVEY_LOG}
+       ${ZPIOS_SH} ${VERBOSE_FLAG} -c ${ZPOOL_CONFIG} -t ${ZPIOS_TEST} \
+               -o "--zerocopy" |                                      \
+               tee -a ${ZPIOS_SURVEY_LOG}
+       ${ZFS_SH} -u ${VERBOSE_FLAG} | \
+               tee -a ${ZPIOS_SURVEY_LOG}
+}
+
+# Disabling checksumming should show some (if small) improvement
+# simply due to freeing up a modest amount of CPU.
+zpios_survey_checksum() {
+       TEST_NAME="${ZPOOL_CONFIG}+${ZPIOS_TEST}+checksum"
+       print_header ${TEST_NAME}
+
+       ${ZFS_SH} ${VERBOSE_FLAG} | \
+               tee -a ${ZPIOS_SURVEY_LOG}
+       ${ZPIOS_SH} ${VERBOSE_FLAG} -c ${ZPOOL_CONFIG} -t ${ZPIOS_TEST} \
+               -s "set checksum=off" |                                \
+               tee -a ${ZPIOS_SURVEY_LOG}
+       ${ZFS_SH} -u ${VERBOSE_FLAG} | \
+               tee -a ${ZPIOS_SURVEY_LOG}
+}
+
+# Increasing the pending IO depth also seems to improve things likely
+# at the expense of latency.  This should be explored more because I'm
+# seeing a much bigger impact there that I would have expected.  There
+# may be some low hanging fruit to be found here.
+zpios_survey_pending() {
+       TEST_NAME="${ZPOOL_CONFIG}+${ZPIOS_TEST}+pending"
+       print_header ${TEST_NAME}
+
+       ${ZFS_SH} ${VERBOSE_FLAG}                  \
+               zfs="zfs_vdev_max_pending=1024" | \
+               tee -a ${ZPIOS_SURVEY_LOG}
+       ${ZPIOS_SH} ${VERBOSE_FLAG} -c ${ZPOOL_CONFIG} -t ${ZPIOS_TEST} | \
+               tee -a ${ZPIOS_SURVEY_LOG}
+       ${ZFS_SH} -u ${VERBOSE_FLAG} | \
+               tee -a ${ZPIOS_SURVEY_LOG}
+}
+
+# To avoid memory fragmentation issues our slab implementation can be
+# based on a virtual address space.  Interestingly, we take a pretty
+# substantial performance penalty for this somewhere in the low level
+# IO drivers.  If we back the slab with kmem pages we see far better
+# read performance numbers at the cost of memory fragmention and general
+# system instability due to large allocations.  This may be because of
+# an optimization in the low level drivers due to the contigeous kmem
+# based memory.  This needs to be explained.  The good news here is that
+# with zerocopy interfaces added at the DMU layer we could gaurentee
+# kmem based memory for a pool of pages.
+#
+# 0x100 = KMC_KMEM - Force kmem_* based slab
+# 0x200 = KMC_VMEM - Force vmem_* based slab
+zpios_survey_kmem() {
+       TEST_NAME="${ZPOOL_CONFIG}+${ZPIOS_TEST}+kmem"
+       print_header ${TEST_NAME}
+
+       ${ZFS_SH} ${VERBOSE_FLAG}             \  
+               zfs="zio_bulk_flags=0x100" | \
+               tee -a ${ZPIOS_SURVEY_LOG}
+       ${ZPIOS_SH} ${VERBOSE_FLAG} -c ${ZPOOL_CONFIG} -t ${ZPIOS_TEST} | \
+               tee -a ${ZPIOS_SURVEY_LOG}
+       ${ZFS_SH} -u ${VERBOSE_FLAG} | \
+               tee -a ${ZPIOS_SURVEY_LOG}
+}
+
+# Apply all possible turning concurrently to get a best case number
+zpios_survey_all() {
+       TEST_NAME="${ZPOOL_CONFIG}+${ZPIOS_TEST}+all"
+       print_header ${TEST_NAME}
+
+       ${ZFS_SH} ${VERBOSE_FLAG}                \  
+               zfs="zfs_vdev_max_pending=1024" \
+               zfs="zio_bulk_flags=0x100" |    \
+               tee -a ${ZPIOS_SURVEY_LOG}
+       ${ZPIOS_SH} ${VERBOSE_FLAG} -c ${ZPOOL_CONFIG} -t ${ZPIOS_TEST} \
+               -o "--noprefetch --zerocopy"                           \
+               -s "set checksum=off" |                                \
+               tee -a ${ZPIOS_SURVEY_LOG}
+       ${ZFS_SH} -u ${VERBOSE_FLAG} | \
+               tee -a ${ZPIOS_SURVEY_LOG}
+}
+
+
+PROFILE=
+ZPOOL_NAME=zpios-survey
+ZPOOL_CONFIG=zpool-config.sh
+ZPIOS_TEST=zpios-test.sh
+ZPIOS_SURVEY_LOG=/dev/null
+
+while getopts 'hvpc:t:l:' OPTION; do
+       case $OPTION in
+       h)
+               usage
+               exit 1
+               ;;
+       v)
+               VERBOSE=1
+               VERBOSE_FLAG="-v"
+               ;;
+       p)
+               PROFILE=1
+               PROFILE_FLAG="-p"
+               ;;
+       c)
+               ZPOOL_CONFIG=${OPTARG}
+               ;;
+       t)
+               ZPIOS_TEST=${OPTARG}
+               ;;
+       l)
+               ZPIOS_SURVEY_LOG=${OPTARG}
+               ;;
+       ?)
+               usage
+               exit
+               ;;
+       esac
+done
+
+if [ $(id -u) != 0 ]; then
+       die "Must run as root"
+fi
+
+zpios_survey_base
+zpios_survey_prefetch
+zpios_survey_zerocopy
+zpios_survey_checksum
+zpios_survey_pending
+zpios_survey_kmem
+zpios_survey_all
+
+exit 0