1f08c3bdfSopenharmony_ci#!/bin/sh 2f08c3bdfSopenharmony_ci# SPDX-License-Identifier: GPL-2.0-or-later 3f08c3bdfSopenharmony_ci# Copyright (c) Linux Test Project, 2016-2022 4f08c3bdfSopenharmony_ci# Copyright (c) 2015 Fujitsu Ltd. 5f08c3bdfSopenharmony_ci# Author: Zeng Linggang <zenglg.jy@cn.fujitsu.com> 6f08c3bdfSopenharmony_ci# 7f08c3bdfSopenharmony_ci# This is a regression test for commit: 8f08c3bdfSopenharmony_ci# http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=bb2bc55 9f08c3bdfSopenharmony_ci# 10f08c3bdfSopenharmony_ci# A newly created cpuset group crashed the kernel, if exclusive was set to 1, 11f08c3bdfSopenharmony_ci# before a cpuset was set. 12f08c3bdfSopenharmony_ci 13f08c3bdfSopenharmony_ciTST_SETUP=setup 14f08c3bdfSopenharmony_ciTST_CLEANUP=cleanup 15f08c3bdfSopenharmony_ciTST_TESTFUNC=do_test 16f08c3bdfSopenharmony_ciTST_NEEDS_ROOT=1 17f08c3bdfSopenharmony_ciTST_NEEDS_TMPDIR=1 18f08c3bdfSopenharmony_ciTST_MIN_KVER="3.18" 19f08c3bdfSopenharmony_ci 20f08c3bdfSopenharmony_ciLOCAL_MOUNTPOINT="cpuset_test" 21f08c3bdfSopenharmony_ciBACKUP_DIRECTORY="cpuset_backup" 22f08c3bdfSopenharmony_ci 23f08c3bdfSopenharmony_cicpu_num= 24f08c3bdfSopenharmony_ciroot_cpuset_dir= 25f08c3bdfSopenharmony_cicpu_exclusive="cpuset.cpu_exclusive" 26f08c3bdfSopenharmony_cicpus="cpuset.cpus" 27f08c3bdfSopenharmony_ciold_cpu_exclusive_value=1 28f08c3bdfSopenharmony_ci 29f08c3bdfSopenharmony_ci# Check if there are cpuset groups 30f08c3bdfSopenharmony_cicpuset_has_groups() 31f08c3bdfSopenharmony_ci{ 32f08c3bdfSopenharmony_ci find ${root_cpuset_dir} -mindepth 1 -type d -exec echo 1 \; -quit 33f08c3bdfSopenharmony_ci} 34f08c3bdfSopenharmony_ci 35f08c3bdfSopenharmony_ci# cpuset_find_parent_first <what> 36f08c3bdfSopenharmony_ci# Do a parent first find of <what> 37f08c3bdfSopenharmony_cicpuset_find_parent_first() 38f08c3bdfSopenharmony_ci{ 39f08c3bdfSopenharmony_ci local what=$1 40f08c3bdfSopenharmony_ci 41f08c3bdfSopenharmony_ci find . -mindepth 2 -name ${what} | 42f08c3bdfSopenharmony_ci awk '{print length($0) " " $0}' | 43f08c3bdfSopenharmony_ci sort -n | cut -d " " -f 2- 44f08c3bdfSopenharmony_ci} 45f08c3bdfSopenharmony_ci 46f08c3bdfSopenharmony_ci# cpuset_find_child_first <what> 47f08c3bdfSopenharmony_ci# Do a child first find of <what> 48f08c3bdfSopenharmony_cicpuset_find_child_first() 49f08c3bdfSopenharmony_ci{ 50f08c3bdfSopenharmony_ci local what=$1 51f08c3bdfSopenharmony_ci 52f08c3bdfSopenharmony_ci find . -mindepth 2 -name ${what} | 53f08c3bdfSopenharmony_ci awk '{print length($0) " " $0}' | 54f08c3bdfSopenharmony_ci sort -nr | cut -d " " -f 2- 55f08c3bdfSopenharmony_ci} 56f08c3bdfSopenharmony_ci 57f08c3bdfSopenharmony_ci# cpuset_backup_and_update <backup_dir> <what> 58f08c3bdfSopenharmony_ci# Create backup of the values of a specific file (<what>) 59f08c3bdfSopenharmony_ci# in all cpuset groups and set the value to 1 60f08c3bdfSopenharmony_ci# The backup is written to <backup_dir> in the same structure 61f08c3bdfSopenharmony_ci# as in the cpuset filesystem 62f08c3bdfSopenharmony_cicpuset_backup_and_update() 63f08c3bdfSopenharmony_ci{ 64f08c3bdfSopenharmony_ci local backup_dir=$1 65f08c3bdfSopenharmony_ci local what=$2 66f08c3bdfSopenharmony_ci local old_dir=$PWD 67f08c3bdfSopenharmony_ci local cpu_max=$((cpu_num - 1)) 68f08c3bdfSopenharmony_ci local res 69f08c3bdfSopenharmony_ci 70f08c3bdfSopenharmony_ci cd ${root_cpuset_dir} 71f08c3bdfSopenharmony_ci 72f08c3bdfSopenharmony_ci 73f08c3bdfSopenharmony_ci cpuset_find_parent_first ${what} | 74f08c3bdfSopenharmony_ci while read -r file; do 75f08c3bdfSopenharmony_ci [ "$(cat "${file}")" = "" ] && continue 76f08c3bdfSopenharmony_ci 77f08c3bdfSopenharmony_ci mkdir -p "$(dirname "${backup_dir}/${file}")" 78f08c3bdfSopenharmony_ci cat "${file}" > "${backup_dir}/${file}" 79f08c3bdfSopenharmony_ci echo "0-$cpu_max" > "${file}" || exit 1 80f08c3bdfSopenharmony_ci done 81f08c3bdfSopenharmony_ci if [ $? -ne 0 ]; then 82f08c3bdfSopenharmony_ci cd $old_dir 83f08c3bdfSopenharmony_ci return 1 84f08c3bdfSopenharmony_ci fi 85f08c3bdfSopenharmony_ci 86f08c3bdfSopenharmony_ci cpuset_find_child_first ${what} | 87f08c3bdfSopenharmony_ci while read -r file; do 88f08c3bdfSopenharmony_ci [ "$(cat "${file}")" = "" ] && continue 89f08c3bdfSopenharmony_ci echo "1" > "${file}" 90f08c3bdfSopenharmony_ci done 91f08c3bdfSopenharmony_ci res=$? 92f08c3bdfSopenharmony_ci 93f08c3bdfSopenharmony_ci cd $old_dir 94f08c3bdfSopenharmony_ci 95f08c3bdfSopenharmony_ci return $res 96f08c3bdfSopenharmony_ci} 97f08c3bdfSopenharmony_ci 98f08c3bdfSopenharmony_ci# cpuset_restore <backup_dir> <what> 99f08c3bdfSopenharmony_ci# Restores the value of a file (<what>) in all cpuset 100f08c3bdfSopenharmony_ci# groups from the backup created by cpuset_backup_and_update 101f08c3bdfSopenharmony_cicpuset_restore() 102f08c3bdfSopenharmony_ci{ 103f08c3bdfSopenharmony_ci local backup_dir=$1 104f08c3bdfSopenharmony_ci local what=$2 105f08c3bdfSopenharmony_ci local old_dir=$PWD 106f08c3bdfSopenharmony_ci local cpu_max=$((cpu_num - 1)) 107f08c3bdfSopenharmony_ci 108f08c3bdfSopenharmony_ci cd ${backup_dir} 109f08c3bdfSopenharmony_ci 110f08c3bdfSopenharmony_ci cpuset_find_parent_first ${what} | 111f08c3bdfSopenharmony_ci while read -r file; do 112f08c3bdfSopenharmony_ci echo "0-$cpu_max" > "${root_cpuset_dir}/${file}" 113f08c3bdfSopenharmony_ci done 114f08c3bdfSopenharmony_ci 115f08c3bdfSopenharmony_ci cpuset_find_child_first ${what} | 116f08c3bdfSopenharmony_ci while read -r file; do 117f08c3bdfSopenharmony_ci cat "${file}" > "${root_cpuset_dir}/${file}" 118f08c3bdfSopenharmony_ci done 119f08c3bdfSopenharmony_ci 120f08c3bdfSopenharmony_ci cd $old_dir 121f08c3bdfSopenharmony_ci} 122f08c3bdfSopenharmony_ci 123f08c3bdfSopenharmony_cisetup() 124f08c3bdfSopenharmony_ci{ 125f08c3bdfSopenharmony_ci cgroup_require "cpuset" 126f08c3bdfSopenharmony_ci cgroup_version=$(cgroup_get_version "cpuset") 127f08c3bdfSopenharmony_ci root_cpuset_dir=$(cgroup_get_mountpoint "cpuset") 128f08c3bdfSopenharmony_ci testpath=$(cgroup_get_test_path "cpuset") 129f08c3bdfSopenharmony_ci task_list=$(cgroup_get_task_list "cpuset") 130f08c3bdfSopenharmony_ci 131f08c3bdfSopenharmony_ci tst_res TINFO "test starts with cgroup version $cgroup_version" 132f08c3bdfSopenharmony_ci 133f08c3bdfSopenharmony_ci if [ "$cgroup_version" = "2" ]; then 134f08c3bdfSopenharmony_ci tst_brk TCONF "cgroup v2 found, skipping test" 135f08c3bdfSopenharmony_ci return 136f08c3bdfSopenharmony_ci fi 137f08c3bdfSopenharmony_ci 138f08c3bdfSopenharmony_ci if ! [ -f ${root_cpuset_dir}/${cpu_exclusive} ]; then 139f08c3bdfSopenharmony_ci cpu_exclusive=cpu_exclusive 140f08c3bdfSopenharmony_ci cpus=cpus 141f08c3bdfSopenharmony_ci fi 142f08c3bdfSopenharmony_ci 143f08c3bdfSopenharmony_ci if ! [ -f ${root_cpuset_dir}/${cpu_exclusive} ]; then 144f08c3bdfSopenharmony_ci tst_brk TBROK "Both cpuset.cpu_exclusive and cpu_exclusive do not exist" 145f08c3bdfSopenharmony_ci fi 146f08c3bdfSopenharmony_ci 147f08c3bdfSopenharmony_ci # Ensure that we can use cpu 0 exclusively 148f08c3bdfSopenharmony_ci if [ "$(cpuset_has_groups)" = "1" ]; then 149f08c3bdfSopenharmony_ci cpu_num=$(tst_getconf _NPROCESSORS_ONLN) 150f08c3bdfSopenharmony_ci if [ $cpu_num -lt 2 ]; then 151f08c3bdfSopenharmony_ci tst_brk TCONF "There are already cpuset groups, so at least two cpus are required." 152f08c3bdfSopenharmony_ci fi 153f08c3bdfSopenharmony_ci 154f08c3bdfSopenharmony_ci # Use cpu 1 for all existing cpuset cgroups 155f08c3bdfSopenharmony_ci mkdir ${BACKUP_DIRECTORY} 156f08c3bdfSopenharmony_ci cpuset_backup_and_update "${PWD}/${BACKUP_DIRECTORY}" ${cpus} 157f08c3bdfSopenharmony_ci [ $? -ne 0 ] && tst_brk TBROK "Unable to prepare existing cpuset cgroups" 158f08c3bdfSopenharmony_ci fi 159f08c3bdfSopenharmony_ci 160f08c3bdfSopenharmony_ci old_cpu_exclusive_value=$(cat ${root_cpuset_dir}/${cpu_exclusive}) 161f08c3bdfSopenharmony_ci if [ "${old_cpu_exclusive_value}" != "1" ];then 162f08c3bdfSopenharmony_ci echo 1 > ${root_cpuset_dir}/${cpu_exclusive} 163f08c3bdfSopenharmony_ci [ $? -ne 0 ] && tst_brk TBROK "'echo 1 > ${root_cpuset_dir}/${cpu_exclusive}' failed" 164f08c3bdfSopenharmony_ci fi 165f08c3bdfSopenharmony_ci} 166f08c3bdfSopenharmony_ci 167f08c3bdfSopenharmony_cicleanup() 168f08c3bdfSopenharmony_ci{ 169f08c3bdfSopenharmony_ci if [ -d "${root_cpuset_dir}/testdir" ]; then 170f08c3bdfSopenharmony_ci rmdir ${root_cpuset_dir}/testdir 171f08c3bdfSopenharmony_ci fi 172f08c3bdfSopenharmony_ci 173f08c3bdfSopenharmony_ci if [ -d "${BACKUP_DIRECTORY}" ]; then 174f08c3bdfSopenharmony_ci cpuset_restore "${PWD}/${BACKUP_DIRECTORY}" ${cpus} 175f08c3bdfSopenharmony_ci fi 176f08c3bdfSopenharmony_ci 177f08c3bdfSopenharmony_ci if [ "$old_cpu_exclusive_value" != 1 ]; then 178f08c3bdfSopenharmony_ci # Need to flush, or write may fail with: "Device or resource busy" 179f08c3bdfSopenharmony_ci sync 180f08c3bdfSopenharmony_ci echo ${old_cpu_exclusive_value} > ${root_cpuset_dir}/${cpu_exclusive} 181f08c3bdfSopenharmony_ci fi 182f08c3bdfSopenharmony_ci 183f08c3bdfSopenharmony_ci cgroup_cleanup 184f08c3bdfSopenharmony_ci} 185f08c3bdfSopenharmony_ci 186f08c3bdfSopenharmony_cido_test() 187f08c3bdfSopenharmony_ci{ 188f08c3bdfSopenharmony_ci local cpu_exclusive_tmp cpus_value 189f08c3bdfSopenharmony_ci 190f08c3bdfSopenharmony_ci ROD_SILENT mkdir ${root_cpuset_dir}/testdir 191f08c3bdfSopenharmony_ci 192f08c3bdfSopenharmony_ci # Creat an exclusive cpuset. 193f08c3bdfSopenharmony_ci echo 1 > ${root_cpuset_dir}/testdir/${cpu_exclusive} 194f08c3bdfSopenharmony_ci [ $? -ne 0 ] && tst_brk TFAIL "'echo 1 > ${root_cpuset_dir}/testdir/${cpu_exclusive}' failed" 195f08c3bdfSopenharmony_ci 196f08c3bdfSopenharmony_ci cpu_exclusive_tmp=$(cat ${root_cpuset_dir}/testdir/${cpu_exclusive}) 197f08c3bdfSopenharmony_ci if [ "${cpu_exclusive_tmp}" != "1" ]; then 198f08c3bdfSopenharmony_ci tst_brk TFAIL "${cpu_exclusive} is '${cpu_exclusive_tmp}', expected '1'" 199f08c3bdfSopenharmony_ci fi 200f08c3bdfSopenharmony_ci 201f08c3bdfSopenharmony_ci # This may trigger the kernel crash 202f08c3bdfSopenharmony_ci echo 0 > ${root_cpuset_dir}/testdir/${cpus} 203f08c3bdfSopenharmony_ci [ $? -ne 0 ] && tst_brk TFAIL "'echo 0 > ${root_cpuset_dir}/testdir/${cpus}' failed" 204f08c3bdfSopenharmony_ci 205f08c3bdfSopenharmony_ci cpus_value=$(cat ${root_cpuset_dir}/testdir/${cpus}) 206f08c3bdfSopenharmony_ci if [ "${cpus_value}" != "0" ]; then 207f08c3bdfSopenharmony_ci tst_brk TFAIL "${cpus} is '${cpus_value}', expected '0'" 208f08c3bdfSopenharmony_ci fi 209f08c3bdfSopenharmony_ci 210f08c3bdfSopenharmony_ci tst_res TPASS "Bug is not reproducible" 211f08c3bdfSopenharmony_ci} 212f08c3bdfSopenharmony_ci 213f08c3bdfSopenharmony_ci. cgroup_lib.sh 214f08c3bdfSopenharmony_citst_run 215