Message ID | 20210827092007.20889-1-krzysztof.kozlowski@canonical.com |
---|---|
State | Changes Requested |
Headers | show |
Series | [v3,1/2] controllers/cpuacct: skip cpuacct_100_100 on small memory systems | expand |
Hi! > +check_free_memory() > +{ > + local memneeded > + local memfree=`awk '/MemAvailable/ {print $2}' /proc/meminfo` > + > + if [ $? -ne 0 ]; then > + local memcached > + > + memfree=`awk '/MemFree/ {print $2}' /proc/meminfo` > + test $? -eq 0 || return 0 > + > + memcached=`awk '/MemCached/ {print $2}' /proc/meminfo` > + test $? -eq 0 || return 0 > + > + memfree=$((memfree + memcached)) > + fi > + > + # On x86_64, each 100 of processes were using ~16 MB of memory, > + # so try to estimate the needed free memory based on this. > + memneeded=$((max * nbprocess * 16384 / 100)) > + > + if [ $memfree -lt $memneeded ]; then > + tst_brk TCONF "not enough of free memory on this system (approximate need $memneeded kB, free $memfree kB)" > + fi > + tst_res TINFO "memory requirements fulfilled (approximate need $memneeded kB, free $memfree kB)" > + > + return 0 > +} > + > +check_limits() > +{ > + local real_uid="$SUDO_UID" > + local tasksneeded=$((max * nbprocess + 100)) > + > + if [ "$real_uid" = "" ]; then > + real_uid=`id -u` > + test $? -eq 0 || return 0 > + fi > + > + local tasksmax=`systemctl show user-${real_uid}.slice | awk -F '=' '/TasksMax/ {print $2}'` > + test $? -eq 0 || return 0 > + > + # Check for number for cases like TasksMax=infinity > + [ -n "$tasksmax" ] && [ "$tasksmax" -eq "$tasksmax" ] 2>/dev/null > + test $? -eq 0 || return 0 Well we do have a C implementation of this now, it would be better to have the logic in one place and just call the C function to collect the number of pids. If we add tst_get_free_pids.c to the testcases/lib/ directory with: #define TST_NO_DEFAULT_MAIN #include <stdio.h> #include <tst_test.h> extern struct tst_test *tst_test; static struct tst_test test = { }; int main(void) { /* force messages to be printed from new library */ tst_test = &test; printf("%i\n", tst_get_free_pids()); return 0; } We can do FREE_PIDS=$(tst_get_free_pids) here and then just compare the numbers. > + if [ $tasksmax -le $tasksneeded ]; then > + tst_brk TCONF "limit of tasks is too low (approximate need $tasksneeded, limit $tasksmax)" > + fi > + tst_res TINFO "task limit fulfilled (approximate need $tasksneeded, limit $tasksmax)" > + > + return 0 > +} > + > setup() > { > if ! grep -q -w cpuacct /proc/cgroups; then > tst_brk TCONF "cpuacct not supported on this system" > fi > > + check_limits > + # Don't bother with memory limit checks on smaller tests > + if [ $max -ge 100 ] && [ $nbprocess -ge 100 ]; then > + check_free_memory > + fi > + > mount_point=`grep -w cpuacct /proc/mounts | cut -f 2 | cut -d " " -f2` > tst_res TINFO "cpuacct: $mount_point" > if [ "$mount_point" = "" ]; then > -- > 2.30.2 > > > -- > Mailing list info: https://lists.linux.it/listinfo/ltp
On 01/09/2021 15:17, Cyril Hrubis wrote: > Hi! >> +check_free_memory() >> +{ >> + local memneeded >> + local memfree=`awk '/MemAvailable/ {print $2}' /proc/meminfo` >> + >> + if [ $? -ne 0 ]; then >> + local memcached >> + >> + memfree=`awk '/MemFree/ {print $2}' /proc/meminfo` >> + test $? -eq 0 || return 0 >> + >> + memcached=`awk '/MemCached/ {print $2}' /proc/meminfo` >> + test $? -eq 0 || return 0 >> + >> + memfree=$((memfree + memcached)) >> + fi >> + >> + # On x86_64, each 100 of processes were using ~16 MB of memory, >> + # so try to estimate the needed free memory based on this. >> + memneeded=$((max * nbprocess * 16384 / 100)) >> + >> + if [ $memfree -lt $memneeded ]; then >> + tst_brk TCONF "not enough of free memory on this system (approximate need $memneeded kB, free $memfree kB)" >> + fi >> + tst_res TINFO "memory requirements fulfilled (approximate need $memneeded kB, free $memfree kB)" >> + >> + return 0 >> +} >> + >> +check_limits() >> +{ >> + local real_uid="$SUDO_UID" >> + local tasksneeded=$((max * nbprocess + 100)) >> + >> + if [ "$real_uid" = "" ]; then >> + real_uid=`id -u` >> + test $? -eq 0 || return 0 >> + fi >> + >> + local tasksmax=`systemctl show user-${real_uid}.slice | awk -F '=' '/TasksMax/ {print $2}'` >> + test $? -eq 0 || return 0 >> + >> + # Check for number for cases like TasksMax=infinity >> + [ -n "$tasksmax" ] && [ "$tasksmax" -eq "$tasksmax" ] 2>/dev/null >> + test $? -eq 0 || return 0 > > Well we do have a C implementation of this now, it would be better to > have the logic in one place and just call the C function to collect the > number of pids. > > If we add tst_get_free_pids.c to the testcases/lib/ directory with: > > #define TST_NO_DEFAULT_MAIN > #include <stdio.h> > #include <tst_test.h> > > extern struct tst_test *tst_test; > > static struct tst_test test = { > }; > > int main(void) > { > /* force messages to be printed from new library */ > tst_test = &test; > > printf("%i\n", tst_get_free_pids()); > > return 0; > } > > We can do FREE_PIDS=$(tst_get_free_pids) here and then just compare the numbers. > I'll move this piece, as you suggested. The free memory limits is okay to stay here? Best regards, Krzysztof
Hi! > I'll move this piece, as you suggested. The free memory limits is okay > to stay here? There is no such API in the C library yet, so unless you want to add it it can stay where it is.
diff --git a/testcases/kernel/controllers/cpuacct/cpuacct.sh b/testcases/kernel/controllers/cpuacct/cpuacct.sh index 323aa7513bf4..cde2ea948cee 100755 --- a/testcases/kernel/controllers/cpuacct/cpuacct.sh +++ b/testcases/kernel/controllers/cpuacct/cpuacct.sh @@ -38,12 +38,72 @@ OPTIONS EOF } +check_free_memory() +{ + local memneeded + local memfree=`awk '/MemAvailable/ {print $2}' /proc/meminfo` + + if [ $? -ne 0 ]; then + local memcached + + memfree=`awk '/MemFree/ {print $2}' /proc/meminfo` + test $? -eq 0 || return 0 + + memcached=`awk '/MemCached/ {print $2}' /proc/meminfo` + test $? -eq 0 || return 0 + + memfree=$((memfree + memcached)) + fi + + # On x86_64, each 100 of processes were using ~16 MB of memory, + # so try to estimate the needed free memory based on this. + memneeded=$((max * nbprocess * 16384 / 100)) + + if [ $memfree -lt $memneeded ]; then + tst_brk TCONF "not enough of free memory on this system (approximate need $memneeded kB, free $memfree kB)" + fi + tst_res TINFO "memory requirements fulfilled (approximate need $memneeded kB, free $memfree kB)" + + return 0 +} + +check_limits() +{ + local real_uid="$SUDO_UID" + local tasksneeded=$((max * nbprocess + 100)) + + if [ "$real_uid" = "" ]; then + real_uid=`id -u` + test $? -eq 0 || return 0 + fi + + local tasksmax=`systemctl show user-${real_uid}.slice | awk -F '=' '/TasksMax/ {print $2}'` + test $? -eq 0 || return 0 + + # Check for number for cases like TasksMax=infinity + [ -n "$tasksmax" ] && [ "$tasksmax" -eq "$tasksmax" ] 2>/dev/null + test $? -eq 0 || return 0 + + if [ $tasksmax -le $tasksneeded ]; then + tst_brk TCONF "limit of tasks is too low (approximate need $tasksneeded, limit $tasksmax)" + fi + tst_res TINFO "task limit fulfilled (approximate need $tasksneeded, limit $tasksmax)" + + return 0 +} + setup() { if ! grep -q -w cpuacct /proc/cgroups; then tst_brk TCONF "cpuacct not supported on this system" fi + check_limits + # Don't bother with memory limit checks on smaller tests + if [ $max -ge 100 ] && [ $nbprocess -ge 100 ]; then + check_free_memory + fi + mount_point=`grep -w cpuacct /proc/mounts | cut -f 2 | cut -d " " -f2` tst_res TINFO "cpuacct: $mount_point" if [ "$mount_point" = "" ]; then
Running cpuacct_100_100 on a system with less than ~4 GB of RAM fails: cpuacct 1 TINFO: timeout per run is 0h 5m 0s cpuacct 1 TINFO: cpuacct: /sys/fs/cgroup/cpu,cpuacct cpuacct 1 TINFO: Creating 100 subgroups each with 100 processes testcases/bin/cpuacct.sh: 0: Cannot fork In dmesg: LTP: starting cpuacct_100_100 (cpuacct.sh 100 100) cgroup: fork rejected by pids controller in /user.slice/user-1000.slice/session-1.scope The reason is cgroups pid limit set by systemd user.slice. For example on 2 GB RAM machine it is set as: /sys/fs/cgroup/pids/user.slice/user-0.slice/pids.max:5207 Add a check for both free memory and maximum number of pids (when using systemd) to skip the test. Systems not using systemd might still fail. Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> --- Changes since v2: 1. Correct realuid->real_uid typo. 2. Correct handling dash shell tests for return value. 3. Correct handling numbers - infinite. Changes since v1: 1. Add checking for pids. 2. Accurately check the memory constraints. --- .../kernel/controllers/cpuacct/cpuacct.sh | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+)