Commit b78531c7 authored by Michal Berger's avatar Michal Berger Committed by Tomasz Zawadzki
Browse files

test/scheduler: Add some debugging cgroup routines



Parse process's set of flags for debugging purposes.

Change-Id: Iaeb4a28a0540147fa9e919e4da8cd9d3b66aff91
Signed-off-by: default avatarMichal Berger <michal.berger@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/19678


Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <jim.harris@gmail.com>
parent af24a874
Loading
Loading
Loading
Loading
+67 −3
Original line number Diff line number Diff line
@@ -72,13 +72,27 @@ move_cgroup_procs() {

	fold_list_onto_array procs $(< "$sysfs_cgroup/$old_cgroup/$old_proc_interface")

	local moved=0
	for proc in "${!procs[@]}"; do
		# We can't move every kernel thread around and every process can
		# exit at any point so ignore any failures upon writing the
		# processes out. FIXME: Check PF_KTHREAD instead?
		[[ -n $(readlink -f "/proc/$proc/exe") ]] || continue
		echo "$proc" > "$sysfs_cgroup/$new_cgroup/$new_proc_interface" 2> /dev/null || :
		# processes out but keep count of any failed attempts for debugging
		# purposes.
		if move_proc "$proc" "$new_cgroup" "$old_cgroup" "$new_proc_interface"; then
			((++moved))
		fi
	done
	echo "Moved $moved processes, failed $((${#procs[@]} - moved))" >&2
}

move_proc() {
	local proc=$1 new_cgroup=$2 old_cgroup=${3:-N/A} attr=$4 write_fail

	echo "Moving $proc ($(id_proc "$proc" 2>&1)) to $new_cgroup from $old_cgroup" >&2
	if ! write_fail=$(set_cgroup_attr "$new_cgroup" "$attr" "$proc" 2>&1); then
		echo "Moving $proc failed: ${write_fail##*: }" >&2
		return 1
	fi
}

set_cgroup_attr() {
@@ -187,5 +201,55 @@ set_cgroup_attr_top_bottom() {
	_set_cgroup_attr_top_bottom "$(get_cgroup_path "$1")" "$2" "$3"
}

id_proc() {
	local pid=$1 flag_to_check=${2:-all}
	local flags flags_map=() comm stats tflags

	[[ -e /proc/$pid/stat ]] || return 1
	# Comm is wrapped in () but the name of the thread itself may include "()", giving in result
	# something similar to: ((sd-pam))
	comm=$(< "/proc/$pid/stat") || return 1

	stats=(${comm/*) /}) tflags=${stats[6]}

	# include/linux/sched.h
	flags_map[0x1]=PF_VCPU
	flags_map[0x2]=PF_IDLE
	flags_map[0x4]=PF_EXITING
	flags_map[0x8]=PF_POSTCOREDUMP
	flags_map[0x10]=PF_IO_WORKER
	flags_map[0x20]=PF_WQ_WORKER
	flags_map[0x40]=PF_FORK_NO_EXEC
	flags_map[0x80]=PF_MCE_PROCESS
	flags_map[0x100]=PF_SUPERPRIV
	flags_map[0x200]=PF_DUMPCORE
	flags_map[0x400]=PF_SIGNALED
	flags_map[0x800]=PF_MEMALLOC
	flags_map[0x1000]=PF_NPROC_EXCEEDED
	flags_map[0x2000]=PF_USED_MATH
	flags_map[0x4000]=PF_USER_WORKER
	flags_map[0x8000]=PF_NOFREEZE
	flags_map[0x20000]=PF_KSWAPD
	flags_map[0x40000]=PF_MEMALLOC_NOFS
	flags_map[0x80000]=PF_MEMALLOC_NOIO
	flags_map[0x100000]=PF_LOCAL_THROTTLE
	flags_map[0x00200000]=PF_KTHREAD
	flags_map[0x00400000]=PF_RANDOMIZE
	flags_map[0x04000000]=PF_NO_SETAFFINITY
	flags_map[0x08000000]=PF_MCE_EARLY
	flags_map[0x10000000]=PF_MEMALLOC_PIN
	flags_map[0x80000000]=PF_SUSPEND_TASK

	for flag in "${!flags_map[@]}"; do
		[[ $flag_to_check == "${flags_map[flag]}" || $flag_to_check == all ]] || continue
		((tflags & flag)) && flags=${flags:+$flags,}"${flags_map[flag]}"
	done
	if [[ -n $flags ]]; then
		echo "$flags" >&2
		return 0
	fi
	return 1
}

declare -r sysfs_cgroup=/sys/fs/cgroup
cgroup_version=$(check_cgroup)