diff options
author | Uwe Kleine-König <uwe@kleine-koenig.org> | 2012-07-18 17:14:57 +0200 |
---|---|---|
committer | Uwe Kleine-König <uwe@kleine-koenig.org> | 2012-07-18 17:14:57 +0200 |
commit | c8c033e865d700300331725883cf27082a392558 (patch) | |
tree | 2bb6a4d3d68fbe0940f9e78634544d4206ca4c13 | |
parent | 6932f363c2fafb3849bb3eb0cfb768571646814d (diff) | |
parent | 857cdd5320ce1f293f5dbcbec79cc8fe22b0bebf (diff) | |
download | rt-tests-c8c033e865d700300331725883cf27082a392558.tar.gz |
Merge tag 'v0.84'
Notice: this object is not reachable from any branch.
misc fixes
Notice: this object is not reachable from any branch.
-rw-r--r-- | .gitignore | 31 | ||||
-rw-r--r-- | Makefile | 55 | ||||
-rw-r--r-- | README.markdown | 87 | ||||
-rw-r--r-- | rt-tests.spec-in | 23 | ||||
-rw-r--r-- | src/cyclictest/cyclictest.c | 172 | ||||
-rw-r--r-- | src/cyclictest/rt_numa.h | 1 | ||||
-rwxr-xr-x | src/hwlatdetect/hwlatdetect.py | 4 | ||||
-rw-r--r-- | src/include/error.h | 3 | ||||
-rw-r--r-- | src/include/rt-utils.h | 5 | ||||
-rw-r--r-- | src/lib/error.c | 31 | ||||
-rw-r--r-- | src/lib/rt-utils.c | 32 | ||||
-rw-r--r-- | src/pi_tests/pi_stress.c | 8 | ||||
-rw-r--r-- | src/pmqtest/pmqtest.c | 1 | ||||
-rw-r--r-- | src/ptsematest/ptsematest.c | 1 | ||||
-rw-r--r-- | src/rt-migrate-test/rt-migrate-test.c | 85 | ||||
-rw-r--r-- | src/svsematest/svsematest.c | 1 |
16 files changed, 398 insertions, 142 deletions
@@ -10,19 +10,24 @@ releases BUILD RPMS SRPMS -classic_pi -pi_stress -cyclictest -signaltest + +# +# Top-level programs +# +/classic_pi +/pi_stress +/cyclictest +/signaltest +/hwlatdetect +/rt-migrate-test +/ptsematest +/sendme +/sigwaittest +/svsematest +/pip_stress +/hackbench +/pmqtest + rt-tests.spec -hwlatdetect tags TAGS -rt-migrate-test -ptsematest -sendme -sigwaittest -svsematest -pip_stress -hackbench -pmqtest @@ -1,4 +1,4 @@ -VERSION_STRING = 0.83 +VERSION_STRING = 0.84 sources = cyclictest.c signaltest.c pi_stress.c rt-migrate-test.c \ ptsematest.c sigwaittest.c svsematest.c pmqtest.c sendme.c \ @@ -6,7 +6,7 @@ sources = cyclictest.c signaltest.c pi_stress.c rt-migrate-test.c \ TARGETS = $(sources:.c=) -LIBS = -lrt -lpthread +LIBS = -lrt -lpthread -lrttest -L. EXTRA_LIBS ?= -ldl # for get_cpu DESTDIR ?= prefix ?= /usr/local @@ -14,13 +14,14 @@ bindir ?= $(prefix)/bin mandir ?= $(prefix)/share/man srcdir ?= $(prefix)/src -machinetype = $(shell uname -m | \ - sed -e 's/i.86/i386/' -e 's/mips.*/mips/' -e 's/ppc.*/powerpc/') +machinetype = $(shell $(CC) -dumpmachine | \ + sed -e 's/-.*//' -e 's/i.86/i386/' -e 's/mips.*/mips/' -e 's/ppc.*/powerpc/') ifneq ($(filter x86_64 i386 ia64 mips powerpc,$(machinetype)),) NUMA := 1 endif -CFLAGS = -D_GNU_SOURCE -Wall -Wno-nonnull -Isrc/include +CFLAGS ?= -D_GNU_SOURCE -Wall -Wno-nonnull -Isrc/include +LDFLAGS ?= PYLIB := $(shell python -c 'import distutils.sysconfig; print distutils.sysconfig.get_python_lib()') @@ -60,44 +61,47 @@ all: $(TARGETS) hwlatdetect # Include dependency files, automatically generate them if needed. -include $(sources:.c=.d) -cyclictest: cyclictest.o rt-utils.o - $(CC) $(CFLAGS) -o $@ $^ $(LIBS) $(NUMA_LIBS) +cyclictest: cyclictest.o librttest.a + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) $(NUMA_LIBS) -signaltest: signaltest.o rt-utils.o - $(CC) $(CFLAGS) -o $@ $^ $(LIBS) +signaltest: signaltest.o librttest.a + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) pi_stress: pi_stress.o - $(CC) $(CFLAGS) -o $@ $^ $(LIBS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) hwlatdetect: src/hwlatdetect/hwlatdetect.py chmod +x src/hwlatdetect/hwlatdetect.py ln -s src/hwlatdetect/hwlatdetect.py hwlatdetect rt-migrate-test: rt-migrate-test.o - $(CC) $(CFLAGS) -o $@ $^ $(LIBS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) -ptsematest: ptsematest.o rt-utils.o rt-get_cpu.o - $(CC) $(CFLAGS) -o $@ $^ $(LIBS) $(EXTRA_LIBS) +ptsematest: ptsematest.o librttest.a + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) $(EXTRA_LIBS) -sigwaittest: sigwaittest.o rt-utils.o rt-get_cpu.o - $(CC) $(CFLAGS) -o $@ $^ $(LIBS) $(EXTRA_LIBS) +sigwaittest: sigwaittest.o librttest.a + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) $(EXTRA_LIBS) -svsematest: svsematest.o rt-utils.o rt-get_cpu.o - $(CC) $(CFLAGS) -o $@ $^ $(LIBS) $(EXTRA_LIBS) +svsematest: svsematest.o librttest.a + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) $(EXTRA_LIBS) -pmqtest: pmqtest.o rt-utils.o rt-get_cpu.o - $(CC) $(CFLAGS) -o $@ $^ $(LIBS) $(EXTRA_LIBS) +pmqtest: pmqtest.o librttest.a + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) $(EXTRA_LIBS) -sendme: sendme.o rt-utils.o rt-get_cpu.o - $(CC) $(CFLAGS) -o $@ $^ $(LIBS) $(EXTRA_LIBS) +sendme: sendme.o librttest.a + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) $(EXTRA_LIBS) -pip_stress: pip_stress.o error.o rt-utils.o - $(CC) $(CFLAGS) -o $@ $^ $(LIBS) +pip_stress: pip_stress.o librttest.a + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) hackbench: hackbench.o - $(CC) $(CFLAGS) -o $@ $^ $(LIBS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) -CLEANUP = $(TARGETS) *.o .depend *.*~ *.orig *.rej rt-tests.spec *.d +librttest.a: rt-utils.o error.o rt-get_cpu.o + $(AR) rcs librttest.a rt-utils.o error.o rt-get_cpu.o + +CLEANUP = $(TARGETS) *.o .depend *.*~ *.orig *.rej rt-tests.spec *.d *.a CLEANUP += $(if $(wildcard .git), ChangeLog) .PHONY: clean @@ -121,6 +125,7 @@ install: all cp $(TARGETS) "$(DESTDIR)$(bindir)" if test -n "$(PYLIB)" ; then \ install -D -m 755 src/hwlatdetect/hwlatdetect.py $(DESTDIR)$(PYLIB)/hwlatdetect.py ; \ + rm -f "$(DESTDIR)$(bindir)/hwlatdetect" ; \ ln -s $(PYLIB)/hwlatdetect.py "$(DESTDIR)$(bindir)/hwlatdetect" ; \ fi install -D -m 644 src/backfire/backfire.c "$(DESTDIR)$(srcdir)/backfire/backfire.c" diff --git a/README.markdown b/README.markdown new file mode 100644 index 0000000..3ab6ddf --- /dev/null +++ b/README.markdown @@ -0,0 +1,87 @@ +# RT-Tests + +This repository contains some programs that test various rt-linux features. + +## Usage + +### Compile + + sudo apt-get install build-essential libnuma-dev + make + +### Run tests + +To run one test thread per CPU or per CPU core, each thread on a separate +processor, type + + sudo ./cyclictest -a -t -n -p99 + +On a non-realtime system, you may see something like + + T: 0 ( 3431) P:99 I:1000 C: 100000 Min: 5 Act: 10 Avg: 14 Max: 39242 + T: 1 ( 3432) P:98 I:1500 C: 66934 Min: 4 Act: 10 Avg: 17 Max: 39661 + +The rightmost column contains the most important result, i.e. the worst-case +latency of 39.242 milliseconds. On a realtime-enabled system, the result may +look like + + T: 0 ( 3407) P:99 I:1000 C: 100000 Min: 7 Act: 10 Avg: 10 Max: 18 + T: 1 ( 3408) P:98 I:1500 C: 67043 Min: 7 Act: 8 Avg: 10 Max: 22 + +and, thus, indicate an apparent short-term worst-case latency of 18 +microseconds. + +Running cyclictest only over a short period of time and without creating +appropriate real-time stress conditions is rather meaningless, since the +execution of an asynchronous event from idle state is normally always quite +fast, and every - even non-RT system - can do that. The challenge is to minimize + the latency when reacting to an asynchronuous event, irrespective of what code +path is executed at the time when the external event arrives. +Therefore, specific stress conditions must be present while cyclictest is +running to reliably determine the worst-case latency of a given system. + +### Latency fighting + +If - as in the above example - a low worst-case latency is measured, and this is +the case even under a system load that is equivalent to the load expected under +production conditions, everything is alright. +Of course, the measurement must last suffciently long, preferably 24 hours or +more to run several hundred million test threads. If possible, the `-i` command +line option (thread interval) should be used to increase the number of test +threads over time. +As a role of thumb, the thread interval should be set to a value twice as long +as the expected worst-case latency. If at the end of such a test period the +worst-cae latency still did not exceed the value that is assumed critical for a +given system, the particular kernel in combination with the hardware in use can +then probably be regarded as real-time capable. + +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: + + ./cyclictest -a -t -n -p99 -f -b100 + +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`. +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 + + qemu-30047 2D.h3 742805us : __activate_task+0x42/0x68 <cyclicte-426> (199 1) + qemu-30047 2D.h3 742806us : __trace_start_sched_wakeup+0x40/0x161 <cyclicte-426> (0 -1) + qemu-30047 2DNh3 742806us!: try_to_wake_up+0x422/0x460 <cyclicte-426> (199 -5) + qemu-30047 2DN.1 742939us : __sched_text_start+0xf3/0xdcd (c064e442 0) + +The first column indicates the calling process responsible for triggering the +latency. + +If the trace output is not obvious, it can be submitted to the OSADL Latency +Fight Support Service at +[latency-fighters@osadl.org](mailto:latency-fighters@osadl.org). +In addition to the output of `cat /sys/kernel/debug/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 +against kernel and driver latencies. diff --git a/rt-tests.spec-in b/rt-tests.spec-in index 77a9a08..4ecb90d 100644 --- a/rt-tests.spec-in +++ b/rt-tests.spec-in @@ -62,6 +62,29 @@ rm -rf $RPM_BUILD_ROOT /usr/share/man/man8/hackbench.8.gz %changelog +* Wed May 9 2012 Clark Williams <williams@redhat.com> - 0.84-1 +- [cyclictest] added -Q/--priospread option to +- from Markus Kohlhase <mail@markus-kohlhase.de> + - [docs] added description from osadl.org +- from Darren Hart <dvhart@linux.intel.com> + - Makefile: Support user supplied CFLAGS and LDFLAGS +- from Steven Rostedt <rostedt@goodmis.org> + - rt-tests: Update rt-migrate-test to use ftrace infrastructure +- from John Kacur <jkacur@redhat.com> + - .gitignore: differentiate between program names and directories + - pi_stress: Check the status of sched_getaffinity + - Makefile: Introduce a static library + - Move info, warn, and fatal functions to error.[ch] + - install: Fix failed to create symbolic link hwlatdetect file exists + - cyclictest: Make cyclictest fail if it cannot run with requested priority +- from Frank Rowand <frank.rowand@am.sony.com> + - cyclictest: segfault with '-a' + - cyclictest: avoid unneeded warning + - cyclictest: warn of interaction between '-a', '--smp', and '--numa' + - Makefile: get machinetype from compiler instead of uname + - cyclictest: incorrect first latency value for --verbose option + - cyclictest: printf format compile warning + * Mon Sep 26 2011 Clark Williams <williams@redhat.com> - 0.83-1 - modified Makefile to be smarter about building with NUMA diff --git a/src/cyclictest/cyclictest.c b/src/cyclictest/cyclictest.c index 731b4bd..11b6cea 100644 --- a/src/cyclictest/cyclictest.c +++ b/src/cyclictest/cyclictest.c @@ -1,7 +1,7 @@ /* * High resolution timer test software * - * (C) 2008-2011 Clark Williams <williams@redhat.com> + * (C) 2008-2012 Clark Williams <williams@redhat.com> * (C) 2005-2007 Thomas Gleixner <tglx@linutronix.de> * * This program is free software; you can redistribute it and/or @@ -31,6 +31,7 @@ #include <sys/sysinfo.h> #include <sys/types.h> #include <sys/time.h> +#include <sys/resource.h> #include <sys/utsname.h> #include <sys/mman.h> #include "rt_numa.h" @@ -108,6 +109,8 @@ extern int clock_nanosleep(clockid_t __clock_id, int __flags, int enable_events; +static char *policyname(int policy); + enum { NOTRACE, CTXTSWITCH, @@ -170,6 +173,7 @@ static int duration = 0; static int use_nsecs = 0; static int refresh_on_max; static int force_sched_other; +static int priospread = 0; static pthread_cond_t refresh_on_max_cond = PTHREAD_COND_INITIALIZER; static pthread_mutex_t refresh_on_max_lock = PTHREAD_MUTEX_INITIALIZER; @@ -586,6 +590,79 @@ parse_time_string(char *val) } /* + * Raise the soft priority limit up to prio, if that is less than or equal + * to the hard limit + * if a call fails, return the error + * if successful return 0 + * if fails, return -1 +*/ +static int raise_soft_prio(int policy, const struct sched_param *param) +{ + int err; + int policy_max; /* max for scheduling policy such as SCHED_FIFO */ + int soft_max; + int hard_max; + int prio; + struct rlimit rlim; + + prio = param->sched_priority; + + policy_max = sched_get_priority_max(policy); + if (policy_max == -1) { + err = errno; + err_msg("WARN: no such policy\n"); + return err; + } + + err = getrlimit(RLIMIT_RTPRIO, &rlim); + if (err) { + err = errno; + err_msg_n(err, "WARN: getrlimit failed\n"); + return err; + } + + soft_max = (rlim.rlim_cur == RLIM_INFINITY) ? policy_max : rlim.rlim_cur; + hard_max = (rlim.rlim_max == RLIM_INFINITY) ? policy_max : rlim.rlim_max; + + if (prio > soft_max && prio <= hard_max) { + rlim.rlim_cur = prio; + err = setrlimit(RLIMIT_RTPRIO, &rlim); + if (err) { + err = errno; + err_msg_n(err, "WARN: setrlimit failed\n"); + /* return err; */ + } + } else { + err = -1; + } + + return err; +} + +/* + * Check the error status of sched_setscheduler + * If an error can be corrected by raising the soft limit priority to + * a priority less than or equal to the hard limit, then do so. + */ +static int setscheduler(pid_t pid, int policy, const struct sched_param *param) +{ + int err = 0; + +try_again: + err = sched_setscheduler(pid, policy, param); + if (err) { + err = errno; + if (err == EPERM) { + int err1; + err1 = raise_soft_prio(policy, param); + if (!err1) goto try_again; + } + } + + return err; +} + +/* * timer thread * * Modes: @@ -610,6 +687,7 @@ void *timerthread(void *param) struct thread_stat *stat = par->stats; int stopped = 0; cpu_set_t mask; + pthread_t thread; /* if we're running in numa mode, set our memory node */ if (par->node != -1) @@ -618,7 +696,8 @@ void *timerthread(void *param) if (par->cpu != -1) { CPU_ZERO(&mask); CPU_SET(par->cpu, &mask); - if(sched_setaffinity(0, sizeof(mask), &mask) == -1) + thread = pthread_self(); + if(pthread_setaffinity_np(thread, sizeof(mask), &mask) == -1) warn("Could not set CPU affinity to CPU #%d\n", par->cpu); } @@ -641,7 +720,8 @@ void *timerthread(void *param) memset(&schedp, 0, sizeof(schedp)); schedp.sched_priority = par->prio; - sched_setscheduler(0, par->policy, &schedp); + if (setscheduler(0, par->policy, &schedp)) + fatal("timerthread%d: failed to set priority to %d\n", par->cpu, par->prio); /* Get current time */ clock_gettime(par->clock, &now); @@ -692,35 +772,50 @@ void *timerthread(void *param) case MODE_CLOCK_NANOSLEEP: if (par->timermode == TIMER_ABSTIME) { - ret = clock_nanosleep(par->clock, TIMER_ABSTIME, - &next, NULL); + if ((ret = clock_nanosleep(par->clock, TIMER_ABSTIME, &next, NULL))) { + if (ret != EINTR) + warn("clock_nanosleep failed. errno: %d\n", errno); + goto out; + } } else { - clock_gettime(par->clock, &now); - ret = clock_nanosleep(par->clock, TIMER_RELTIME, - &interval, NULL); + if ((ret = clock_gettime(par->clock, &now))) { + if (ret != EINTR) + warn("clock_gettime() failed: %s", strerror(errno)); + goto out; + } + if ((ret = clock_nanosleep(par->clock, TIMER_RELTIME, &interval, NULL))) { + if (ret != EINTR) + warn("clock_nanosleep() failed. errno: %d\n", errno); + goto out; + } next.tv_sec = now.tv_sec + interval.tv_sec; next.tv_nsec = now.tv_nsec + interval.tv_nsec; tsnorm(&next); } - - /* Avoid negative calcdiff result if clock_nanosleep() - * gets interrupted. - */ - if (ret == EINTR) - goto out; - break; case MODE_SYS_NANOSLEEP: - clock_gettime(par->clock, &now); - nanosleep(&interval, NULL); + if ((ret = clock_gettime(par->clock, &now))) { + if (ret != EINTR) + warn("clock_gettime() failed: errno %d\n", errno); + goto out; + } + if (nanosleep(&interval, NULL)) { + if (errno != EINTR) + warn("nanosleep failed. errno: %d\n", errno); + goto out; + } next.tv_sec = now.tv_sec + interval.tv_sec; next.tv_nsec = now.tv_nsec + interval.tv_nsec; tsnorm(&next); break; } - clock_gettime(par->clock, &now); + if ((ret = clock_gettime(par->clock, &now))) { + if (ret != EINTR) + warn("clock_getttime() failed. errno: %d\n", errno); + goto out; + } if (use_nsecs) diff = calcdiff_ns(now, next); @@ -749,7 +844,6 @@ void *timerthread(void *param) pthread_mutex_unlock(&break_thread_id_lock); } stat->act = diff; - stat->cycles++; if (par->bufmsk) stat->values[stat->cycles & par->bufmsk] = diff; @@ -762,6 +856,8 @@ void *timerthread(void *param) stat->hist_array[diff]++; } + stat->cycles++; + next.tv_sec += interval.tv_sec; next.tv_nsec += interval.tv_nsec; if (par->mode == MODE_CYCLIC) { @@ -845,6 +941,7 @@ static void display_help(int error) "-p PRIO --prio=PRIO priority of highest prio thread\n" "-P --preemptoff Preempt off tracing (used with -b)\n" "-q --quiet print only a summary on exit\n" + "-Q --priospread spread priority levels starting at specified value\n" "-r --relative use relative timer instead of absolute\n" "-s --system use sys_nanosleep and sys_setitimer\n" "-t --threads one thread per available processor\n" @@ -942,10 +1039,11 @@ static char *policyname(int policy) static void process_options (int argc, char *argv[]) { int error = 0; + int option_affinity = 0; int max_cpus = sysconf(_SC_NPROCESSORS_CONF); for (;;) { - int option_index = 0; + int option_index = 0; /** Options for getopt */ static struct option long_options[] = { {"affinity", optional_argument, NULL, 'a'}, @@ -984,18 +1082,18 @@ static void process_options (int argc, char *argv[]) {"smp", no_argument, NULL, 'S'}, {"numa", no_argument, NULL, 'U'}, {"latency", required_argument, NULL, 'e'}, + {"priospread", no_argument, NULL, 'Q'}, {NULL, 0, NULL, 0} }; - int c = getopt_long(argc, argv, "a::b:Bc:Cd:Efh:H:i:Il:MnNo:O:p:PmqrsSt::uUvD:wWT:y:e:", + int c = getopt_long(argc, argv, "a::b:Bc:Cd:Efh:H:i:Il:MnNo:O:p:PmqQrsSt::uUvD:wWT:y:e:", long_options, &option_index); if (c == -1) break; switch (c) { case 'a': - if (smp) { - warn("-a ignored due to --smp\n"); + option_affinity = 1; + if (smp || numa) break; - } if (optarg != NULL) { affinity = atoi(optarg); setaffinity = AFFINITY_SPECIFIED; @@ -1045,6 +1143,7 @@ static void process_options (int argc, char *argv[]) } break; case 'q': quiet = 1; break; + case 'Q': priospread = 1; break; case 'r': timermode = TIMER_RELTIME; break; case 's': use_system = MODE_SYS_OFFSET; break; case 't': @@ -1084,6 +1183,8 @@ static void process_options (int argc, char *argv[]) if (smp) fatal("numa and smp options are mutually exclusive\n"); #ifdef NUMA + if (numa_available() == -1) + fatal("NUMA functionality not available!"); numa = 1; num_threads = max_cpus; setaffinity = AFFINITY_USEALL; @@ -1104,6 +1205,14 @@ static void process_options (int argc, char *argv[]) } } + if (option_affinity) { + if (smp) { + warn("-a ignored due to --smp\n"); + } else if (numa) { + warn("-a ignored due to --numa\n"); + } + } + if (setaffinity == AFFINITY_SPECIFIED) { if (affinity < 0) error = 1; @@ -1140,6 +1249,12 @@ static void process_options (int argc, char *argv[]) if (priority < 0 || priority > 99) error = 1; + if (priospread && priority == 0) { + fprintf(stderr, "defaulting realtime priority to %d\n", + num_threads+1); + priority = num_threads+1; + } + if (priority && (policy != SCHED_FIFO && policy != SCHED_RR)) { fprintf(stderr, "policy and priority don't match: setting policy to SCHED_FIFO\n"); policy = SCHED_FIFO; @@ -1456,7 +1571,7 @@ int main(int argc, char **argv) par->policy = SCHED_OTHER; force_sched_other = 1; } - if (priority && !histogram && !smp && !numa) + if (priospread) priority--; par->clock = clocksources[clocksel]; par->mode = mode; @@ -1561,7 +1676,7 @@ int main(int argc, char **argv) print_tids(parameters, num_threads); if (break_thread_id) { printf("# Break thread: %d\n", break_thread_id); - printf("# Break value: %lu\n", break_thread_value); + printf("# Break value: %llu\n", (unsigned long long)break_thread_value); } } @@ -1588,8 +1703,9 @@ int main(int argc, char **argv) if (trace_fd >= 0) close(trace_fd); - /* turn off all events */ - event_disable_all(); + if (enable_events) + /* turn off all events */ + event_disable_all(); /* turn off the function tracer */ fileprefix = procfileprefix; diff --git a/src/cyclictest/rt_numa.h b/src/cyclictest/rt_numa.h index 2b91615..4ae10ee 100644 --- a/src/cyclictest/rt_numa.h +++ b/src/cyclictest/rt_numa.h @@ -15,6 +15,7 @@ #define _RT_NUMA_H #include "rt-utils.h" +#include "error.h" static int numa = 0; diff --git a/src/hwlatdetect/hwlatdetect.py b/src/hwlatdetect/hwlatdetect.py index 66e66a2..ca47c1c 100755 --- a/src/hwlatdetect/hwlatdetect.py +++ b/src/hwlatdetect/hwlatdetect.py @@ -519,11 +519,13 @@ if __name__ == '__main__': info("Samples exceeding threshold: %d" % exceeding) if reportfile: + count = 0 f = open(reportfile, "w") for s in detect.samples: + count += 1 f.write("%s\n" % s) f.close() - info("sample data written to %s" % reportfile) + info("sample data (%d samples) written to %s" % (count, reportfile)) else: for s in detect.samples: print "%s" % s diff --git a/src/include/error.h b/src/include/error.h index 512b3a6..1e33f6c 100644 --- a/src/include/error.h +++ b/src/include/error.h @@ -10,6 +10,9 @@ void err_exit(int err, char *fmt, ...); void err_msg(char *fmt, ...); void err_msg_n(int err, char *fmt, ...); void err_quit(char *fmt, ...); +void info(char *fmt, ...); +void warn(char *fmt, ...); +void fatal(char *fmt, ...); void err_doit(int err, const char *fmt, va_list ap); #endif /* __ERROR_H */ diff --git a/src/include/rt-utils.h b/src/include/rt-utils.h index 316b09c..4a7d01f 100644 --- a/src/include/rt-utils.h +++ b/src/include/rt-utils.h @@ -1,7 +1,6 @@ #ifndef __RT_UTILS_H #define __RT_UTILS_H - #define _STR(x) #x #define STR(x) _STR(x) #define MAX_PATH 256 @@ -18,8 +17,4 @@ int event_disable(char *event); int event_enable_all(void); int event_disable_all(void); -void warn(char *fmt, ...); -void fatal(char *fmt, ...); -void info(char *fmt, ...); - #endif /* __RT_UTILS.H */ diff --git a/src/lib/error.c b/src/lib/error.c index e9fe58f..1b5de5d 100644 --- a/src/lib/error.c +++ b/src/lib/error.c @@ -46,6 +46,37 @@ void err_quit(char *fmt, ...) exit(1); } +void info(char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fputs("INFO: ", stderr); + err_doit(0, fmt, ap); + va_end(ap); +} + +void warn(char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fputs("WARN: ", stderr); + err_doit(0, fmt, ap); + va_end(ap); +} + +void fatal(char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fputs("FATAL: ", stderr); + err_doit(0, fmt, ap); + va_end(ap); + exit(EXIT_FAILURE); +} + void err_doit(int err, const char *fmt, va_list ap) { if (err) diff --git a/src/lib/rt-utils.c b/src/lib/rt-utils.c index ec71dbd..f4da4b3 100644 --- a/src/lib/rt-utils.c +++ b/src/lib/rt-utils.c @@ -17,6 +17,7 @@ #include <sys/stat.h> #include <unistd.h> #include "rt-utils.h" +#include "error.h" static char debugfileprefix[MAX_PATH]; @@ -272,34 +273,3 @@ int check_privs(void) return sched_setscheduler(0, policy, &old_param); } -void info(char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - fputs("INFO: ", stderr); - vfprintf(stderr, fmt, ap); - va_end(ap); -} - -void warn(char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - fputs("WARNING: ", stderr); - vfprintf(stderr, fmt, ap); - va_end(ap); -} - -void fatal(char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - fputs("FATAL: ", stderr); - vfprintf(stderr, fmt, ap); - va_end(ap); - exit(EXIT_FAILURE); -} - diff --git a/src/pi_tests/pi_stress.c b/src/pi_tests/pi_stress.c index 0940567..e273d62 100644 --- a/src/pi_tests/pi_stress.c +++ b/src/pi_tests/pi_stress.c @@ -597,9 +597,17 @@ void *reporter(void *arg) int verify_cpu(int cpu) { int status; + int err; cpu_set_t mask; + CPU_ZERO(&mask); + status = sched_getaffinity(0, sizeof(cpu_set_t), &mask); + if (status == -1) { + err = errno; + fprintf(stderr, "sched_getaffinity %s\n", strerror(err)); + exit(-1); + } if (CPU_ISSET(cpu, &mask)) return SUCCESS; diff --git a/src/pmqtest/pmqtest.c b/src/pmqtest/pmqtest.c index 2ac6c55..b811d95 100644 --- a/src/pmqtest/pmqtest.c +++ b/src/pmqtest/pmqtest.c @@ -37,6 +37,7 @@ #include <mqueue.h> #include "rt-utils.h" #include "rt-get_cpu.h" +#include "error.h" #include <pthread.h> diff --git a/src/ptsematest/ptsematest.c b/src/ptsematest/ptsematest.c index 14c3f81..92f0ab5 100644 --- a/src/ptsematest/ptsematest.c +++ b/src/ptsematest/ptsematest.c @@ -36,6 +36,7 @@ #include <utmpx.h> #include "rt-utils.h" #include "rt-get_cpu.h" +#include "error.h" #include <pthread.h> diff --git a/src/rt-migrate-test/rt-migrate-test.c b/src/rt-migrate-test/rt-migrate-test.c index 1963641..e3c7a09 100644 --- a/src/rt-migrate-test/rt-migrate-test.c +++ b/src/rt-migrate-test/rt-migrate-test.c @@ -44,39 +44,55 @@ #include <errno.h> #include <sched.h> #include <pthread.h> -#ifdef LOGDEV -# include <dump_log.h> -# define do_logdev_open() open("/debug/logdev/write", O_WRONLY) -# define do_logdev_close(ld) close(ld) -__thread char buff[BUFSIZ]; -static lgprint(int fd, const char *fmt, ...) + +#define gettid() syscall(__NR_gettid) + +#ifndef VERSION_STRING +#define VERSION_STRING 0.3 +#endif + +int nr_tasks; +int lfd; + +static int mark_fd = -1; +static __thread char buff[BUFSIZ+1]; + +static void setup_ftrace_marker(void) +{ + struct stat st; + char *files[] = { + "/sys/kernel/debug/tracing/trace_marker", + "/debug/tracing/trace_marker", + "/debugfs/tracing/trace_marker", + }; + int ret; + int i; + + for (i = 0; i < (sizeof(files) / sizeof(char *)); i++) { + ret = stat(files[i], &st); + if (ret >= 0) + goto found; + } + /* todo, check mounts system */ + return; +found: + mark_fd = open(files[i], O_WRONLY); +} + +static void ftrace_write(const char *fmt, ...) { va_list ap; int n; + if (mark_fd < 0) + return; + va_start(ap, fmt); n = vsnprintf(buff, BUFSIZ, fmt, ap); va_end(ap); - write(fd, buff, n); + write(mark_fd, buff, n); } -#else -# define do_logdev_open() (0) -# define do_logdev_close(lfd) do { } while(0) -# define logdev_print_set(x) do { } while(0) -# define logdev_switch_set(x) do { } while(0) -# define lgprint(x...) do { } while(0) -#endif - - -#define gettid() syscall(__NR_gettid) - -#ifndef VERSION_STRING -#define VERSION_STRING "V 0.3" -#endif - -int nr_tasks; -int lfd; #define nano2sec(nan) (nan / 1000000000ULL) #define nano2ms(nan) (nan / 1000000ULL) @@ -360,8 +376,8 @@ void *start_task(void *data) } pthread_barrier_wait(&start_barrier); start_time = get_time(); - lgprint(lfd, "Thread %d: started %lld diff %lld\n", - pid, start_time, start_time - now); + ftrace_write("Thread %d: started %lld diff %lld\n", + pid, start_time, start_time - now); l = busy_loop(start_time); record_time(id, start_time, l); pthread_barrier_wait(&end_barrier); @@ -403,8 +419,6 @@ static int check_times(int l) static void stop_log(int sig) { - logdev_print_set(0); - logdev_switch_set(0); stop = 1; } @@ -527,27 +541,25 @@ int main (int argc, char **argv) print_progress_bar(0); - lfd = do_logdev_open(); - logdev_print_set(1); - logdev_switch_set(1); + setup_ftrace_marker(); for (loop=0; loop < nr_runs; loop++) { unsigned long long end; now = get_time(); - lgprint(lfd, "Loop %d now=%lld\n", loop, now); + ftrace_write("Loop %d now=%lld\n", loop, now); pthread_barrier_wait(&start_barrier); - lgprint(lfd, "All running!!!\n"); + ftrace_write("All running!!!\n"); nanosleep(&intv, NULL); print_progress_bar((loop * 100)/ nr_runs); end = get_time(); - lgprint(lfd, "Loop %d end now=%lld diff=%lld\n", loop, end, end - now); + ftrace_write("Loop %d end now=%lld diff=%lld\n", loop, end, end - now); pthread_barrier_wait(&end_barrier); @@ -557,8 +569,6 @@ int main (int argc, char **argv) break; } } - do_logdev_close(lfd); - putc('\n', stderr); pthread_barrier_wait(&start_barrier); @@ -568,9 +578,6 @@ int main (int argc, char **argv) for (i=0; i < nr_tasks; i++) pthread_join(threads[i], (void*)&thread_pids[i]); - logdev_print_set(0); - logdev_switch_set(0); - print_results(); if (stop) { diff --git a/src/svsematest/svsematest.c b/src/svsematest/svsematest.c index d4ee1c4..89473a5 100644 --- a/src/svsematest/svsematest.c +++ b/src/svsematest/svsematest.c @@ -42,6 +42,7 @@ #include <sys/mman.h> #include "rt-utils.h" #include "rt-get_cpu.h" +#include "error.h" #define gettid() syscall(__NR_gettid) |