Add linux zpios support
[zfs.git] / scripts / zpios-profile / zpios-profile.sh
diff --git a/scripts/zpios-profile/zpios-profile.sh b/scripts/zpios-profile/zpios-profile.sh
new file mode 100755 (executable)
index 0000000..f4f0ee9
--- /dev/null
@@ -0,0 +1,226 @@
+#!/bin/bash
+
+
+PROG=zpios-profile.sh
+
+trap "RUN_DONE=1" SIGHUP
+
+RUN_PHASE=${1}
+RUN_LOG_DIR=${2}
+RUN_ID=${3}
+RUN_DONE=0
+
+POLL_INTERVAL=2.99
+
+# Log these pids, the exact pid numbers will vary from system to system
+# so I harvest pid for all the following type of processes from /proc/<pid>/
+#
+# zio_taskq/#
+# spa_zio_issue/#
+# spa_zio_intr/#
+# txg_quiesce_thr
+# txg_sync_thread
+# txg_timelimit_t
+# arc_reclaim_thr
+# l2arc_feed_thre
+# zpios_io/#
+
+ZIO_TASKQ_PIDS=()
+ZIO_REQ_NUL_PIDS=() 
+ZIO_IRQ_NUL_PIDS=() 
+ZIO_REQ_RD_PIDS=() 
+ZIO_IRQ_RD_PIDS=() 
+ZIO_REQ_WR_PIDS=() 
+ZIO_IRQ_WR_PIDS=()
+ZIO_REQ_FR_PIDS=() 
+ZIO_IRQ_FR_PIDS=()
+ZIO_REQ_CM_PIDS=() 
+ZIO_IRQ_CM_PIDS=()
+ZIO_REQ_CTL_PIDS=() 
+ZIO_IRQ_CTL_PIDS=()
+
+TXG_QUIESCE_PIDS=()
+TXG_SYNC_PIDS=() 
+TXG_TIMELIMIT_PIDS=()
+
+ARC_RECLAIM_PIDS=()
+L2ARC_FEED_PIDS=()
+
+ZPIOS_IO_PIDS=()
+
+show_pids() {
+       echo "* zio_taskq:     { ${ZIO_TASKQ_PIDS[@]} } = ${#ZIO_TASKQ_PIDS[@]}"
+       echo "* zio_req_nul:   { ${ZIO_REQ_NUL_PIDS[@]} } = ${#ZIO_REQ_NUL_PIDS[@]}"
+       echo "* zio_irq_nul:   { ${ZIO_IRQ_NUL_PIDS[@]} } = ${#ZIO_IRQ_NUL_PIDS[@]}"
+       echo "* zio_req_rd:    { ${ZIO_REQ_RD_PIDS[@]} } = ${#ZIO_REQ_RD_PIDS[@]}"
+       echo "* zio_irq_rd:    { ${ZIO_IRQ_RD_PIDS[@]} } = ${#ZIO_IRQ_RD_PIDS[@]}"
+       echo "* zio_req_wr:    { ${ZIO_REQ_WR_PIDS[@]} } = ${#ZIO_REQ_WR_PIDS[@]}"
+       echo "* zio_irq_wr:    { ${ZIO_IRQ_WR_PIDS[@]} } = ${#ZIO_IRQ_WR_PIDS[@]}"
+       echo "* zio_req_fr:    { ${ZIO_REQ_FR_PIDS[@]} } = ${#ZIO_REQ_FR_PIDS[@]}"
+       echo "* zio_irq_fr:    { ${ZIO_IRQ_FR_PIDS[@]} } = ${#ZIO_IRQ_FR_PIDS[@]}"
+       echo "* zio_req_cm:    { ${ZIO_REQ_CM_PIDS[@]} } = ${#ZIO_REQ_CM_PIDS[@]}"
+       echo "* zio_irq_cm:    { ${ZIO_IRQ_CM_PIDS[@]} } = ${#ZIO_IRQ_CM_PIDS[@]}"
+       echo "* zio_req_ctl:   { ${ZIO_REQ_CTL_PIDS[@]} } = ${#ZIO_REQ_CTL_PIDS[@]}"
+       echo "* zio_irq_ctl:   { ${ZIO_IRQ_CTL_PIDS[@]} } = ${#ZIO_IRQ_CTL_PIDS[@]}"
+       echo "* txg_quiesce:   { ${TXG_QUIESCE_PIDS[@]} } = ${#TXG_QUIESCE_PIDS[@]}"
+       echo "* txg_sync:      { ${TXG_SYNC_PIDS[@]} } = ${#TXG_SYNC_PIDS[@]}"
+       echo "* txg_timelimit: { ${TXG_TIMELIMIT_PIDS[@]} } = ${#TXG_TIMELIMIT_PIDS[@]}"
+       echo "* arc_reclaim:   { ${ARC_RECLAIM_PIDS[@]} } = ${#ARC_RECLAIM_PIDS[@]}"
+       echo "* l2arc_feed:    { ${L2ARC_FEED_PIDS[@]} } = ${#L2ARC_FEED_PIDS[@]}"
+       echo "* zpios_io:      { ${ZPIOS_IO_PIDS[@]} } = ${#ZPIOS_IO_PIDS[@]}"
+}
+
+check_pid() {
+       local PID=$1
+       local NAME=$2
+       local TYPE=$3
+       local PIDS=( "$4" )
+        local NAME_STRING=`echo ${NAME} | cut -f1 -d'/'`
+        local NAME_NUMBER=`echo ${NAME} | cut -f2 -d'/'`
+
+       if [ "${NAME_STRING}" == "${TYPE}" ]; then
+               if [ -n "${NAME_NUMBER}" ]; then
+                       PIDS[${NAME_NUMBER}]=${PID}
+               else
+                       PIDS[${#PIDS[@]}]=${PID}
+
+               fi
+       fi
+
+       echo "${PIDS[@]}"
+}
+
+# NOTE: This whole process is crazy slow but it will do for now
+aquire_pids() {
+       echo "--- Aquiring ZFS pids ---"
+
+       for PID in `ls /proc/ | grep [0-9] | sort -n -u`; do
+               if [ ! -e /proc/${PID}/status ]; then
+                       continue
+               fi
+
+               NAME=`cat /proc/${PID}/status  | head -n1 | cut -f2`
+
+               ZIO_TASKQ_PIDS=( `check_pid ${PID} ${NAME} "zio_taskq" \
+                                "$(echo "${ZIO_TASKQ_PIDS[@]}")"` )
+
+               ZIO_REQ_NUL_PIDS=( `check_pid ${PID} ${NAME} "zio_req_nul" \
+                                  "$(echo "${ZIO_REQ_NUL_PIDS[@]}")"` )
+
+               ZIO_IRQ_NUL_PIDS=( `check_pid ${PID} ${NAME} "zio_irq_nul" \
+                                  "$(echo "${ZIO_IRQ_NUL_PIDS[@]}")"` )
+
+               ZIO_REQ_RD_PIDS=( `check_pid ${PID} ${NAME} "zio_req_rd" \
+                                  "$(echo "${ZIO_REQ_RD_PIDS[@]}")"` )
+
+               ZIO_IRQ_RD_PIDS=( `check_pid ${PID} ${NAME} "zio_irq_rd" \
+                                  "$(echo "${ZIO_IRQ_RD_PIDS[@]}")"` )
+
+               ZIO_REQ_WR_PIDS=( `check_pid ${PID} ${NAME} "zio_req_wr" \
+                                  "$(echo "${ZIO_REQ_WR_PIDS[@]}")"` )
+
+               ZIO_IRQ_WR_PIDS=( `check_pid ${PID} ${NAME} "zio_irq_wr" \
+                                  "$(echo "${ZIO_IRQ_WR_PIDS[@]}")"` )
+
+               ZIO_REQ_FR_PIDS=( `check_pid ${PID} ${NAME} "zio_req_fr" \
+                                  "$(echo "${ZIO_REQ_FR_PIDS[@]}")"` )
+
+               ZIO_IRQ_FR_PIDS=( `check_pid ${PID} ${NAME} "zio_irq_fr" \
+                                  "$(echo "${ZIO_IRQ_FR_PIDS[@]}")"` )
+
+               ZIO_REQ_CM_PIDS=( `check_pid ${PID} ${NAME} "zio_req_cm" \
+                                  "$(echo "${ZIO_REQ_CM_PIDS[@]}")"` )
+
+               ZIO_IRQ_CM_PIDS=( `check_pid ${PID} ${NAME} "zio_irq_cm" \
+                                  "$(echo "${ZIO_IRQ_CM_PIDS[@]}")"` )
+
+               ZIO_REQ_CTL_PIDS=( `check_pid ${PID} ${NAME} "zio_req_ctl" \
+                                  "$(echo "${ZIO_REQ_CTL_PIDS[@]}")"` )
+
+               ZIO_IRQ_CTL_PIDS=( `check_pid ${PID} ${NAME} "zio_irq_ctl" \
+                                  "$(echo "${ZIO_IRQ_CTL_PIDS[@]}")"` )
+
+               TXG_QUIESCE_PIDS=( `check_pid ${PID} ${NAME} "txg_quiesce" \
+                                  "$(echo "${TXG_QUIESCE_PIDS[@]}")"` )
+
+               TXG_SYNC_PIDS=( `check_pid ${PID} ${NAME} "txg_sync" \
+                               "$(echo "${TXG_SYNC_PIDS[@]}")"` )
+
+               TXG_TIMELIMIT_PIDS=( `check_pid ${PID} ${NAME} "txg_timelimit" \
+                                    "$(echo "${TXG_TIMELIMIT_PIDS[@]}")"` )
+
+               ARC_RECLAIM_PIDS=( `check_pid ${PID} ${NAME} "arc_reclaim" \
+                                     "$(echo "${ARC_RECLAIM_PIDS[@]}")"` )
+
+               L2ARC_FEED_PIDS=( `check_pid ${PID} ${NAME} "l2arc_feed" \
+                                  "$(echo "${L2ARC_FEED_PIDS[@]}")"` )
+       done
+
+       # Wait for zpios_io threads to start
+       kill -s SIGHUP ${PPID}
+       echo "* Waiting for zpios_io threads to start"
+       while [ ${RUN_DONE} -eq 0 ]; do
+               ZPIOS_IO_PIDS=( `ps ax | grep zpios_io | grep -v grep | \
+                                 sed 's/^ *//g' | cut -f1 -d' '` )
+               if [ ${#ZPIOS_IO_PIDS[@]} -gt 0 ]; then
+                       break;
+               fi
+               sleep 0.1
+       done
+
+       echo "`show_pids`" >${RUN_LOG_DIR}/${RUN_ID}/pids.txt
+}
+
+log_pids() {
+       echo "--- Logging ZFS profile to ${RUN_LOG_DIR}/${RUN_ID}/ ---"
+       ALL_PIDS=( ${ZIO_TASKQ_PIDS[@]}     \
+                   ${ZIO_REQ_NUL_PIDS[@]}   \
+                   ${ZIO_IRQ_NUL_PIDS[@]}   \
+                   ${ZIO_REQ_RD_PID[@]}     \
+                   ${ZIO_IRQ_RD_PIDS[@]}    \
+                   ${ZIO_REQ_WR_PIDS[@]}    \
+                   ${ZIO_IRQ_WR_PIDS[@]}    \
+                   ${ZIO_REQ_FR_PIDS[@]}    \ 
+                   ${ZIO_IRQ_FR_PIDS[@]}    \
+                   ${ZIO_REQ_CM_PIDS[@]}    \ 
+                   ${ZIO_IRQ_CM_PIDS[@]}    \
+                   ${ZIO_REQ_CTL_PIDS[@]}   \
+                   ${ZIO_IRQ_CTL_PIDS[@]}   \
+                   ${TXG_QUIESCE_PIDS[@]}   \
+                   ${TXG_SYNC_PIDS[@]}      \
+                   ${TXG_TIMELIMIT_PIDS[@]} \
+                   ${ARC_RECLAIM_PIDS[@]}   \
+                   ${L2ARC_FEED_PIDS[@]}    \
+                   ${ZPIOS_IO_PIDS[@]} )
+
+       while [ ${RUN_DONE} -eq 0 ]; do
+               NOW=`date +%s.%N`
+               LOG_PIDS="${RUN_LOG_DIR}/${RUN_ID}/pids-${NOW}"
+               LOG_DISK="${RUN_LOG_DIR}/${RUN_ID}/disk-${NOW}"
+
+               for PID in "${ALL_PIDS[@]}"; do
+                       if [ -z ${PID} ]; then
+                               continue;
+                       fi
+
+                       if [ -e /proc/${PID}/stat ]; then
+                               cat /proc/${PID}/stat | head -n1 >>${LOG_PIDS}
+                       else
+                               echo "<${PID} exited>" >>${LOG_PIDS}
+                       fi
+               done
+
+               cat /proc/diskstats >${LOG_DISK}
+
+               NOW2=`date +%s.%N`
+               DELTA=`echo "${POLL_INTERVAL}-(${NOW2}-${NOW})" | bc`
+               sleep ${DELTA}
+       done
+}
+
+aquire_pids
+log_pids
+
+# rm ${PROFILE_PID}
+
+exit 0