diff --git a/SOURCES/oslat-Add-command-line-option-for-bucket-width.patch b/SOURCES/oslat-Add-command-line-option-for-bucket-width.patch new file mode 100644 index 0000000..b861c86 --- /dev/null +++ b/SOURCES/oslat-Add-command-line-option-for-bucket-width.patch @@ -0,0 +1,300 @@ +From cbec2872f7533a87f0b63a30d70386d203ebd138 Mon Sep 17 00:00:00 2001 +From: Crystal Wood +Date: Tue, 13 Dec 2022 16:38:28 -0600 +Subject: [PATCH] oslat: Add command line option for bucket width + +New option -W/--bucket-width allows the user to specify how large of a +range of latencies is covered by a single bucket, including allowing the +creation of sub-microsecond buckets. + +When the flag is not used, output should be unchanged. However, if a +bucket width is specified that is not a multiple of one microsecond, +latencies will be output as fractional microseconds, at nanosecond +precision. This includes JSON output. + +When using this option, it is up to the user to determine what level +of precision is meaningful relative to measurement error, as is noted +in the documentation. + +Signed-off-by: Crystal Wood +Signed-off-by: John Kacur +--- + src/oslat/oslat.8 | 9 +++- + src/oslat/oslat.c | 110 ++++++++++++++++++++++++++++++++-------------- + 2 files changed, 85 insertions(+), 34 deletions(-) + +diff --git a/src/oslat/oslat.8 b/src/oslat/oslat.8 +index 39b36df0db3f..eb96448bfff1 100644 +--- a/src/oslat/oslat.8 ++++ b/src/oslat/oslat.8 +@@ -7,7 +7,7 @@ oslat \- OS Latency Detector + .RI "[ \-shvz ] [ \-b " bucket-size " ] [ \-B " bias " ] [ \-c " cpu-list " ] \ + [ \-C " cpu-main-thread " ] [ \-f " rt-prio " ] [ \-\-json " filename " ] \ + [ \-m " workload-mem " ] [\-t " runtime " ] [ \-T " trace-threshold " ] \ +-[ \-w " workload " ]" ++[ \-w " workload " ] [ \-W " bucket-width " ]" + .SH DESCRIPTION + .B oslat + is an open source userspace polling mode stress program to detect OS level +@@ -57,6 +57,13 @@ NOTE: please make sure the CPU frequency on all testing cores + are locked before using this parmater. If you don't know how + to lock the freq then please don't use this parameter. + .TP ++.B \-W, \-\-bucket-width ++Interval between buckets in nanoseconds ++ ++NOTE: Widths not a multiple of 1000 cause ns-precision output ++You are responsible for considering the impact of measurement ++overhead at the nanosecond scale. ++.TP + .B \-h, \-\-help + Show the help message. + .TP +diff --git a/src/oslat/oslat.c b/src/oslat/oslat.c +index 55302f11986b..b680f1ebce96 100644 +--- a/src/oslat/oslat.c ++++ b/src/oslat/oslat.c +@@ -192,6 +192,10 @@ struct global { + struct timeval tv_start; + int rtprio; + int bucket_size; ++ bool bucket_size_param; ++ int bucket_width; ++ int unit_per_us; ++ int precision; + int trace_threshold; + int runtime; + /* The core that we run the main thread. Default is cpu0 */ +@@ -325,45 +329,46 @@ static float cycles_to_sec(const struct thread *t, uint64_t cycles) + + static void insert_bucket(struct thread *t, stamp_t value) + { +- int index, us; ++ int index; ++ unsigned int lat; + uint64_t extra; ++ double us; + +- index = value / t->counter_mhz; +- assert(index >= 0); +- us = index + 1; +- assert(us > 0); +- ++ lat = (value * g.unit_per_us + t->counter_mhz - 1) / t->counter_mhz; ++ us = (double)lat / g.unit_per_us; + if (!g.preheat && g.trace_threshold && us >= g.trace_threshold) { +- char *line = "%s: Trace threshold (%d us) triggered on cpu %d with %u us!\n" ++ char *line = "%s: Trace threshold (%d us) triggered on cpu %d with %.*f us!\n" + "Stopping the test.\n"; +- tracemark(line, g.app_name, g.trace_threshold, t->core_i, us); +- err_quit(line, g.app_name, g.trace_threshold, t->core_i, us); ++ tracemark(line, g.app_name, g.trace_threshold, t->core_i, ++ g.precision, us); ++ err_quit(line, g.app_name, g.trace_threshold, t->core_i, ++ g.precision, us); + } + + /* Update max latency */ +- if (us > t->maxlat) +- t->maxlat = us; ++ if (lat > t->maxlat) ++ t->maxlat = lat; + +- if (us < t->minlat) +- t->minlat = us; ++ if (lat < t->minlat) ++ t->minlat = lat; + + if (g.bias) { + /* t->bias will be set after pre-heat if user enabled it */ +- us -= g.bias; ++ lat -= g.bias; + /* + * Negative should hardly happen, but if it happens, we assume we're in +- * the smallest bucket, which is 1us. Same to index. ++ * the smallest bucket. + */ +- if (us <= 0) +- us = 1; +- index -= g.bias; +- if (index < 0) +- index = 0; ++ if (lat <= 0) ++ lat = 1; + } + ++ index = lat / g.bucket_width; ++ assert(index >= 0); ++ + /* Too big the jitter; put into the last bucket */ + if (index >= g.bucket_size) { +- /* Keep the extra bit (in us) */ ++ /* Keep the extra bit (in bucket width multiples) */ + extra = index - g.bucket_size; + if (t->overflow_sum + extra < t->overflow_sum) { + /* The uint64_t even overflowed itself; bail out */ +@@ -455,6 +460,19 @@ static void *thread_main(void *arg) + printf("%s\n", end); \ + } while (0) + ++#define putfieldp(label, val, end) do { \ ++ printf("%12s:\t", label); \ ++ for (i = 0; i < g.n_threads; ++i) \ ++ printf(" %.*f", g.precision, \ ++ (double)(val) / g.unit_per_us); \ ++ printf("%s\n", end); \ ++ } while (0) ++ ++static double bucket_to_lat(int bucket) ++{ ++ return (g.bias + (bucket + 1) * (double)g.bucket_width) / g.unit_per_us; ++} ++ + void calculate(struct thread *t) + { + int i, j; +@@ -465,11 +483,11 @@ void calculate(struct thread *t) + /* Calculate average */ + sum = count = 0; + for (j = 0; j < g.bucket_size; j++) { +- sum += 1.0 * t[i].buckets[j] * (g.bias+j+1); ++ sum += t[i].buckets[j] * bucket_to_lat(j); + count += t[i].buckets[j]; + } + /* Add the extra amount of huge spikes in */ +- sum += t->overflow_sum; ++ sum += t->overflow_sum * g.bucket_width; + t[i].average = sum / count; + } + } +@@ -501,16 +519,16 @@ static void write_summary(struct thread *t) + print_dotdotdot = 0; + } + +- snprintf(bucket_name, sizeof(bucket_name), "%03"PRIu64 +- " (us)", g.bias+j+1); ++ snprintf(bucket_name, sizeof(bucket_name), "%03.*f (us)", ++ g.precision, bucket_to_lat(j)); + putfield(bucket_name, t[i].buckets[j], PRIu64, + (j == g.bucket_size - 1) ? " (including overflows)" : ""); + } + +- putfield("Minimum", t[i].minlat, PRIu64, " (us)"); ++ putfieldp("Minimum", t[i].minlat, " (us)"); + putfield("Average", t[i].average, ".3lf", " (us)"); +- putfield("Maximum", t[i].maxlat, PRIu64, " (us)"); +- putfield("Max-Min", t[i].maxlat - t[i].minlat, PRIu64, " (us)"); ++ putfieldp("Maximum", t[i].maxlat, " (us)"); ++ putfieldp("Max-Min", t[i].maxlat - t[i].minlat, " (us)"); + putfield("Duration", cycles_to_sec(&(t[i]), t[i].runtime), + ".3f", " (sec)"); + printf("\n"); +@@ -537,8 +555,8 @@ static void write_summary_json(FILE *f, void *data) + if (t[i].buckets[j] == 0) + continue; + fprintf(f, "%s", comma ? ",\n" : "\n"); +- fprintf(f, " \"%" PRIu64 "\": %" PRIu64, +- g.bias+j+1, t[i].buckets[j]); ++ fprintf(f, " \"%.*f\": %" PRIu64, ++ g.precision, bucket_to_lat(j), t[i].buckets[j]); + comma = 1; + } + if (comma) +@@ -610,6 +628,10 @@ static void usage(int error) + "-v, --version Display the version of the software.\n" + "-w, --workload Specify a kind of workload, default is no workload\n" + " (options: no, memmove)\n" ++ "-W, --bucket-width Interval between buckets in nanoseconds\n" ++ " NOTE: Widths not a multiple of 1000 cause ns-precision output\n" ++ " You are responsible for considering the impact of measurement\n" ++ " overhead at the nanosecond scale.\n" + "-z, --zero-omit Don't display buckets in the output histogram if all zeros.\n" + ); + exit(error); +@@ -630,7 +652,7 @@ static int workload_select(char *name) + } + + enum option_value { +- OPT_BUCKETSIZE=1, OPT_CPU_LIST, OPT_CPU_MAIN_THREAD, ++ OPT_BUCKETSIZE = 1, OPT_BUCKETWIDTH, OPT_CPU_LIST, OPT_CPU_MAIN_THREAD, + OPT_DURATION, OPT_JSON, OPT_RT_PRIO, OPT_HELP, OPT_TRACE_TH, + OPT_WORKLOAD, OPT_WORKLOAD_MEM, OPT_BIAS, + OPT_QUIET, OPT_SINGLE_PREHEAT, OPT_ZERO_OMIT, +@@ -644,6 +666,7 @@ static void parse_options(int argc, char *argv[]) + int option_index = 0; + static struct option options[] = { + { "bucket-size", required_argument, NULL, OPT_BUCKETSIZE }, ++ { "bucket-width", required_argument, NULL, OPT_BUCKETWIDTH }, + { "cpu-list", required_argument, NULL, OPT_CPU_LIST }, + { "cpu-main-thread", required_argument, NULL, OPT_CPU_MAIN_THREAD}, + { "duration", required_argument, NULL, OPT_DURATION }, +@@ -660,7 +683,7 @@ static void parse_options(int argc, char *argv[]) + { "version", no_argument, NULL, OPT_VERSION }, + { NULL, 0, NULL, 0 }, + }; +- int i, c = getopt_long(argc, argv, "b:Bc:C:D:f:hm:qsw:T:vz", ++ int i, c = getopt_long(argc, argv, "b:Bc:C:D:f:hm:qsw:W:T:vz", + options, &option_index); + long ncores; + +@@ -670,6 +693,7 @@ static void parse_options(int argc, char *argv[]) + switch (c) { + case OPT_BUCKETSIZE: + case 'b': ++ g.bucket_size_param = true; + g.bucket_size = strtol(optarg, NULL, 10); + if (g.bucket_size > 1024 || g.bucket_size <= 4) { + printf("Illegal bucket size: %s (should be: 4-1024)\n", +@@ -677,6 +701,20 @@ static void parse_options(int argc, char *argv[]) + exit(1); + } + break; ++ case OPT_BUCKETWIDTH: ++ case 'W': ++ g.bucket_width = strtol(optarg, NULL, 10); ++ if (g.bucket_width <= 0) { ++ printf("Illegal bucket width: %s\n", optarg); ++ exit(1); ++ } ++ if (g.bucket_width % 1000) { ++ g.unit_per_us = 1000; ++ g.precision = 3; ++ } else { ++ g.bucket_width /= 1000; ++ } ++ break; + case OPT_BIAS: + case 'B': + g.enable_bias = 1; +@@ -776,6 +814,9 @@ static void parse_options(int argc, char *argv[]) + break; + } + } ++ ++ if (!g.bucket_size_param && g.precision == 3 && g.bucket_width < 1000) ++ g.bucket_size = BUCKET_SIZE * 1000 / g.bucket_width; + } + + void dump_globals(void) +@@ -811,7 +852,8 @@ static void record_bias(struct thread *t) + bias = t[i].minlat; + } + g.bias = bias; +- printf("Global bias set to %" PRId64 " (us)\n", bias); ++ printf("Global bias set to %.*f (us)\n", g.precision, ++ (double)bias / g.unit_per_us); + } + + int main(int argc, char *argv[]) +@@ -835,6 +877,8 @@ int main(int argc, char *argv[]) + g.app_name = argv[0]; + g.rtprio = 0; + g.bucket_size = BUCKET_SIZE; ++ g.bucket_width = 1; ++ g.unit_per_us = 1; + g.runtime = 1; + g.workload = &workload_list[WORKLOAD_DEFAULT]; + g.workload_mem_size = WORKLOAD_MEM_SIZE; +-- +2.38.1 + diff --git a/SOURCES/rt-tests-hackbench-Add-error-checking-to-connect-and.patch b/SOURCES/rt-tests-hackbench-Add-error-checking-to-connect-and.patch new file mode 100644 index 0000000..2f2dc88 --- /dev/null +++ b/SOURCES/rt-tests-hackbench-Add-error-checking-to-connect-and.patch @@ -0,0 +1,39 @@ +From a3f7cd235a4aaf7771763d3b0b27d96dd4f5f1c1 Mon Sep 17 00:00:00 2001 +From: John Kacur +Date: Tue, 1 Nov 2022 09:30:40 -0400 +Subject: [PATCH 1/4] rt-tests: hackbench: Add error checking to connect and + getsockname + +Add error checking around the calls connect and getsockname + +Signed-off-by: John Kacur +--- + src/hackbench/hackbench.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/hackbench/hackbench.c b/src/hackbench/hackbench.c +index 18c928480103..8c6d83520e57 100644 +--- a/src/hackbench/hackbench.c ++++ b/src/hackbench/hackbench.c +@@ -130,14 +130,16 @@ static int inet_socketpair(int fds[2]) + + if (bind(s1, &sin, len) < 0) + barf("bind"); +- getsockname(s1, &sin, &len); ++ if (getsockname(s1, &sin, &len) < 0) ++ barf("getsockname"); + if (listen(s1, 10) < 0) + barf("listen"); + if (ioctl(s2, FIONBIO, &ul) < 0) + barf("ioctl"); + if (ioctl(s1, FIONBIO, &ul) < 0) + barf("ioctl"); +- connect(s2, &sin, len); ++ if (connect(s2, &sin, len) < 0) ++ barf("connect"); + if ((fds[0] = accept(s1, &sin, &len)) < 0) + barf("accept"); + ul = 0; +-- +2.38.1 + diff --git a/SOURCES/rt-tests-hackbench-Fix-compile-comparison-of-differe.patch b/SOURCES/rt-tests-hackbench-Fix-compile-comparison-of-differe.patch new file mode 100644 index 0000000..41c761f --- /dev/null +++ b/SOURCES/rt-tests-hackbench-Fix-compile-comparison-of-differe.patch @@ -0,0 +1,59 @@ +From fb702d9903b7f8b54a7bd51fcbf5f12ce6bc9540 Mon Sep 17 00:00:00 2001 +From: John Kacur +Date: Tue, 1 Nov 2022 09:46:01 -0400 +Subject: [PATCH 2/4] rt-tests: hackbench: Fix compile comparison of different + signed ints + +Fix compile warnings about comparisons of integers of different +signedness. + +Signed-off-by: John Kacur +--- + src/hackbench/hackbench.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/src/hackbench/hackbench.c b/src/hackbench/hackbench.c +index 8c6d83520e57..dda7690b79a0 100644 +--- a/src/hackbench/hackbench.c ++++ b/src/hackbench/hackbench.c +@@ -200,7 +200,8 @@ static void *sender(struct sender_context *ctx) + /* Now pump to every receiver. */ + for (i = 0; i < loops; i++) { + for (j = 0; j < ctx->num_fds; j++) { +- int ret, done = 0; ++ int ret; ++ size_t done = 0; + + again: + ret = write(ctx->out_fds[j], data + done, sizeof(data)-done); +@@ -231,7 +232,8 @@ static void *receiver(struct receiver_context* ctx) + /* Receive them all */ + for (i = 0; i < ctx->num_packets; i++) { + char data[datasize]; +- int ret, done = 0; ++ int ret; ++ size_t done = 0; + + again: + ret = read(ctx->in_fds[0], data + done, datasize - done); +@@ -289,7 +291,7 @@ static int create_worker(childinfo_t *child, void *ctx, void *(*func)(void *)) + + void signal_workers(childinfo_t *children, unsigned int num_children) + { +- int i; ++ unsigned int i; + printf("signaling %d worker threads to terminate\n", num_children); + for (i=0; i < num_children; i++) { + kill(children[i].pid, SIGTERM); +@@ -517,7 +519,7 @@ int main(int argc, char *argv[]) + if (setjmp(jmpbuf) == 0) { + total_children = 0; + for (i = 0; i < num_groups; i++) { +- int c = group(child_tab, total_children, num_fds, readyfds[1], wakefds[0]); ++ unsigned int c = group(child_tab, total_children, num_fds, readyfds[1], wakefds[0]); + if( c != (num_fds*2) ) { + fprintf(stderr, "%i children started. Expected %i\n", c, num_fds*2); + reap_workers(child_tab, total_children + c, 1); +-- +2.38.1 + diff --git a/SOURCES/rt-tests-hackbench-Fix-compile-warning-about-fall-th.patch b/SOURCES/rt-tests-hackbench-Fix-compile-warning-about-fall-th.patch new file mode 100644 index 0000000..381b34c --- /dev/null +++ b/SOURCES/rt-tests-hackbench-Fix-compile-warning-about-fall-th.patch @@ -0,0 +1,30 @@ +From 4164006a834b93995fb3535508fdf18bff92df7d Mon Sep 17 00:00:00 2001 +From: John Kacur +Date: Tue, 1 Nov 2022 09:50:03 -0400 +Subject: [PATCH 3/4] rt-tests: hackbench: Fix compile warning about fall + through + +print_usage_exit(0) never returns, but the compiler doesn't understand +this. In any case it is not harmful to add a break after this statement. +Do so to keep the unhelpful compiler warning from triggering. + +Signed-off-by: John Kacur +--- + src/hackbench/hackbench.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/hackbench/hackbench.c b/src/hackbench/hackbench.c +index dda7690b79a0..69dd5f087fb6 100644 +--- a/src/hackbench/hackbench.c ++++ b/src/hackbench/hackbench.c +@@ -444,6 +444,7 @@ static void process_options(int argc, char *argv[]) + break; + case 'h': + print_usage_exit(0); ++ break; + case 'l': + if (!(argv[optind] && (loops = atoi(optarg)) > 0)) { + fprintf(stderr, "%s: --loops|-l requires an integer > 0\n", argv[0]); +-- +2.38.1 + diff --git a/SOURCES/rt-tests-hwlatdetect-Fix-incorrect-comment-about-tes.patch b/SOURCES/rt-tests-hwlatdetect-Fix-incorrect-comment-about-tes.patch new file mode 100644 index 0000000..82ec325 --- /dev/null +++ b/SOURCES/rt-tests-hwlatdetect-Fix-incorrect-comment-about-tes.patch @@ -0,0 +1,34 @@ +From 8c7532b710390882ffd7e96d50e75fce99a8249f Mon Sep 17 00:00:00 2001 +From: John Kacur +Date: Fri, 11 Nov 2022 14:48:15 -0500 +Subject: [PATCH 3/3] rt-tests: hwlatdetect: Fix incorrect comment about + testduration + +At some point +self.testduration = 10 +was changed to +self.testduration = 30 + +but retained the comment, "ten seconds" + +Just change the comment to say, "in seconds" so it's clear what unit +we are talking about. + +Signed-off-by: John Kacur + +diff --git a/src/hwlatdetect/hwlatdetect.py b/src/hwlatdetect/hwlatdetect.py +index c5b3a689dcd1..68df58f7e2d0 100755 +--- a/src/hwlatdetect/hwlatdetect.py ++++ b/src/hwlatdetect/hwlatdetect.py +@@ -130,7 +130,7 @@ class Detector: + if not self.debugfs.mount(): + raise RuntimeError("failed to mount debugfs") + self.samples = [] +- self.testduration = 30 # ten seconds ++ self.testduration = 30 # in seconds + self.have_msr = False + self.initsmi = [] + if os.path.exists('/usr/sbin/rdmsr'): +-- +2.31.1 + diff --git a/SOURCES/rt-tests-hwlatdetect-Update-to-integer-division.patch b/SOURCES/rt-tests-hwlatdetect-Update-to-integer-division.patch new file mode 100644 index 0000000..2b086a5 --- /dev/null +++ b/SOURCES/rt-tests-hwlatdetect-Update-to-integer-division.patch @@ -0,0 +1,34 @@ +From 1eaa7feae3225ae82d00d2e1f02986e34c31a38d Mon Sep 17 00:00:00 2001 +From: Leah Leshchinsky +Date: Thu, 10 Nov 2022 10:35:27 -0500 +Subject: [PATCH 2/3] rt-tests: hwlatdetect: Update to integer division + +In Python 3, "/" is a float division operator, as opposed to Python 2, +which defaults to integer division. This results in an error when +calculating width, which assumes an integer. + +Update width division to integer division with the "//" operator. + +Signed-off-by: Leah Leshchinsky +Signed-off-by: John Kacur + +diff --git a/src/hwlatdetect/hwlatdetect.py b/src/hwlatdetect/hwlatdetect.py +index 1efbe7a60059..c5b3a689dcd1 100755 +--- a/src/hwlatdetect/hwlatdetect.py ++++ b/src/hwlatdetect/hwlatdetect.py +@@ -454,9 +454,10 @@ if __name__ == '__main__': + + if args.window: + w = microseconds(args.window) ++ width = w//2 + if w < int(detect.get("width")): +- debug(f"shrinking width to {w//2} for new window of {w}") +- detect.set("width", w/2) ++ debug(f"shrinking width to {width} for new window of {w}") ++ detect.set("width", width) + debug(f"window parameter = {w}") + detect.set("window", w) + debug(f"window for sampling set to {w}us") +-- +2.31.1 + diff --git a/SOURCES/rt-tests-hwlatdetect.py-Covert-to-f-strings.patch b/SOURCES/rt-tests-hwlatdetect.py-Covert-to-f-strings.patch new file mode 100644 index 0000000..f09e92d --- /dev/null +++ b/SOURCES/rt-tests-hwlatdetect.py-Covert-to-f-strings.patch @@ -0,0 +1,225 @@ +From d9acad79fa157f90522b3dc2b745bbb3b72fef1d Mon Sep 17 00:00:00 2001 +From: Leah Leshchinsky +Date: Fri, 11 Nov 2022 13:49:33 -0500 +Subject: [PATCH 1/3] rt-tests: hwlatdetect.py Covert to f-strings + +Add f-strings where applicable for readability. + +Signed-off-by: Leah Leshchinsky +Signed-off-by: John Kacur + +diff --git a/src/hwlatdetect/hwlatdetect.py b/src/hwlatdetect/hwlatdetect.py +index 9ef50f862127..1efbe7a60059 100755 +--- a/src/hwlatdetect/hwlatdetect.py ++++ b/src/hwlatdetect/hwlatdetect.py +@@ -59,7 +59,7 @@ class DebugFS: + if self.premounted or self.mounted: + debug("not mounting debugfs") + return True +- debug("mounting debugfs at %s" % path) ++ debug(f"mounting debugfs at {path}") + self.mountpoint = path + cmd = ['/bin/mount', '-t', 'debugfs', 'none', path] + self.mounted = (subprocess.call(cmd) == 0) +@@ -90,7 +90,7 @@ class DebugFS: + try: + val = f.readline() + except OSError as e: +- print("errno: %s" % e) ++ print(f"errno: {e}") + if e.errno == errno.EAGAIN: + val = None + else: +@@ -192,18 +192,18 @@ class Detector: + count = 0 + threshold = int(self.get("threshold")) + self.c_states_off() +- debug("enabling detector module (threshold: %d)" % threshold) ++ debug(f"enabling detector module (threshold: {threshold})") + self.set("enable", 1) + while self.get("enable") == 0: + debug("still disabled, retrying in a bit") + count += 1 + time.sleep(0.1) +- debug("retrying enable of detector module (%d)" % count) ++ debug(f"retrying enable of detector module ({count})") + self.set("enable", 1) + if self.get("threshold") != threshold: + debug("start: threshold reset by start, fixing") + self.set("threshold", threshold) +- debug("detector module enabled (threshold: %d)" % int(self.get("threshold"))) ++ debug(f"detector module enabled (threshold: {int(self.get('threshold'))})") + + def stop(self): + """ disable the detector """ +@@ -214,7 +214,7 @@ class Detector: + debug("still enabled, retrying in a bit") + count += 1 + time.sleep(0.1) +- debug("retrying disable of detector module(%d)" % count) ++ debug(f"retrying disable of detector module({count})") + self.set("enable", 0) + self.c_states_on() + debug("detector module disabled") +@@ -248,7 +248,7 @@ class Tracer(Detector): + self.outer = int(o) + + def __str__(self): +- return "ts: %s, inner:%d, outer:%d" % (self.timestamp, self.inner, self.outer) ++ return f"ts: {self.timestamp}, inner:{self.inner}, outer:{self.outer}" + + def display(self): + """ convert object to string and print """ +@@ -322,8 +322,8 @@ class Tracer(Detector): + if output: + with open(output, "w") as f: + for s in self.samples: +- f.write("%s\n" % str(s)) +- print("report saved to %s (%d samples)" % (output, len(self.samples))) ++ f.write(f"{s}\n") ++ print(f"report saved to {output} ({len(self.samples)} samples)") + + def display(self): + for s in self.samples: +@@ -341,7 +341,7 @@ def seconds(sval): + if sval.isdigit(): + return int(sval) + if sval[-2].isalpha(): +- raise RuntimeError("illegal suffix for seconds: '%s'" % sval[-2:-1]) ++ raise RuntimeError(f"illegal suffix for seconds: '{sval[-2:-1]}'") + if sval[-1:] == 's': + return int(sval[0:-1]) + if sval[-1:] == 'm': +@@ -352,7 +352,7 @@ def seconds(sval): + return int(sval[0:-1]) * 86400 + if sval[-1:] == 'w': + return int(sval[0:-1]) * 86400 * 7 +- raise RuntimeError("invalid input for seconds: '%s'" % sval) ++ raise RuntimeError(f"invalid input for seconds: '{sval}'") + + + def milliseconds(sval): +@@ -367,7 +367,7 @@ def milliseconds(sval): + return int(sval[0:-1]) * 1000 * 60 + if sval[-1] == 'h': + return int(sval[0:-1]) * 1000 * 60 * 60 +- raise RuntimeError("invalid input for milliseconds: %s" % sval) ++ raise RuntimeError(f"invalid input for milliseconds: {sval}") + + + def microseconds(sval): +@@ -380,7 +380,7 @@ def microseconds(sval): + return int(sval[0:-2]) + if sval[-1:] == 's': + return int(sval[0:-1]) * 1000 * 1000 +- raise RuntimeError("invalid input for microseconds: '%s'" % sval) ++ raise RuntimeError(f"invalid input for microseconds: '{sval}'") + + + if __name__ == '__main__': +@@ -444,37 +444,37 @@ if __name__ == '__main__': + if args.threshold: + t = microseconds(args.threshold) + detect.set("threshold", t) +- debug("threshold set to %dus" % t) ++ debug(f"threshold set to {t}us") + + if args.hardlimit: + hardlimit = microseconds(args.hardlimit) + else: + hardlimit = int(detect.get("threshold")) +- debug("hardlimit set to %dus" % hardlimit) ++ debug(f"hardlimit set to {hardlimit}us") + + if args.window: + w = microseconds(args.window) + if w < int(detect.get("width")): +- debug("shrinking width to %d for new window of %d" % (w/2, w)) ++ debug(f"shrinking width to {w//2} for new window of {w}") + detect.set("width", w/2) +- debug("window parameter = %d" % w) ++ debug(f"window parameter = {w}") + detect.set("window", w) +- debug("window for sampling set to %dus" % w) ++ debug(f"window for sampling set to {w}us") + + if args.width: + w = microseconds(args.width) + if w > int(detect.get("window")): +- debug("widening window to %d for new width of %d" % (w*2, w)) ++ debug(f"widening window to {w*2} for new width of {w}") + detect.set("window", w*2) +- debug("width parameter = %d" % w) ++ debug(f"width parameter = {w}") + detect.set("width", w) +- debug("sample width set to %dus" % w) ++ debug(f"sample width set to {w}us") + + if args.duration: + detect.testduration = seconds(args.duration) + else: + detect.testduration = 120 # 2 minutes +- debug("test duration is %ds" % detect.testduration) ++ debug(f"test duration is {detect.testduration}s") + + if args.watch: + watch = True +@@ -491,18 +491,18 @@ if __name__ == '__main__': + l, r = map(int, [c, c]) + for i in range(l, r + 1): + cpumask |= (1 << i) +- debug("set tracing_cpumask to %x" % cpumask) +- detect.set("cpumask", "%x" % cpumask) ++ debug(f"set tracing_cpumask to {cpumask:x}") ++ detect.set("cpumask", f"{cpumask:x}") + +- info("hwlatdetect: test duration %d seconds" % detect.testduration) +- info(" detector: %s" % detect.type) ++ info(f"hwlatdetect: test duration {detect.testduration} seconds") ++ info(f" detector: {detect.type}") + info(" parameters:") +- info(" CPU list: %s" % args.cpulist) +- info(" Latency threshold: %dus" % int(detect.get("threshold"))) +- info(" Sample window: %dus" % int(detect.get("window"))) +- info(" Sample width: %dus" % int(detect.get("width"))) +- info(" Non-sampling period: %dus" % (int(detect.get("window")) - int(detect.get("width")))) +- info(" Output File: %s" % reportfile) ++ info(f" CPU list: {args.cpulist}") ++ info(f" Latency threshold: {int(detect.get('threshold'))}us") ++ info(f" Sample window: {int(detect.get('window'))}us") ++ info(f" Sample width: {int(detect.get('width'))}us") ++ info(f" Non-sampling period: {(int(detect.get('window')) - int(detect.get('width')))}us") ++ info(f" Output File: {reportfile}") + info("\nStarting test") + + detect.detect() +@@ -513,12 +513,12 @@ if __name__ == '__main__': + if max_latency == 0: + info("Max Latency: Below threshold") + else: +- info("Max Latency: %dus" % max_latency) ++ info(f"Max Latency: {int(max_latency)}us") + +- info("Samples recorded: %d" % len(detect.samples)) ++ info(f"Samples recorded: {len(detect.samples)}") + + exceeding = detect.get("count") +- info("Samples exceeding threshold: %d" % exceeding) ++ info(f"Samples exceeding threshold: {exceeding}") + + if detect.have_msr: + finishsmi = detect.getsmicounts() +@@ -527,8 +527,8 @@ if __name__ == '__main__': + if count > detect.initsmi[i]: + smis = count - detect.initsmi[i] + total_smis += smis +- print("%d SMIs occured on cpu %d" % (smis, i)) +- info("SMIs during run: %d" % total_smis) ++ print(f"{smis} SMIs occured on cpu {i}") ++ info(f"SMIs during run: {total_smis}") + + maxlatency = int(detect.get("max")) + +-- +2.31.1 + diff --git a/SPECS/rt-tests.spec b/SPECS/rt-tests.spec index 59b2a97..da3b90e 100644 --- a/SPECS/rt-tests.spec +++ b/SPECS/rt-tests.spec @@ -6,7 +6,7 @@ Name: rt-tests # Numa argument to make: NUMA=1 # Version: 2.4 -Release: 2%{?dist} +Release: 5%{?dist} License: GPLv2 Group: Development/Tools URL: git://git.kernel.org/pub/scm/utils/rt-tests/rt-tests.git @@ -22,6 +22,13 @@ Requires: bash bc #Patches Patch1: rt-tests-Remove-arbitrary-num-of-threads-limits.patch +Patch2: rt-tests-hackbench-Add-error-checking-to-connect-and.patch +Patch3: rt-tests-hackbench-Fix-compile-comparison-of-differe.patch +Patch4: rt-tests-hackbench-Fix-compile-warning-about-fall-th.patch +Patch5: rt-tests-hwlatdetect.py-Covert-to-f-strings.patch +Patch6: rt-tests-hwlatdetect-Update-to-integer-division.patch +Patch7: rt-tests-hwlatdetect-Fix-incorrect-comment-about-tes.patch +Patch8: oslat-Add-command-line-option-for-bucket-width.patch %description rt-tests is a set of programs that test and measure various components of @@ -31,6 +38,13 @@ latency. It also tests the functioning of priority-inheritance mutexes. %prep %setup -q -n %{name}-%{version} %patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 %build %set_build_flags @@ -85,6 +99,22 @@ rm -rf ${build_root} %{_mandir}/man8/determine_maximum_mpps.8.* %changelog +* Wed Dec 14 2022 Crystal Wood - 2.4-5 +- oslat: Add command line option for bucket width +Resolves: rhbz#2122374 + +* Mon Nov 14 2022 Leah Leshchinsky - 2.4-4 +- hwlatdetect: Convert to fstrings +- hwlatdetect: Update to integer division +- hwlatdetect: Fix incorrect comment about test duration +Resolves: rhbz#2121152 + +* Wed Nov 02 2022 John Kacur - 2.4-3 +- Add error checking in hackbench to connect and getsockname +- Fix compile warnings in hackbench because of comparison of different signs +- Fix compile warnings in hackbench because of warnings about fall through +Resolves: rhbz#bz2115064 + * Fri Oct 07 2022 John Kacur - 2.4-2 - Remove arbitrary limits on number of threads Resolves: rhbz#2132822