From nobody Wed Dec 17 15:35:17 2025 Received: from m16.mail.163.com (m16.mail.163.com [117.135.210.5]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 5AC4D1B947 for ; Tue, 16 Jul 2024 06:06:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=117.135.210.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721109982; cv=none; b=VdbtrzFrpz9BHezzom3Lx/DBlSDtflwMTW2zpIkqxCWucHeuyyDuJhVg8mW0VyYOvpgJ4voAuVG2f5W8yhAKtvd8CzYRlzLFt3rmrhJmxbjD03z3juoVN31QGSgErPO0dH2gGpkh0A6OjX7/rR5q/1VvPX51uhM6l1GR5878IQc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721109982; c=relaxed/simple; bh=n9mrTrq5+LraWjYtTuapNum43v8RQdRKu8yn8S9340Y=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Sc47YO13444rrA5oseswv6wgQTBcUlI72WWeNG0ldT6z2QRf97CVFMcT2bfYvg84NAEwUmdnVJtXeuJd8YtkLHUNgSXBVYjIm6OFP0fws7dPe+eksGlsCVht4HZMkk01kagTmgU5AA8PC/I9mAnyJhwPQbR2M79LrUQFk43Qmls= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=RueG3cH8; arc=none smtp.client-ip=117.135.210.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="RueG3cH8" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:Subject:Date:Message-Id:MIME-Version; bh=JMUzw 31GzDBFXXf8S1ZK7C+G64nkNDBD7NUvACKUfvQ=; b=RueG3cH8icWBNWEwMToZp 9QEWetnYnmsAkJQWOu2j51T6BSHw68uscWdBwcjgNJeuMJPtS6boVd4N+r1xrt61 RHw4wIOTy2xmCgPgtdKXUw1pspoAOAO6RMe0UtmovH4q2/chijIo8O1MiUunFdKx +AviHaw4OVgaBOmyr/6UdE= Received: from localhost (unknown [101.132.132.191]) by gzga-smtp-mta-g1-1 (Coremail) with SMTP id _____wD339efDZZmFJ2tBw--.41123S2; Tue, 16 Jul 2024 14:05:19 +0800 (CST) From: Xavier To: mingo@redhat.com, peterz@infradead.org, juri.lelli@redhat.com, vincent.guittot@linaro.org Cc: dietmar.eggemann@arm.com, rostedt@goodmis.org, bsegall@google.com, mgorman@suse.de, bristot@redhat.com, vschneid@redhat.com, linux-kernel@vger.kernel.org, oliver.sang@intel.com, Xavier Subject: [PATCH-RT sched v3 2/2] RT test: Adding test cases for RT group scheduling Date: Tue, 16 Jul 2024 14:05:14 +0800 Message-Id: <20240716060514.304324-3-xavier_qy@163.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240716060514.304324-1-xavier_qy@163.com> References: <20240629112812.243691-1-xavier_qy@163.com> <20240716060514.304324-1-xavier_qy@163.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wD339efDZZmFJ2tBw--.41123S2 X-Coremail-Antispam: 1Uf129KBjvJXoW3Jw1xGr47XFy8ZrykCFWDXFb_yoWftFy8pF WkuryDAw4rG3W3trs3Ca10vF1ruws7ZFW7JrZ3KryUAa4xGFs3tFyIkFW2qrn3CrWF9w13 Zayagay7CF47trJanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07U-db8UUUUU= X-CM-SenderInfo: 50dyxvpubt5qqrwthudrp/1tbiZQEeEGXAnEXKnQAAsB Content-Type: text/plain; charset="utf-8" Adding test cases for RT group scheduling, create some RT infinite loop processes/threads, then set them to the same or different priorities. Place them in different RT task groups, run for a period of time, and finally count the number of infinite loop executions for all tasks. Signed-off-by: Xavier --- MAINTAINERS | 7 + tools/testing/selftests/sched/Makefile | 4 +- tools/testing/selftests/sched/deadloop.c | 192 ++++++++++++++++++ .../selftests/sched/rt_group_sched_test.sh | 119 +++++++++++ 4 files changed, 320 insertions(+), 2 deletions(-) create mode 100644 tools/testing/selftests/sched/deadloop.c create mode 100755 tools/testing/selftests/sched/rt_group_sched_test.sh diff --git a/MAINTAINERS b/MAINTAINERS index 43353b705988..d29effe57bf8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19480,6 +19480,13 @@ L: linux-remoteproc@vger.kernel.org S: Maintained F: drivers/tty/rpmsg_tty.c =20 +RT GROUP SCHED TEST +M: Xavier +L: linux-kernel@vger.kernel.org +S: Maintained +F: tools/testing/selftests/sched/deadloop.c +F: tools/testing/selftests/sched/rt_group_sched_test.sh + RTL2830 MEDIA DRIVER L: linux-media@vger.kernel.org S: Orphan diff --git a/tools/testing/selftests/sched/Makefile b/tools/testing/selftes= ts/sched/Makefile index 099ee9213557..96decb58bf35 100644 --- a/tools/testing/selftests/sched/Makefile +++ b/tools/testing/selftests/sched/Makefile @@ -8,7 +8,7 @@ CFLAGS +=3D -O2 -Wall -g -I./ $(KHDR_INCLUDES) -Wl,-rpath= =3D./ \ $(CLANG_FLAGS) LDLIBS +=3D -lpthread =20 -TEST_GEN_FILES :=3D cs_prctl_test -TEST_PROGS :=3D cs_prctl_test +TEST_GEN_FILES :=3D cs_prctl_test deadloop +TEST_PROGS :=3D cs_prctl_test deadloop =20 include ../lib.mk diff --git a/tools/testing/selftests/sched/deadloop.c b/tools/testing/selft= ests/sched/deadloop.c new file mode 100644 index 000000000000..d850a3e2a0ab --- /dev/null +++ b/tools/testing/selftests/sched/deadloop.c @@ -0,0 +1,192 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Create multiple infinite loop threads based on the passed parameters + * Usage: deadloop num policy prio + * num: the number of child threads + * policy: the scheduling policy of the child threads, 0-fair, 1-fifo, 2-rr + * prio: the priority + * If this process is killed, it will print the loop count of all child th= reads + * to the OUTPUT_FILE + * + * Date: June 27, 2024 + * Author: Xavier + */ + +#define OUTPUT_FILE "rt_group_sched_test.log" + +#if __GLIBC_PREREQ(2, 30) =3D=3D 0 +#include +static pid_t gettid(void) +{ + return syscall(SYS_gettid); +} +#endif + +#define do_err(x) \ +do { \ + if ((x) < 0) { \ + printf("test BUG_ON func %s, line %d %ld\n", \ + __func__, __LINE__, (long)(x) \ + ); \ + while (1) \ + sleep(1); \ + } \ +} while (0) + +#define do_false(x) \ +do { \ + if ((x) =3D=3D 1) { \ + printf("test BUG_ON func %s, line %d %d\n", \ + __func__, __LINE__, (x) \ + ); \ + while (1) \ + sleep(1); \ + } \ +} while (0) + + +struct thread_data { + pthread_t thread; + int index; + int pid; + unsigned long cnt; +}; + +static struct thread_data *pdata; +static int thread_num =3D 1; + +static void create_thread_posix(void *entry, pthread_t *thread, int *para, + int policy, int prio) +{ + int ret; + struct sched_param param; + pthread_attr_t attr; + + memset(¶m, 0, sizeof(param)); + ret =3D pthread_attr_init(&attr); + do_err(ret); + + ret =3D pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + do_err(ret); + + param.sched_priority =3D prio; + + ret =3D pthread_attr_setschedpolicy(&attr, policy); + do_err(ret); + + ret =3D pthread_attr_setschedparam(&attr, ¶m); + do_err(ret); + + ret =3D pthread_create(thread, &attr, entry, para); + do_err(ret); +} + +static void *dead_loop_entry(void *arg) +{ + int index =3D *(int *)arg; + struct sched_param param; + int cur =3D gettid(); + + sched_getparam(cur, ¶m); + pdata[index].pid =3D cur; + printf("cur:%d prio:%d\n", cur, param.sched_priority); + + while (1) { + asm volatile("" ::: "memory"); + pdata[index].cnt++; + } + return NULL; +} + +static void handle_signal(int signal) +{ + int cnt =3D 0; + + if (signal =3D=3D SIGTERM) { + FILE *file =3D freopen(OUTPUT_FILE, "a", stdout); + + if (file =3D=3D NULL) { + perror("freopen"); + exit(0); + } + + while (cnt < thread_num) { + printf("pid:%d cnt:%ld\n", pdata[cnt].pid, pdata[cnt].cnt); + cnt++; + } + fclose(file); + exit(0); + } +} + +static int dead_loop_create(int policy, int prio) +{ + int cnt =3D 0; + int ret; + void *status; + struct sched_param param; + + param.sched_priority =3D prio; + pdata =3D malloc(thread_num * sizeof(struct thread_data)); + do_false(!pdata); + + if (policy) { + ret =3D sched_setscheduler(0, policy, ¶m); + do_err(ret); + } + + while (cnt < thread_num) { + pdata[cnt].index =3D cnt; + create_thread_posix(dead_loop_entry, &pdata[cnt].thread, + &pdata[cnt].index, policy, prio); + cnt++; + } + + signal(SIGTERM, handle_signal); + + cnt =3D 0; + while (cnt < thread_num) { + pthread_join(pdata[cnt].thread, &status); + cnt++; + } + + free(pdata); + return 0; +} + +int main(int argc, char **argv) +{ + int policy =3D 2; + int prio =3D 50; + + if (argc =3D=3D 2) + thread_num =3D atoi(argv[1]); + + if (argc =3D=3D 3) { + thread_num =3D atoi(argv[1]); + policy =3D atoi(argv[2]); + if (policy > 0) + prio =3D 50; + } + + if (argc =3D=3D 4) { + thread_num =3D atoi(argv[1]); + policy =3D atoi(argv[2]); + prio =3D atoi(argv[3]); + } + + dead_loop_create(policy, prio); + + return 0; +} diff --git a/tools/testing/selftests/sched/rt_group_sched_test.sh b/tools/t= esting/selftests/sched/rt_group_sched_test.sh new file mode 100755 index 000000000000..9031250a2684 --- /dev/null +++ b/tools/testing/selftests/sched/rt_group_sched_test.sh @@ -0,0 +1,119 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Test for rt group scheduling +# Date: June 27, 2024 +# Author: Xavier + +# Record the list of child process PIDs +PIDS=3D() + +# File for redirected output +LOGFILE=3D"rt_group_sched_test.log" + +# Cleanup function: kill all recorded child processes and unmount the cgro= up +function cleanup() { + echo "Cleaning up..." + for pid in "${PIDS[@]}"; do + if kill -0 $pid 2>/dev/null; then + kill -TERM $pid + fi + done + + # Sleep for a while to ensure the processes are properly killed + sleep 2 + + # Unmount the cgroup filesystem + umount /sys/fs/cgroup/cpu 2>/dev/null + umount /sys/fs/cgroup 2>/dev/null + echo "Cleanup completed." + + # Ensure the LOGFILE exists and is correct + if [ ! -f "$LOGFILE" ]; then + echo "$LOGFILE not found!" + exit 1 + fi + + # Initialize the total count variable + total=3D0 + + # Read matching lines and calculate the total sum + while IFS=3D read -r line + do + # Use grep to match lines containing 'pid:' and 'cnt:', and extract the = value of cnt + if echo "$line" | grep -q '^pid:[[:digit:]]\+ cnt:[[:digit:]]\+'; then + cnt=3D$(echo "$line" | sed -n \ + 's/^pid:[[:digit:]]\+ cnt:\([[:digit:]]\+\)/\1/p') + total=3D$((total + cnt)) + fi + done < "$LOGFILE" + + # Print the total sum + echo "Total cnt: $total" + echo "Finished processing." +} + +# Capture actions when interrupted or terminated by a signal +trap cleanup EXIT + +# Start the cgroup filesystem and create the necessary directories +function setup_cgroups() { + mount -t tmpfs -o mode=3D755 cgroup_root /sys/fs/cgroup + mkdir -p /sys/fs/cgroup/cpu + mount -t cgroup -o cpu none /sys/fs/cgroup/cpu +} + +# Create cgroup subdirectories and configure their settings +function create_child_cgroup() { + local base_dir=3D$1 + local name=3D$2 + local rt_period=3D$3 + local rt_runtime=3D$4 + mkdir -p "$base_dir/$name" + echo $rt_period > "$base_dir/$name/cpu.rt_period_us" + echo $rt_runtime > "$base_dir/$name/cpu.rt_runtime_us" +} +# Launch a process and add it to the specified cgroup +function launch_process() { + local process_name=3D$1 + + # Three parameters representing the number of child threads, scheduling p= olicy, and priority + local args=3D$2 + local cgroup_path=3D$3 + + # Launch the process + exec -a $process_name ./deadloop $args & + local pid=3D$! + PIDS+=3D($pid) + + # Short sleep to ensure the process starts + sleep 1 + + # Check if the process started successfully + if ! pgrep -x $process_name > /dev/null; then + echo "Error: No process found with name $process_name." + exit 1 + fi + + echo $pid > "$cgroup_path/cgroup.procs" + echo "Process $process_name with PID $pid added to cgroup $cgroup_path" +} + +# Main function running all tasks +function main() { + echo "The test needs 30 seconds..." + rm -f "$LOGFILE" + setup_cgroups + create_child_cgroup "/sys/fs/cgroup/cpu" "child1" 1000000 800000 + create_child_cgroup "/sys/fs/cgroup/cpu/child1" "child2" 1000000 700000 + create_child_cgroup "/sys/fs/cgroup/cpu/child1/child2" "child3" 1000000 6= 00000 + launch_process "child1" "3 2 50" "/sys/fs/cgroup/cpu/child1" + launch_process "child2" "3 2 50" "/sys/fs/cgroup/cpu/child1/child2" + launch_process "child3" "1 2 50" "/sys/fs/cgroup/cpu/child1/child2/child3" + launch_process "tg_root" "1 2 50" "/sys/fs/cgroup/cpu" + + # Run for 30 seconds + sleep 30 +} + +# Execute the main function +main --=20 2.45.2