Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package rt-tests for openSUSE:Factory checked in at 2026-06-22 17:32:29 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rt-tests (Old) and /work/SRC/openSUSE:Factory/.rt-tests.new.1956 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rt-tests" Mon Jun 22 17:32:29 2026 rev:15 rq:1360799 version:2.10 Changes: -------- --- /work/SRC/openSUSE:Factory/rt-tests/rt-tests.changes 2025-09-09 20:31:32.376499578 +0200 +++ /work/SRC/openSUSE:Factory/.rt-tests.new.1956/rt-tests.changes 2026-06-22 17:32:38.508478022 +0200 @@ -1,0 +2,9 @@ +Sat Jun 20 20:35:17 UTC 2026 - Martin Pluskal <[email protected]> + +- Update to version 2.10: + * hwlatdetect: add MTBF calculation and width/bounds checking + * cyclictest: fix the -A long option name in the manpage and drop a + duplicate getopt entry + * rt-utils: fix the write() return-value check + +------------------------------------------------------------------- Old: ---- rt-tests-2.9.tar.gz New: ---- rt-tests-2.10.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rt-tests.spec ++++++ --- /var/tmp/diff_new_pack.rwZnET/_old 2026-06-22 17:32:39.976529179 +0200 +++ /var/tmp/diff_new_pack.rwZnET/_new 2026-06-22 17:32:39.980529319 +0200 @@ -1,7 +1,7 @@ # # spec file for package rt-tests # -# Copyright (c) 2025 SUSE LLC +# Copyright (c) 2026 SUSE LLC and contributors # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: rt-tests -Version: 2.9 +Version: 2.10 Release: 0 Summary: Realtime Kernel Testsuite License: GPL-2.0-only @@ -36,6 +36,8 @@ %prep %autosetup -p1 +# avoid env-script-interpreter rpmlint error +sed -i '1s|/usr/bin/env python3|/usr/bin/python3|' src/cyclictest/get_cyclictest_snapshot.py %build export CFLAGS="%{optflags}" ++++++ rt-tests-2.9.tar.gz -> rt-tests-2.10.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rt-tests-2.9/Makefile new/rt-tests-2.10/Makefile --- old/rt-tests-2.9/Makefile 2025-07-01 16:20:28.000000000 +0200 +++ new/rt-tests-2.10/Makefile 2026-02-27 21:09:47.000000000 +0100 @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-or-later include feature/test-feature.mak -VERSION = 2.8 +VERSION = 2.10 CC = $(CROSS_COMPILE)gcc AR = $(CROSS_COMPILE)ar diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rt-tests-2.9/README.markdown new/rt-tests-2.10/README.markdown --- old/rt-tests-2.9/README.markdown 2025-07-01 16:20:28.000000000 +0200 +++ new/rt-tests-2.10/README.markdown 2026-02-27 21:09:47.000000000 +0100 @@ -57,15 +57,16 @@ What, however, if the latency is higher than acceptable? Then, the famous "*latency fighting*" begins. For this purpose, the cyclictest tool provides the -`-b` option that causes a function tracing to be written to -`/sys/kernel/debug/tracing/trace`, if a specified latency threshold was -exceeded, for example: +`--breaktrace` option to halt tracing if the specified latency was exceeded. A +tracer must be configured upfront. The resulting trace can be invastigated in +`/sys/kernel/tracing/trace`, for example: - ./cyclictest -a -t -n -p99 -f -b100 + echo function > /sys/kernel/tracing/current_tracer + cyclictest -a -t -n -p99 --tracemark --breaktrace 100 This causes the program to abort execution, if the latency value exceeds 100 microseconds; the culprit can then be found in the trace output at -`/sys/kernel/debug/tracing/trace`. +`/sys/kernel/tracing/trace`. The kernel function that was executed just before a latency of more than 100 microseconds was detected is marked with an exclamation mark such as @@ -80,7 +81,7 @@ If the trace output is not obvious, it can be submitted to the OSADL Latency Fight Support Service at [[email protected]](mailto:[email protected]). -In addition to the output of `cat /sys/kernel/debug/tracing/trace`, the output +In addition to the output of `cat /sys/kernel/tracing/trace`, the output of `lspci` and the `.config` file that was used to build the kernel in question must be submitted. We are sure you understand that OSADL members will be served first, but we promise to do our best to help everybody to successfully fight diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rt-tests-2.9/src/backfire/sendme.c new/rt-tests-2.10/src/backfire/sendme.c --- old/rt-tests-2.9/src/backfire/sendme.c 2025-07-01 16:20:28.000000000 +0200 +++ new/rt-tests-2.10/src/backfire/sendme.c 2026-02-27 21:09:47.000000000 +0100 @@ -45,7 +45,7 @@ static int kernvar(int mode, const char *name, char *value, size_t sizeofvalue) { char filename[128]; - char *fileprefix = get_debugfileprefix(); + char *fileprefix = get_tracefs_prefix(); int retval = 1; int path; size_t len_prefix = strlen(fileprefix), len_name = strlen(name); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rt-tests-2.9/src/cyclictest/cyclictest.8 new/rt-tests-2.10/src/cyclictest/cyclictest.8 --- old/rt-tests-2.9/src/cyclictest/cyclictest.8 2025-07-01 16:20:28.000000000 +0200 +++ new/rt-tests-2.10/src/cyclictest/cyclictest.8 2026-02-27 21:09:47.000000000 +0100 @@ -17,7 +17,7 @@ cyclictest \- High resolution test program .SH SYNOPSIS .SY cyclictest -.RI "[ \-hfmnqrsvMS ] [\-a " proc " ] [\-A " align " ] [\-b " usec " ] [\-c " clock " ] [\-d " dist " ] \ +.RI "[ \-hfmnqrsvMS ] [\-a " proc " ] [\-A " aligned " ] [\-b " usec " ] [\-c " clock " ] [\-d " dist " ] \ [\-h " histogram " ] [\-i " intv " ] [\-\-json " filename " ] [\-l " loop " ] [\-o " red " ] \ [\-p " prio " ] [\-t " num " ] [\-D " time "] [\-w] [\-W] [\-y " policy " ] [ \-S | \-U ]" @@ -47,7 +47,7 @@ * Support for CPU sets requires libnuma version >= 2. For libnuma v1, PROC-SET, if specified, must be a single CPU number. .TP -.B \-A, \-\-align=USEC +.B \-A, \-\-aligned=USEC Align thread wakeups to a specific offset in microseconds .TP .B \-b, \-\-breaktrace=USEC diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rt-tests-2.9/src/cyclictest/cyclictest.c new/rt-tests-2.10/src/cyclictest/cyclictest.c --- old/rt-tests-2.9/src/cyclictest/cyclictest.c 2025-07-01 16:20:28.000000000 +0200 +++ new/rt-tests-2.10/src/cyclictest/cyclictest.c 2026-02-27 21:09:47.000000000 +0100 @@ -852,6 +852,7 @@ break_thread_id = stat->tid; tracemark("hit latency threshold (%llu > %d)", (unsigned long long) diff, tracelimit); + tracing_stop(); break_thread_value = diff; } pthread_mutex_unlock(&break_thread_id_lock); @@ -1146,7 +1147,7 @@ {"deepest-idle-state", required_argument, NULL, OPT_DEEPEST_IDLE_STATE }, {NULL, 0, NULL, 0 }, }; - int c = getopt_long(argc, argv, "a::A::b:c:d:D:F:h:H:i:l:MNo:p:mqrRsSt::uvD:x", + int c = getopt_long(argc, argv, "a::A::b:c:d:D:F:h:H:i:l:MNo:p:mqrRsSt::uvx", long_options, &option_index); if (c == -1) break; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rt-tests-2.9/src/hwlatdetect/hwlatdetect.py new/rt-tests-2.10/src/hwlatdetect/hwlatdetect.py --- old/rt-tests-2.9/src/hwlatdetect/hwlatdetect.py 2025-07-01 16:20:28.000000000 +0200 +++ new/rt-tests-2.10/src/hwlatdetect/hwlatdetect.py 2026-02-27 21:09:47.000000000 +0100 @@ -38,6 +38,17 @@ return ','.join([num_hex[max(i - 8, 0):i] for i in range(len(num_hex), 0, -8)][::-1]) +def key_values(fields): + """ Extract key:value pairs from a list of fields and return them as a dictionary """ + return { + k: v + for field in fields + if ':' in field + for k, v in [field.split(":", 1)] + if k and v + } + + # # Class used to manage mounting and umounting the debugfs # filesystem. Note that if an instance of this class mounts @@ -242,18 +253,36 @@ class Sample: 'private class for tracer sample data' - __slots__ = 'cpu', 'timestamp', 'inner', 'outer' + __slots__ = 'cpu', 'timestamp', 'inner', 'outer', 'count' def __init__(self, line): fields = line.split() - self.cpu = int(fields[1][1:-1]) + if len(fields) < 8: + raise ValueError(f"Unexpected trace format: {line}") + + kv = key_values(fields) + + # Parse CPU number from either [NNN] or NNd.... format + cpu_field = fields[1] + if not cpu_field: + raise ValueError(f"Empty CPU field in: {line}") + + if cpu_field[0] == '[': + # nolatency-format: [007] + self.cpu = int(cpu_field[1:-1]) + else: + # latency-format: 13d.... + self.cpu = int(cpu_field[:-5]) i, o = fields[6].split('/') ts = fields[7][3:] self.timestamp = str(ts) self.inner = int(i) self.outer = int(o) + self.count = int(kv["count"]) if "count" in kv else None def __str__(self): + if self.count is not None: + return f"ts: {self.timestamp}, inner:{self.inner}, outer:{self.outer}, cpu:{self.cpu}, count:{self.count}" return f"ts: {self.timestamp}, inner:{self.inner}, outer:{self.outer}, cpu:{self.cpu}" def display(self): @@ -277,6 +306,8 @@ raise DetectorNotAvailable("hwlat", "hwlat tracer not available") self.type = "tracer" self.samples = [] + self.first = None + self.last = None self.set("enable", 0) self.set('current_tracer', 'hwlat') @@ -286,6 +317,9 @@ def get(self, field): if field == "count": + # Use new count field if available, otherwise fall back to sample count + if self.samples and self.samples[0].count is not None: + return sum(s.count for s in self.samples) return len(self.samples) if field == "max": max = 0 @@ -306,6 +340,8 @@ pollcnt += 1 val = self.get_sample() while val: + self.first = self.first or val.timestamp + self.last = val.timestamp self.samples.append(val) if watch: val.display() @@ -527,6 +563,12 @@ exceeding = detect.get("count") info(f"Samples exceeding threshold: {exceeding}") + if exceeding > 1: + width = int(detect.get('width')) + if width > 0: + mtbf = (((float(detect.last) - float(detect.first)) * int(detect.get('window'))) / ((exceeding - 1) * width)) + info(f"MTBF: {mtbf:.3f} seconds") + if detect.have_msr: finishsmi = detect.getsmicounts() total_smis = 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rt-tests-2.9/src/include/rt-utils.h new/rt-tests-2.10/src/include/rt-utils.h --- old/rt-tests-2.9/src/include/rt-utils.h 2025-07-01 16:20:28.000000000 +0200 +++ new/rt-tests-2.10/src/include/rt-utils.h 2026-02-27 21:09:47.000000000 +0100 @@ -11,8 +11,7 @@ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) int check_privs(void); -char *get_debugfileprefix(void); -int mount_debugfs(char *); +char *get_tracefs_prefix(void); int get_tracers(char ***); int valid_tracer(char *); @@ -32,6 +31,7 @@ void enable_trace_mark(void); void tracemark(char *fmt, ...) __attribute__((format(printf, 1, 2))); +void tracing_stop(void); void disable_trace_mark(void); #define MSEC_PER_SEC 1000 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rt-tests-2.9/src/lib/rt-utils.c new/rt-tests-2.10/src/lib/rt-utils.c --- old/rt-tests-2.9/src/lib/rt-utils.c 2025-07-01 16:20:28.000000000 +0200 +++ new/rt-tests-2.10/src/lib/rt-utils.c 2026-02-27 21:09:47.000000000 +0100 @@ -32,8 +32,7 @@ #define MAX_COMMAND_LINE 4096 #define MAX_TS_SIZE 64 -static char debugfileprefix[MAX_PATH]; -static char *fileprefix; +static char tracefs_prefix[MAX_PATH]; static int trace_fd = -1; static int tracemark_fd = -1; static __thread char tracebuf[TRACEBUFSIZ]; @@ -41,28 +40,21 @@ static char ts_start[MAX_TS_SIZE]; /* - * Finds the tracing directory in a mounted debugfs + * Finds the tracing directory */ -char *get_debugfileprefix(void) +char *get_tracefs_prefix(void) { char type[100]; FILE *fp; - int size; int found = 0; struct stat s; - if (debugfileprefix[0] != '\0') + if (tracefs_prefix[0] != '\0') goto out; /* look in the "standard" mount point first */ - if ((stat("/sys/kernel/debug/tracing", &s) == 0) && S_ISDIR(s.st_mode)) { - strcpy(debugfileprefix, "/sys/kernel/debug/tracing/"); - goto out; - } - - /* now look in the "other standard" place */ - if ((stat("/debug/tracing", &s) == 0) && S_ISDIR(s.st_mode)) { - strcpy(debugfileprefix, "/debug/tracing/"); + if ((stat("/sys/kernel/tracing", &s) == 0) && S_ISDIR(s.st_mode)) { + strcpy(tracefs_prefix, "/sys/kernel/tracing/"); goto out; } @@ -73,14 +65,8 @@ while (fscanf(fp, "%*s %" STR(MAX_PATH) "s %99s %*s %*d %*d\n", - debugfileprefix, type) == 2) { - if (strcmp(type, "debugfs") == 0) { - found = 1; - break; - } - /* stupid check for systemd-style autofs mount */ - if ((strcmp(debugfileprefix, "/sys/kernel/debug") == 0) && - (strcmp(type, "systemd") == 0)) { + tracefs_prefix, type) == 2) { + if (strcmp(type, "tracefs") == 0) { found = 1; break; } @@ -88,41 +74,11 @@ fclose(fp); if (!found) { - debugfileprefix[0] = '\0'; + tracefs_prefix[0] = '\0'; goto out; } - - size = sizeof(debugfileprefix) - strlen(debugfileprefix); - strncat(debugfileprefix, "/tracing/", size); - out: - return debugfileprefix; -} - -int mount_debugfs(char *path) -{ - char *mountpoint = path; - char cmd[MAX_PATH]; - char *prefix; - int ret; - - /* if it's already mounted just return */ - prefix = get_debugfileprefix(); - if (strlen(prefix) != 0) { - info(1, "debugfs mountpoint: %s\n", prefix); - return 0; - } - if (!mountpoint) - mountpoint = "/sys/kernel/debug"; - - sprintf(cmd, "mount -t debugfs debugfs %s", mountpoint); - ret = system(cmd); - if (ret != 0) { - fprintf(stderr, "Error mounting debugfs at %s: %s\n", - mountpoint, strerror(errno)); - return -1; - } - return 0; + return tracefs_prefix; } static char **tracer_list; @@ -139,7 +95,7 @@ int ret; FILE *fp; char buffer[CHUNKSZ]; - char *prefix = get_debugfileprefix(); + char *prefix = get_tracefs_prefix(); char *tmpbuf = NULL; char *ptr; int tmpsz = 0; @@ -219,7 +175,7 @@ */ int setevent(char *event, char *val) { - char *prefix = get_debugfileprefix(); + char *prefix = get_tracefs_prefix(); char buffer[MAX_PATH]; int fd; int ret; @@ -406,12 +362,17 @@ static void open_tracemark_fd(void) { char path[MAX_PATH]; + int n; /* * open the tracemark file if it's not already open */ if (tracemark_fd < 0) { - sprintf(path, "%s/%s", fileprefix, "trace_marker"); + n = snprintf(path, sizeof(path), "%s/%s", tracefs_prefix, "trace_marker"); + if (n >= sizeof(path)) { + warn("tracefs path too long\n"); + return; + } tracemark_fd = open(path, O_WRONLY); if (tracemark_fd < 0) { warn("unable to open trace_marker file: %s\n", path); @@ -425,7 +386,11 @@ * if we hit a breaktrace threshold */ if (trace_fd < 0) { - sprintf(path, "%s/%s", fileprefix, "tracing_on"); + n = snprintf(path, sizeof(path), "%s/%s", tracefs_prefix, "tracing_on"); + if (n >= sizeof(path)) { + warn("tracefs path too long\n"); + return; + } if ((trace_fd = open(path, O_WRONLY)) < 0) warn("unable to open tracing_on file: %s\n", path); } @@ -443,32 +408,27 @@ static int trace_file_exists(char *name) { struct stat sbuf; - char *tracing_prefix = get_debugfileprefix(); - char path[MAX_PATH]; - strcat(strcpy(path, tracing_prefix), name); - return stat(path, &sbuf) ? 0 : 1; + return stat(tracefs_prefix, &sbuf) ? 0 : 1; } -static void debugfs_prepare(void) +static void tracefs_prepare(void) { - if (mount_debugfs(NULL)) - fatal("could not mount debugfs"); - - fileprefix = get_debugfileprefix(); + get_tracefs_prefix(); if (!trace_file_exists("tracing_enabled") && !trace_file_exists("tracing_on")) warn("tracing_enabled or tracing_on not found\n" - "debug fs not mounted"); + "tracefs not found"); } void tracemark(char *fmt, ...) { va_list ap; int len; + int ret; /* bail out if we're not tracing */ /* or if the kernel doesn't support trace_mark */ - if (tracemark_fd < 0 || trace_fd < 0) + if (tracemark_fd < 0) return; va_start(ap, fmt); @@ -476,15 +436,25 @@ va_end(ap); /* write the tracemark message */ - write(tracemark_fd, tracebuf, len); + ret = write(tracemark_fd, tracebuf, len); + if (ret != len) + warn("trace mark write failed\n"); +} - /* now stop any trace */ - write(trace_fd, "0\n", 2); +void tracing_stop(void) +{ + int ret; + + if (trace_fd < 0) + return; + ret = write(trace_fd, "0\n", 2); + if (ret != 2) + warn("trace stop write failed\n"); } void enable_trace_mark(void) { - debugfs_prepare(); + tracefs_prepare(); open_tracemark_fd(); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rt-tests-2.9/src/oslat/oslat.c new/rt-tests-2.10/src/oslat/oslat.c --- old/rt-tests-2.9/src/oslat/oslat.c 2025-07-01 16:20:28.000000000 +0200 +++ new/rt-tests-2.10/src/oslat/oslat.c 2026-02-27 21:09:47.000000000 +0100 @@ -340,6 +340,7 @@ char *line = "%s: Trace threshold (%d us) triggered on cpu %d with %.*f us!\n"; tracemark(line, g.app_name, g.trace_threshold, t->core_i, g.precision, us); + tracing_stop(); err_quit(line, g.app_name, g.trace_threshold, t->core_i, g.precision, us); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rt-tests-2.9/src/pmqtest/pmqtest.c new/rt-tests-2.10/src/pmqtest/pmqtest.c --- old/rt-tests-2.9/src/pmqtest/pmqtest.c 2025-07-01 16:20:28.000000000 +0200 +++ new/rt-tests-2.10/src/pmqtest/pmqtest.c 2026-02-27 21:09:47.000000000 +0100 @@ -75,6 +75,7 @@ int policy = SCHED_FIFO; struct sched_param schedp; struct timespec ts; + int ret; memset(&schedp, 0, sizeof(schedp)); schedp.sched_priority = par->priority; @@ -184,12 +185,15 @@ if (par->tracelimit && par->maxdiff > par->tracelimit) { char tracing_enabled_file[MAX_PATH]; - strcpy(tracing_enabled_file, get_debugfileprefix()); + strcpy(tracing_enabled_file, get_tracefs_prefix()); strcat(tracing_enabled_file, "tracing_on"); int tracing_enabled = open(tracing_enabled_file, O_WRONLY); if (tracing_enabled >= 0) { - write(tracing_enabled, "0", 1); + ret = write(tracing_enabled, "0", 1); + if (ret < 0) + fatal("Could not write to %s: %s\n", + tracing_enabled_file, strerror(errno)); close(tracing_enabled); } else fatal("Could not access %s\n", tracing_enabled_file); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rt-tests-2.9/src/ptsematest/ptsematest.c new/rt-tests-2.10/src/ptsematest/ptsematest.c --- old/rt-tests-2.9/src/ptsematest/ptsematest.c 2025-07-01 16:20:28.000000000 +0200 +++ new/rt-tests-2.10/src/ptsematest/ptsematest.c 2026-02-27 21:09:47.000000000 +0100 @@ -62,6 +62,7 @@ cpu_set_t mask; int policy = SCHED_FIFO; struct sched_param schedp; + int ret; memset(&schedp, 0, sizeof(schedp)); schedp.sched_priority = par->priority; @@ -107,12 +108,15 @@ if (par->tracelimit && par->maxdiff > par->tracelimit) { char tracing_enabled_file[MAX_PATH]; - strcpy(tracing_enabled_file, get_debugfileprefix()); + strcpy(tracing_enabled_file, get_tracefs_prefix()); strcat(tracing_enabled_file, "tracing_on"); int tracing_enabled = open(tracing_enabled_file, O_WRONLY); if (tracing_enabled >= 0) { - write(tracing_enabled, "0", 1); + ret = write(tracing_enabled, "0", 1); + if (ret < 0) + fatal("Could not write to %s: %s\n", + tracing_enabled_file, strerror(errno)); close(tracing_enabled); } else fatal("Could not access %s\n", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rt-tests-2.9/src/queuelat/queuelat.c new/rt-tests-2.10/src/queuelat/queuelat.c --- old/rt-tests-2.9/src/queuelat/queuelat.c 2025-07-01 16:20:28.000000000 +0200 +++ new/rt-tests-2.10/src/queuelat/queuelat.c 2026-02-27 21:09:47.000000000 +0100 @@ -331,7 +331,7 @@ { int fd; - fd = open("/sys/kernel/debug/tracing/trace_marker", O_RDWR); + fd = open("/sys/kernel/tracing/trace_marker", O_RDWR); if (fd == -1) { perror("open"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rt-tests-2.9/src/rt-migrate-test/rt-migrate-test.c new/rt-tests-2.10/src/rt-migrate-test/rt-migrate-test.c --- old/rt-tests-2.9/src/rt-migrate-test/rt-migrate-test.c 2025-07-01 16:20:28.000000000 +0200 +++ new/rt-tests-2.10/src/rt-migrate-test/rt-migrate-test.c 2026-02-27 21:09:47.000000000 +0100 @@ -39,9 +39,7 @@ { struct stat st; char *files[] = { - "/sys/kernel/debug/tracing/trace_marker", - "/debug/tracing/trace_marker", - "/debugfs/tracing/trace_marker", + "/sys/kernel/tracing/trace_marker", }; int ret; unsigned int i; @@ -61,6 +59,7 @@ { va_list ap; int n; + int ret; if (mark_fd < 0) return; @@ -69,7 +68,9 @@ n = vsnprintf(buff, BUFSIZ, fmt, ap); va_end(ap); - write(mark_fd, buff, n); + ret = write(mark_fd, buff, n); + if (ret < 0) + fprintf(stderr, "%s: write failed\n", __func__); } #define nano2sec(nan) (nan / 1000000000ULL) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rt-tests-2.9/src/sched_deadline/cyclicdeadline.c new/rt-tests-2.10/src/sched_deadline/cyclicdeadline.c --- old/rt-tests-2.9/src/sched_deadline/cyclicdeadline.c 2025-07-01 16:20:28.000000000 +0200 +++ new/rt-tests-2.10/src/sched_deadline/cyclicdeadline.c 2026-02-27 21:09:47.000000000 +0100 @@ -72,8 +72,6 @@ int bufmsk; struct thread_stat stat; - - char buff[BUFSIZ+1]; }; static int shutdown; @@ -92,7 +90,6 @@ static int all_cpus; static int nr_threads; static int use_nsecs; -static int mark_fd; static int quiet; static char jsonfile[MAX_PATH]; @@ -136,107 +133,6 @@ return debugfs; } -static int my_vsprintf(char *buf, int size, const char *fmt, va_list ap) -{ - const char *p; - char tmp[100]; - char *s = buf; - char *end = buf + size; - char *str; - long long lng; - int l; - int i; - - end[-1] = 0; - - for (p = fmt; *p && s < end; p++) { - if (*p == '%') { - l = 0; - again: - p++; - switch (*p) { - case 's': - if (l) - fatal("Illegal print format l used with %%s\n"); - str = va_arg(ap, char *); - l = strlen(str); - strncpy(s, str, end - s); - s += l; - break; - case 'l': - l++; - goto again; - case 'd': - if (l == 1) { - if (sizeof(long) == 8) - l = 2; - } - if (l == 2) - lng = va_arg(ap, long long); - else if (l > 2) - fatal("Illegal print format l=%d\n", l); - else - lng = va_arg(ap, int); - i = 0; - while (lng > 0) { - tmp[i++] = (lng % 10) + '0'; - lng /= 10; - } - tmp[i] = 0; - l = strlen(tmp); - if (!l) { - *s++ = '0'; - } else { - while (l) - *s++ = tmp[--l]; - } - break; - default: - fatal("Illegal print format '%c'\n", *p); - } - continue; - } - *s++ = *p; - } - - return s - buf; -} - -static void ftrace_write(char *buf, const char *fmt, ...) -{ - va_list ap; - int n; - - if (mark_fd < 0) - return; - - va_start(ap, fmt); - n = my_vsprintf(buf, BUFSIZ, fmt, ap); - va_end(ap); - - write(mark_fd, buf, n); -} - -static void setup_ftrace_marker(void) -{ - struct stat st; - const char *debugfs = find_debugfs(); - char files[strlen(debugfs) + strlen("/tracing/trace_marker") + 1]; - int ret; - - if (strlen(debugfs) == 0) - return; - - sprintf(files, "%s/tracing/trace_marker", debugfs); - ret = stat(files, &st); - if (ret >= 0) - goto found; - /* Do nothing if not mounted */ - return; -found: - mark_fd = open(files, O_WRONLY); -} - /* * Return true if file exists */ @@ -264,20 +160,15 @@ if (strlen(debugfs) == 0) return -1; - snprintf(path, MAX_PATH, "%s/sched/features", debugfs); - ret = check_file_exists(path); - if (ret) - return 0; - - snprintf(path, MAX_PATH, "%s/sched_features", debugfs); + ret = snprintf(path, MAX_PATH, "%s/sched/features", debugfs); + if (ret >= MAX_PATH) + return -1; ret = check_file_exists(path); if (ret) return 0; memset(path, 0, MAX_PATH); - return ret; - } static int setup_hr_tick(void) @@ -448,6 +339,10 @@ if (fd < 0) return fd; ret = write(fd, "0", 2); + if (ret < 0) { + close(fd); + return ret; + } close(fd); return 0; @@ -634,7 +529,14 @@ sprintf(buf, "%d", pid); if (print) printf("Moving %d out of %s\n", pid, name); - write(fd, buf, strlen(buf)); + ret = write(fd, buf, strlen(buf)); + if (ret < 0 && errno == ENOSPC) { + fclose(fp); + close(fd); + fatal("Cannot move tasks out of cpuset %s\n", name); + } + + } fclose(fp); close(fd); @@ -656,19 +558,24 @@ static void teardown(void) { int fd; + int ret; if (all_cpus) return; fd = open_cpuset(CPUSET_PATH, "cpuset.cpu_exclusive"); if (fd >= 0) { - write(fd, "0", 2); + ret = write(fd, "0", 2); + if (ret < 0) + perror("cpuset.cpu_exclusive"); close(fd); } fd = open_cpuset(CPUSET_PATH, "cpuset.sched_load_balance"); if (fd >= 0) { - write(fd, "1", 2); + ret = write(fd, "1", 2); + if (ret < 0) + perror("cpuset.sched_load_balance"); close(fd); } @@ -804,16 +711,15 @@ * preempting us when we started. If that's the case then * adjust the current period. */ - ftrace_write(sd->buff, - "Adjusting period: now: %lld period: %lld delta:%lld%s\n", - now, period, delta, delta > sd->deadline_us / 2 ? - " HUGE ADJUSTMENT" : ""); + tracemark("Adjusting period: now: %lld period: %lld delta:%lld%s\n", + now, period, delta, delta > sd->deadline_us / 2 ? + " HUGE ADJUSTMENT" : ""); period = now; next_period = period + sd->deadline_us; } - ftrace_write(sd->buff, "start at %lld off=%lld (period=%lld next=%lld)\n", - now, now - period, period, next_period); + tracemark("start at %lld off=%lld (period=%lld next=%lld)\n", + now, now - period, period, next_period); diff = now - period; @@ -885,6 +791,7 @@ break_thread_value = stat->max; tracemark("hit latency threshold (%lld > %d)", (unsigned long long) stat->max, tracelimit); + tracing_stop(); } pthread_mutex_unlock(&break_thread_id_lock); break; @@ -1164,6 +1071,7 @@ int nr_cpus; int i; int c; + int ret; rt_init(argc, argv); @@ -1292,7 +1200,6 @@ if (mlockall(MCL_CURRENT|MCL_FUTURE) == -1) warn("mlockall"); - setup_ftrace_marker(); if (tracelimit && trace_marker) enable_trace_mark(); @@ -1387,7 +1294,9 @@ CPUSET_FL_CLONE_CHILDREN | CPUSET_FL_TASKS, pids); - system("cat /sys/fs/cgroup/cpuset/my_cpuset/tasks"); + ret = system("cat /sys/fs/cgroup/cpuset/my_cpuset/tasks"); + if (ret < 0) + perror("system call failed"); } debug(debug_enable, "main thread %d\n", gettid()); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rt-tests-2.9/src/sched_deadline/deadline_test.c new/rt-tests-2.10/src/sched_deadline/deadline_test.c --- old/rt-tests-2.9/src/sched_deadline/deadline_test.c 2025-07-01 16:20:28.000000000 +0200 +++ new/rt-tests-2.10/src/sched_deadline/deadline_test.c 2026-02-27 21:09:47.000000000 +0100 @@ -325,6 +325,7 @@ { va_list ap; int n; + int ret; if (mark_fd < 0) return; @@ -333,7 +334,9 @@ n = my_vsprintf(buf, BUFSIZ, fmt, ap); va_end(ap); - write(mark_fd, buf, n); + ret = write(mark_fd, buf, n); + if (ret < 0) + perror("ftrace write failed"); } /** @@ -626,6 +629,10 @@ if (fd < 0) return fd; ret = write(fd, "0", 2); + if (ret < 0) { + close(fd); + return ret; + } close(fd); return 0; @@ -875,7 +882,19 @@ sprintf(buf, "%d", pid); if (print) printf("Moving %d out of %s\n", pid, name); - write(fd, buf, strlen(buf)); + ret = write(fd, buf, strlen(buf)); + if (ret < 0 && errno == ENOSPC) { + /* + * If we get ENOSPC, then we have a problem, as it + * means that the cpuset is full, and we cannot move + * the tasks out of it. + */ + fclose(fp); + close(fd); + fprintf(stderr, "Failed to move %d out of %s\n", pid, name); + perror("write"); + return; + } } fclose(fp); close(fd); @@ -910,16 +929,21 @@ static void teardown(void) { int fd; + int ret; fd = open_cpuset(CPUSET_PATH, "cpuset.cpu_exclusive"); if (fd >= 0) { - write(fd, "0", 2); + ret = write(fd, "0", 2); + if (ret < 0) + perror("cpuset.cpu_exclusive"); close(fd); } fd = open_cpuset(CPUSET_PATH, "cpuset.sched_load_balance"); if (fd >= 0) { - write(fd, "1", 2); + ret = write(fd, "1", 2); + if (ret < 0) + perror("cpuset.sched_load_balance"); close(fd); } @@ -1790,6 +1814,7 @@ int rt_task = 0; int i; int c; + int ret; cpu_count = sysconf(_SC_NPROCESSORS_CONF); if (cpu_count < 1) { @@ -2041,7 +2066,9 @@ exit(-1); } - system("cat /sys/fs/cgroup/cpuset/my_cpuset/tasks"); + ret = system("cat /sys/fs/cgroup/cpuset/my_cpuset/tasks"); + if (ret < 0) + perror("system call failed"); } pthread_barrier_wait(&barrier); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rt-tests-2.9/src/sigwaittest/sigwaittest.c new/rt-tests-2.10/src/sigwaittest/sigwaittest.c --- old/rt-tests-2.9/src/sigwaittest/sigwaittest.c 2025-07-01 16:20:28.000000000 +0200 +++ new/rt-tests-2.10/src/sigwaittest/sigwaittest.c 2026-02-27 21:09:47.000000000 +0100 @@ -72,6 +72,7 @@ cpu_set_t mask; int policy = SCHED_FIFO; struct sched_param schedp; + int ret; memset(&schedp, 0, sizeof(schedp)); schedp.sched_priority = par->priority; @@ -163,12 +164,15 @@ if (par->tracelimit && par->maxdiff > par->tracelimit) { char tracing_enabled_file[MAX_PATH]; - strcpy(tracing_enabled_file, get_debugfileprefix()); + strcpy(tracing_enabled_file, get_tracefs_prefix()); strcat(tracing_enabled_file, "tracing_on"); int tracing_enabled = open(tracing_enabled_file, O_WRONLY); if (tracing_enabled >= 0) { - write(tracing_enabled, "0", 1); + ret = write(tracing_enabled, "0", 1); + if (ret < 0) + fatal("Could not write to %s: %s\n", + tracing_enabled_file, strerror(errno)); close(tracing_enabled); } else fatal("Could not access %s\n", @@ -489,7 +493,12 @@ fprintf(stderr, "Could not create shared memory\n"); return 1; } - ftruncate(shmem, totalsize); + if (ftruncate(shmem, totalsize) == -1) { + perror("ftruncate failed"); + close(shmem); + shm_unlink("/sigwaittest"); + return 1; + } param = mmap(0, totalsize, PROT_READ|PROT_WRITE, MAP_SHARED, shmem, 0); if (param == MAP_FAILED) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rt-tests-2.9/src/ssdd/ssdd.c new/rt-tests-2.10/src/ssdd/ssdd.c --- old/rt-tests-2.9/src/ssdd/ssdd.c 2025-07-01 16:20:28.000000000 +0200 +++ new/rt-tests-2.10/src/ssdd/ssdd.c 2026-02-27 21:09:47.000000000 +0100 @@ -30,6 +30,7 @@ #include <getopt.h> #include <string.h> #include <signal.h> +#include <time.h> #include <errno.h> #include <sys/types.h> @@ -67,7 +68,7 @@ static int quiet; static char jsonfile[MAX_PATH]; -static int got_sigchld; +volatile int got_sigchld; enum option_value { OPT_NFORKS=1, OPT_NITERS, OPT_HELP, OPT_JSON, OPT_QUIET }; @@ -127,23 +128,33 @@ return STATE_UNKNOWN; } -static int check_sigchld(void) +static int check_sigchld(sigset_t *set) { - int i; + + struct timespec timeout; + + timeout.tv_sec = 10; + timeout.tv_nsec = 0; + int recv_sig = 0; + /* - * The signal is asynchronous so give it some - * time to arrive. + * Check the handler flag, then if need be, wait for the signal to + * arrive */ - for (i = 0; i < 10 && !got_sigchld; i++) - usleep(1000); /* 10 msecs */ - for (i = 0; i < 10 && !got_sigchld; i++) - usleep(2000); /* 20 + 10 = 30 msecs */ - for (i = 0; i < 10 && !got_sigchld; i++) - usleep(4000); /* 40 + 30 = 70 msecs */ - for (i = 0; i < 10 && !got_sigchld; i++) - usleep(8000); /* 80 + 70 = 150 msecs */ - for (i = 0; i < 10 && !got_sigchld; i++) - usleep(16000); /* 160 + 150 = 310 msecs */ + if (!got_sigchld) + recv_sig = sigtimedwait(set, NULL, &timeout); + + if (sigprocmask(SIG_UNBLOCK, set, NULL) == -1) { + printf("EXITING, ERROR: unable to mask signal set\n"); + exit(1); + } + + if (recv_sig == -1) { + printf("EXITING, ERROR: Timeout: no signal received in 10 seconds\n"); + exit(1); + } else if (recv_sig == SIGCHLD) { + got_sigchld = 1; + } return got_sigchld; } @@ -196,6 +207,20 @@ } /* + * Block the signal before it is generated + * Ensures we can synchronously wait for it. + */ + sigset_t set; + + sigemptyset(&set); + sigaddset(&set, SIGCHLD); + + if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) { + printf("EXITING, ERROR: unable to mask signal set\n"); + exit(1); + } + + /* * Attach to the child. */ pstatus = ptrace(PTRACE_ATTACH, child, NULL, NULL); @@ -224,7 +249,7 @@ ret_sig); exit(1); } - if (!check_sigchld()) { + if (!check_sigchld(&set)) { printf("forktest#%d/%d: EXITING, ERROR: " "wait on PTRACE_ATTACH saw a SIGCHLD count of %d, should be 1\n", testid, getpid(), got_sigchld); @@ -238,6 +263,12 @@ * step the tracee. */ for (i = 0; i < nsteps; i++) { + + if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) { + printf("EXITING, ERROR: unable to mask signal set\n"); + exit(1); + } + pstatus = ptrace(PTRACE_SINGLESTEP, child, NULL, NULL); if (pstatus) { @@ -271,7 +302,7 @@ testid, getpid(), i, ret_sig); exit(1); } - if (!check_sigchld()) { + if (!check_sigchld(&set)) { printf("forktest#%d/%d: EXITING, ERROR: " "wait on PTRACE_SINGLESTEP #%d: no SIGCHLD seen " "(signal count == 0), signo %d\n", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rt-tests-2.9/src/svsematest/svsematest.c new/rt-tests-2.10/src/svsematest/svsematest.c --- old/rt-tests-2.9/src/svsematest/svsematest.c 2025-07-01 16:20:28.000000000 +0200 +++ new/rt-tests-2.10/src/svsematest/svsematest.c 2026-02-27 21:09:47.000000000 +0100 @@ -84,6 +84,7 @@ struct sched_param schedp; struct sembuf sb = { 0, 0, 0}; sigset_t sigset; + int ret; sigemptyset(&sigset); pthread_sigmask(SIG_SETMASK, &sigset, NULL); @@ -170,12 +171,15 @@ if (par->tracelimit && par->maxdiff > par->tracelimit) { char tracing_enabled_file[MAX_PATH]; - strcpy(tracing_enabled_file, get_debugfileprefix()); + strcpy(tracing_enabled_file, get_tracefs_prefix()); strcat(tracing_enabled_file, "tracing_on"); int tracing_enabled = open(tracing_enabled_file, O_WRONLY); if (tracing_enabled >= 0) { - write(tracing_enabled, "0", 1); + ret = write(tracing_enabled, "0", 1); + if (ret < 0) + fatal("Could not write to %s: %s\n", + tracing_enabled_file, strerror(errno)); close(tracing_enabled); } else fatal("Could not access %s\n", @@ -544,7 +548,12 @@ fprintf(stderr, "Could not create shared memory\n"); return 1; } - ftruncate(shmem, totalsize); + if (ftruncate(shmem, totalsize) == -1) { + perror("ftruncate failed"); + close(shmem); + shm_unlink("/sigwaittest"); + return 1; + } param = mmap(0, totalsize, PROT_READ|PROT_WRITE, MAP_SHARED, shmem, 0); if (param == MAP_FAILED) {
