1#!/bin/sh 2# SPDX-License-Identifier: GPL-2.0-or-later 3# Copyright (c) 2019-2022 Petr Vorel <[email protected]> 4# Copyright (c) 2009 FUJITSU LIMITED 5# Author: Li Zefan <[email protected]> 6 7TST_TESTFUNC=test 8TST_SETUP=do_setup 9TST_CLEANUP=do_cleanup 10TST_CNT=8 11TST_NEEDS_ROOT=1 12TST_NEEDS_TMPDIR=1 13TST_NEEDS_CMDS="awk dmesg find mountpoint rmdir" 14 15do_setup() 16{ 17 mkdir cgroup/ 18 19 if [ ! -f /proc/cgroups ]; then 20 tst_brk TCONF ignored "Kernel does not support for control groups; skipping testcases"; 21 fi 22 23 dmesg -c > /dev/null 24 NR_BUG=`dmesg | grep -c "kernel BUG"` 25 NR_NULL=`dmesg | grep -c "kernel NULL pointer dereference"` 26 NR_WARNING=`dmesg | grep -c "^WARNING"` 27 NR_LOCKDEP=`dmesg | grep -c "possible recursive locking detected"` 28} 29 30do_cleanup() 31{ 32 if mountpoint -q cgroup/; then 33 find cgroup/ -maxdepth 1 -depth -exec rmdir {} + 34 umount cgroup/ 35 rmdir cgroup 36 fi 37} 38 39check_kernel_bug() 40{ 41 local id="$1" 42 local ok_msg="no kernel bug was found" 43 local new_bug=`dmesg | grep -c "kernel BUG"` 44 local new_null=`dmesg | grep -c "kernel NULL pointer dereference"` 45 local new_warning=`dmesg | grep -c "^WARNING"` 46 local new_lockdep=`dmesg | grep -c "possible recursive locking detected"` 47 48 [ "$id" ] && ok_msg="$ok_msg for test $i" 49 50 # no kernel bug is detected 51 if [ $new_bug -eq $NR_BUG -a $new_warning -eq $NR_WARNING -a \ 52 $new_null -eq $NR_NULL -a $new_lockdep -eq $NR_LOCKDEP ]; then 53 tst_res TPASS $ok_msg 54 return 0 55 fi 56 57 # some kernel bug is detected 58 if [ $new_bug -gt $NR_BUG ]; then 59 tst_res TFAIL "kernel BUG was detected!" 60 fi 61 if [ $new_warning -gt $NR_WARNING ]; then 62 tst_res TFAIL "kernel WARNING was detected!" 63 fi 64 if [ $new_null -gt $NR_NULL ]; then 65 tst_res TFAIL "kernel NULL pointer dereference!" 66 fi 67 if [ $new_lockdep -gt $NR_LOCKDEP ]; then 68 tst_res TFAIL "kernel lockdep warning was detected!" 69 fi 70 71 NR_BUG=$new_bug 72 NR_NULL=$new_null 73 NR_WARNING=$new_warning 74 NR_LOCKDEP=$new_lockdep 75 76 tst_res TWARN "BUG FOUND!" 77 dmesg 78 return 1 79} 80 81#--------------------------------------------------------------------------- 82# Bug: There was a race when keeping forking processes and at the same 83# time cat /cgroup/tasks (should be the very first time to read 84# /cgroup/tasks, otherwise this bug won't be triggered) 85# Kernel: 2.6.24, 2.6.25-rcX 86# Links: http://lkml.org/lkml/2007/10/17/224 87# http://lkml.org/lkml/2008/3/5/332 88# http://lkml.org/lkml/2008/4/16/493 89# Fix: commit 0e04388f0189fa1f6812a8e1cb6172136eada87e 90#--------------------------------------------------------------------------- 91test1() 92{ 93 cgroup_regression_fork_processes & 94 sleep 1 95 96 mount -t cgroup -o none,name=foo cgroup cgroup/ 97 if [ $? -ne 0 ]; then 98 tst_res TFAIL "failed to mount cgroup filesystem" 99 kill -TERM $! 100 return 101 fi 102 cat cgroup/tasks > /dev/null 103 104 kill -TERM $! 105 wait $! 2>/dev/null 106 umount cgroup/ 107 check_kernel_bug 108} 109 110#--------------------------------------------------------------------------- 111# Bug: a cgroup's notify_on_release flag did not inherit from its parent. 112# Kernel: 2.6.24-rcX 113# Links: http://lkml.org/lkml/2008/2/25/12 114# Fix: commit bc231d2a048010d5e0b49ac7fddbfa822fc41109 115#--------------------------------------------------------------------------- 116test2() 117{ 118 local val1 119 local val2 120 121 mount -t cgroup -o none,name=foo cgroup cgroup/ 122 if [ $? -ne 0 ]; then 123 tst_res TFAIL "Failed to mount cgroup filesystem" 124 return 125 fi 126 127 echo 0 > cgroup/notify_on_release 128 mkdir cgroup/0 129 val1=`cat cgroup/0/notify_on_release` 130 131 echo 1 > cgroup/notify_on_release 132 mkdir cgroup/1 133 val2=`cat cgroup/1/notify_on_release` 134 135 if [ $val1 -ne 0 -o $val2 -ne 1 ]; then 136 tst_res TFAIL "wrong notify_on_release value" 137 else 138 tst_res TPASS "notify_on_release is inherited" 139 fi 140 141 rmdir cgroup/0 cgroup/1 142 tst_umount $PWD/cgroup 143} 144 145#--------------------------------------------------------------------------- 146# Bug: Accessing NULL cgrp->dentry when reading /proc/sched_debug 147# Kernel: 2.6.26-2.6.28 148# Links: http://lkml.org/lkml/2008/10/30/44 149# http://lkml.org/lkml/2008/12/12/107 150# http://lkml.org/lkml/2008/12/16/481 151# Fix: commit a47295e6bc42ad35f9c15ac66f598aa24debd4e2 152#--------------------------------------------------------------------------- 153test3() 154{ 155 local cpu_subsys_path 156 157 if [ ! -e /proc/sched_debug ]; then 158 tst_res TCONF "CONFIG_SCHED_DEBUG is not enabled" 159 return 160 fi 161 162 if ! grep -q -w "cpu" /proc/cgroups; then 163 tst_res TCONF "CONFIG_CGROUP_SCHED is not enabled" 164 return 165 fi 166 167 cgroup_require "cpu" 168 cpu_subsys_path=$(cgroup_get_mountpoint "cpu") 169 170 cgroup_regression_3_1.sh $cpu_subsys_path & 171 pid1=$! 172 cgroup_regression_3_2.sh & 173 pid2=$! 174 175 sleep 30 176 kill -USR1 $pid1 $pid2 177 wait $pid1 2>/dev/null 178 wait $pid2 2>/dev/null 179 180 rmdir $cpu_subsys_path/0 2> /dev/null 181 cgroup_cleanup 182 check_kernel_bug 183} 184 185#--------------------------------------------------------------------------- 186# Bug: cgroup hierarchy lock's lockdep subclass may overflow 187# Kernel: 2.6.29-rcX 188# Link: http://lkml.org/lkml/2009/2/4/67 189# Fix: 190#--------------------------------------------------------------------------- 191test4() 192{ 193 local lines 194 195 if [ ! -e /proc/lockdep ]; then 196 tst_res TCONF "CONFIG_LOCKDEP is not enabled" 197 return 198 fi 199 200 # MAX_LOCKDEP_SUBCLASSES is 8, so number of subsys should be > 8 201 lines=`cat /proc/cgroups | wc -l` 202 if [ $lines -le 9 ]; then 203 tst_res TCONF "require more than 8 cgroup subsystems" 204 return 205 fi 206 207 mount -t cgroup -o none,name=foo cgroup cgroup/ 208 mkdir cgroup/0 209 rmdir cgroup/0 210 tst_umount $PWD/cgroup 211 212 if dmesg | grep -q "MAX_LOCKDEP_SUBCLASSES too low"; then 213 tst_res TFAIL "lockdep BUG was found" 214 return 215 fi 216 217 tst_res TPASS "no lockdep BUG was found" 218} 219 220#--------------------------------------------------------------------------- 221# Bug: When running 2 concurrent mount/umount threads, kernel WARNING 222# may be triggered, but it's VFS' issue but not cgroup. 223# Kernel: 2.6.24 - 2.6.29-rcX 224# Links: http://lkml.org/lkml/2009/1/4/354 225# Fix: commit 1a88b5364b535edaa321d70a566e358390ff0872 226#--------------------------------------------------------------------------- 227test5() 228{ 229 cgroup_regression_5_1.sh & 230 local pid1=$! 231 cgroup_regression_5_2.sh & 232 local pid2=$! 233 234 sleep 30 235 kill -USR1 $pid1 $pid2 236 wait $pid1 2>/dev/null 237 wait $pid2 2>/dev/null 238 239 mount -t cgroup none cgroup 2> /dev/null 240 mkdir cgroup/0 241 rmdir cgroup/0 242 tst_umount $PWD/cgroup 243 check_kernel_bug 244} 245 246#--------------------------------------------------------------------------- 247# Bug: When running 2 concurrent mount/umount threads, lockdep warning 248# may be triggered, it's a false positive, and it's VFS' issue but 249# not cgroup. 250# Kernel: 2.6.24 - 2.6.29-rcX 251# Links: http://lkml.org/lkml/2009/1/4/352 252# Fix: commit ada723dcd681e2dffd7d73345cc8fda0eb0df9bd 253#--------------------------------------------------------------------------- 254test6() 255{ 256 cgroup_regression_6_1.sh & 257 local pid1=$! 258 cgroup_regression_6_2.sh & 259 local pid2=$! 260 261 sleep 30 262 kill -USR1 $pid1 $pid2 263 wait $pid1 2>/dev/null 264 wait $pid2 2>/dev/null 265 266 umount cgroup/ 2> /dev/null 267 check_kernel_bug 268} 269 270#--------------------------------------------------------------------------- 271# Bug: There was a bug when remount cgroup fs with some dead subdirs in 272# it (rmdir()ed but still has some refcnts on it). It caused memory 273# leak, and may cause oops when cat /proc/sched_debug. 274# Kernel: 2.6.24 - 2.6.27, 2.6.28-rcX 275# Links: http://lkml.org/lkml/2008/12/10/369 276# Fix: commit 307257cf475aac25db30b669987f13d90c934e3a 277#--------------------------------------------------------------------------- 278test_7_1() 279{ 280 local subsys=$1 281 local subsys_path 282 # we should be careful to select a $subsys_path which is related to 283 # cgroup only: if cgroup debugging is enabled a 'debug' $subsys 284 # could be passed here as params and this will lead to ambiguity and 285 # errors when grepping simply for 'debug' in /proc/mounts since we'll 286 # find also /sys/kernel/debug. Helper takes care of this. 287 288 cgroup_require "$subsys" 289 subsys_path=$(cgroup_get_mountpoint "$subsys") 290 291 mkdir $subsys_path/0 292 sleep 100 < $subsys_path/0 & # add refcnt to this dir 293 rmdir $subsys_path/0 294 295 # remount with new subsystems added 296 # since 2.6.28, this remount will fail 297 298 if [ "$subsys_path" = "cgroup" ]; then 299 mount -t cgroup -o remount xxx cgroup/ 2> /dev/null 300 kill -TERM $! 301 wait $! 2>/dev/null 302 umount cgroup/ 303 fi 304 305 cgroup_cleanup 306} 307 308test_7_2() 309{ 310 local subsys=$1 311 312 mount -t cgroup -o none,name=foo cgroup cgroup/ 313 if [ $? -ne 0 ]; then 314 tst_res TFAIL "failed to mount cgroup" 315 return 316 fi 317 318 mkdir cgroup/0 319 sleep 100 < cgroup/0 & # add refcnt to this dir 320 rmdir cgroup/0 321 322 # remount with some subsystems removed 323 # since 2.6.28, this remount will fail 324 mount -t cgroup -o remount,$subsys xxx cgroup/ 2> /dev/null 325 kill -TERM $! 326 wait $! 2>/dev/null 327 umount cgroup/ 328 329 grep -q -w "cpu" /proc/cgroups 330 if [ $? -ne 0 -o ! -e /proc/sched_debug ]; then 331 tst_res TCONF "skip rest of testing due possible oops triggered by reading /proc/sched_debug" 332 return 333 fi 334 335 tmp=0 336 while [ $tmp -lt 50 ]; do 337 echo 3 > /proc/sys/vm/drop_caches 338 cat /proc/sched_debug > /dev/null 339 tmp=$((tmp+1)) 340 done 341} 342 343test7() 344{ 345 local lines=`cat /proc/cgroups | wc -l` 346 local subsys 347 local i=1 348 349 if [ $lines -le 2 ]; then 350 tst_res TCONF "require at least 2 cgroup subsystems" 351 slt_result $SLT_Untested 352 return 353 fi 354 355 subsys=`tail -n 1 /proc/cgroups | awk '{ print $1 }'` 356 357 # remount to add new subsystems to the hierarchy 358 while [ $i -le 2 ]; do 359 test_7_$i $subsys || return 360 check_kernel_bug $i || return 361 i=$((i+1)) 362 done 363} 364 365#--------------------------------------------------------------------------- 366# Bug: oops when get cgroupstat of a cgroup control file 367# Kernel: 2.6.24 - 2.6.27, 2.6.28-rcX 368# Links: http://lkml.org/lkml/2008/11/19/53 369# Fix: commit 33d283bef23132c48195eafc21449f8ba88fce6b 370#--------------------------------------------------------------------------- 371test8() 372{ 373 mount -t cgroup -o none,name=foo cgroup cgroup/ 374 if [ $? -ne 0 ]; then 375 tst_res TFAIL "failed to mount cgroup filesystem" 376 return 377 fi 378 379 if cgroup_regression_getdelays -C cgroup/tasks > /dev/null 2>&1; then 380 tst_res TFAIL "should have failed to get cgroupstat of tasks file" 381 fi 382 383 umount cgroup/ 384 check_kernel_bug 385} 386 387. cgroup_lib.sh 388tst_run 389