summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUwe Kleine-König <uwe@kleine-koenig.org>2012-07-18 17:14:57 +0200
committerUwe Kleine-König <uwe@kleine-koenig.org>2012-07-18 17:14:57 +0200
commitc8c033e865d700300331725883cf27082a392558 (patch)
tree2bb6a4d3d68fbe0940f9e78634544d4206ca4c13
parent6932f363c2fafb3849bb3eb0cfb768571646814d (diff)
parent857cdd5320ce1f293f5dbcbec79cc8fe22b0bebf (diff)
downloadrt-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--.gitignore31
-rw-r--r--Makefile55
-rw-r--r--README.markdown87
-rw-r--r--rt-tests.spec-in23
-rw-r--r--src/cyclictest/cyclictest.c172
-rw-r--r--src/cyclictest/rt_numa.h1
-rwxr-xr-xsrc/hwlatdetect/hwlatdetect.py4
-rw-r--r--src/include/error.h3
-rw-r--r--src/include/rt-utils.h5
-rw-r--r--src/lib/error.c31
-rw-r--r--src/lib/rt-utils.c32
-rw-r--r--src/pi_tests/pi_stress.c8
-rw-r--r--src/pmqtest/pmqtest.c1
-rw-r--r--src/ptsematest/ptsematest.c1
-rw-r--r--src/rt-migrate-test/rt-migrate-test.c85
-rw-r--r--src/svsematest/svsematest.c1
16 files changed, 398 insertions, 142 deletions
diff --git a/.gitignore b/.gitignore
index 44b3d4d..047925c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
diff --git a/Makefile b/Makefile
index 4038dcc..3a82407 100644
--- a/Makefile
+++ b/Makefile
@@ -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)