From: Mike Galbraith <efault@gmx.de>
To: Peter Zijlstra <peterz@infradead.org>
Cc: linux-rt-users <linux-rt-users@vger.kernel.org>,
Thomas Gleixner <tglx@linutronix.de>,
LKML <linux-kernel@vger.kernel.org>,
Oleg Nesterov <oleg@redhat.com>,
Miklos Szeredi <miklos@szeredi.hu>, mingo <mingo@redhat.com>
Subject: Re: rt14: strace -> migrate_disable_atomic imbalance
Date: Thu, 22 Sep 2011 15:42:23 +0200 [thread overview]
Message-ID: <1316698943.6348.8.camel@marge.simson.net> (raw)
In-Reply-To: <1316693391.31429.12.camel@twins>
On Thu, 2011-09-22 at 14:09 +0200, Peter Zijlstra wrote:
> On Thu, 2011-09-22 at 13:55 +0200, Mike Galbraith wrote:
> > On Thu, 2011-09-22 at 12:00 +0200, Peter Zijlstra wrote:
> >
> > > OK, this one seems to be better.. But its quite vile, not sure I
> > > actually like it anymore.
> >
> > Well, seemed to work, but I see there's a v3 now.
>
> Yeah, just posted it for completeness, not sure its actually going
> anywhere since its slower than the current code (although its hard to
> say with the results changing from reboot to reboot), and its still
> quite ugly..
Hm. Stracing this proglet will soon leave it stuck forever unless the
timer is left running. Virgin rt14 does the same though...
strace ./jitter -c 3 -p 99 -f 1000 -t 10 -r
rt_sigtimedwait([], NULL, NULL, 8) = 64
timer_settime(0x1, TIMER_ABSTIME, {it_interval={0, 0}, it_value={0, 0}}, NULL) = 0
timer_settime(0x1, TIMER_ABSTIME, {it_interval={0, 0}, it_value={1316698141, 166759038}}, NULL) = 0
rt_sigtimedwait([], NULL, NULL, 8) = 64
timer_settime(0x1, TIMER_ABSTIME, {it_interval={0, 0}, it_value={0, 0}}, NULL) = 0
timer_settime(0x1, TIMER_ABSTIME, {it_interval={0, 0}, it_value={1316698141, 167822701}}, NULL) = 0
rt_sigtimedwait([], NULL, NULL, 8) = 64
timer_settime(0x1, TIMER_ABSTIME, {it_interval={0, 0}, it_value={0, 0}}, NULL) = 0
timer_settime(0x1, TIMER_ABSTIME, {it_interval={0, 0}, it_value={1316698141, 168887375}}, NULL) = 0
--- SIGRT_32 (Real-time signal 30) @ 0 (0) ---
rt_sigreturn(0x40) = 0
rt_sigtimedwait([], NULL, NULL, 8^C <unfinished ...>
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <values.h>
#include <sched.h>
#include <signal.h>
#include <time.h>
#include <cpuset.h>
#include <getopt.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/mman.h>
/* compile with gcc -O jitter.c -o jitter -lrt -lm */
#define NSEC_PER_SEC 1000000000ULL
#define USEC_PER_SEC 1000000ULL
#define NSEC_PER_USEC 1000ULL
int frequency = 1000;
int period;
int tolerance = 5;
int delay = 1;
int samples = 1000;
int cpu;
int priority = 1;
int reset_timer;
double *deltas;
double *deviants;
sigset_t mysigset;
char *usage = "Usage: -c <cpu> -d <delay> -f <freq(Hz)> -p <prio> -t <tolerance(us)>\n";
void parse_options(int argc, char **argv)
{
int ch;
extern char *optarg;
extern int optind;
while ((ch = getopt(argc, argv, "c:d:f:p:rt:")) != EOF) {
switch (ch) {
case 'c':
if (sscanf(optarg, "%d", &cpu) != 1 ||
cpu < 0) {
fprintf(stderr,"Invalid cpu.\n");
exit(EXIT_FAILURE);
}
break;
case 'd':
if (sscanf(optarg, "%d", &delay) != 1 ||
delay <= 0) {
fprintf(stderr,"Invalid delay.\n");
exit(EXIT_FAILURE);
}
break;
case 'f':
if (sscanf(optarg, "%d", &frequency) != 1 ||
frequency <= 0) {
fprintf(stderr,"Invalid frequency.\n");
exit(EXIT_FAILURE);
}
break;
case 'r':
reset_timer = 1;
break;
case 'p':
if (sscanf(optarg, "%d", &priority) != 1 ||
priority < 1 || priority > 99) {
fprintf(stderr,"Invalid priority.\n");
exit(EXIT_FAILURE);
}
break;
case 't':
if (sscanf(optarg, "%d", &tolerance) != 1 ||
tolerance < 0) {
fprintf(stderr,"Invalid tolerance.\n");
exit(EXIT_FAILURE);
}
break;
default:
fprintf(stderr, "%s", usage);
exit(EXIT_FAILURE);
break;
}
}
samples = frequency * delay;
period = NSEC_PER_SEC / frequency;
}
long delta(struct timespec *now, struct timespec *then)
{
long delta = now->tv_sec * NSEC_PER_SEC + now->tv_nsec;
delta -= then->tv_sec * NSEC_PER_SEC + then->tv_nsec;
return delta;
}
void signal_handler(int signo)
{
}
void init_timer(timer_t *timer_id)
{
struct sigaction sa;
struct sigevent se;
memset(&sa, 0, sizeof(sa));
sa.sa_flags = SA_RESTART|SA_SIGINFO;
sa.sa_handler = signal_handler;
sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGCHLD);
memset(&se, 0, sizeof(se));
se.sigev_notify = SIGEV_SIGNAL;
se.sigev_signo = SIGRTMAX;
se.sigev_value.sival_int = 0;
if (sigaction(SIGRTMAX, &sa, 0) < 0) {
perror("sigaction");
exit(EXIT_FAILURE);
}
if (timer_create(CLOCK_REALTIME, &se, timer_id) < 0) {
perror("timer_create");
exit(EXIT_FAILURE);
}
sigemptyset(&mysigset);
sigaddset(&mysigset,SIGRTMAX);
}
void set_timer(timer_t timer_id, int period, struct timespec *target)
{
struct itimerspec ts;
struct timespec now;
clock_gettime(CLOCK_REALTIME, target);
if (period) {
target->tv_nsec += period;
if (target->tv_nsec >= NSEC_PER_SEC) {
target->tv_sec++;
target->tv_nsec -= NSEC_PER_SEC;
}
ts.it_value = *target;
ts.it_interval.tv_sec = 0;
ts.it_interval.tv_nsec = reset_timer ? 0 : period;
} else
memset(&ts, 0, sizeof(struct itimerspec));
if (timer_settime(timer_id, TIMER_ABSTIME, &ts, NULL) < 0) {
perror("timer_settime");
exit (EXIT_FAILURE);
}
}
void print_stats(void)
{
struct sched_param sp;
double min = MAXDOUBLE, max = MINDOUBLE;
double sum = 0.0, delta, mean, sd;
double tol = (double)tolerance;
int i, deviant = 0;
sp.sched_priority = 0;
if (sched_setscheduler(0, SCHED_OTHER, &sp) == -1) {
perror("sched_setscheduler");
exit(EXIT_FAILURE);
}
for (i = 0; i < samples; i++) {
deltas[i] /= (double)NSEC_PER_USEC;
if (deltas[i] < min)
min = deltas[i];
if (deltas[i] > max)
max = deltas[i];
if (abs((int)deltas[i]) > tol) {
deviants[deviant] = deltas[i];
deviant++;
}
sum += deltas[i];
}
mean = sum / (double)samples;
/* calculate standard deviation */
sum = 0.0;
for (i = 0; i < samples; i++) {
delta = deltas[i] - mean;
sum += delta*delta;
}
sum /= (double)samples;
sd = sqrt(sum);
printf("jitter:%7.2f\tmin: %9.2f max: %9.2f mean: %9.2f stddev: %7.2f\n",
max - min, min, max, mean, sd);
if (!deviant)
goto out;
min = MAXDOUBLE;
max = MINDOUBLE;
sum = 0.0;
for (i = 0; i < deviant; i++) {
if (deviants[i] < min)
min = deviants[i];
if (deviants[i] > max)
max = deviants[i];
sum += deviants[i];
}
mean = sum / (double)deviant;
/* calculate standard deviation */
sum = 0.0;
for (i = 0; i < deviant; i++) {
delta = deviants[i] - mean;
sum += delta*delta;
}
sum /= (double)deviant;
sd = sqrt(sum);
printf("%d > %d us hits\tmin: %9.2f max: %9.2f mean: %9.2f stddev: %7.2f\n\n",
deviant, tolerance, min, max, mean, sd);
out:
fflush(stdout);
sp.sched_priority = priority;
if (sched_setscheduler(0, SCHED_FIFO, &sp) == -1) {
perror("sched_setscheduler");
exit(EXIT_FAILURE);
}
}
int quit;
void exit_handler(int signo)
{
quit = 1;
}
int main(int argc, char **argv)
{
timer_t timer_id;
struct sched_param sp;
cpu_set_t cpuset;
struct timespec now, then;
int i = 0, sig = 0;
parse_options(argc, argv);
signal(SIGINT, exit_handler);
signal(SIGTERM, exit_handler);
if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0) {
perror("mlockall");
exit(EXIT_FAILURE);
}
if (!(deltas = malloc(samples * sizeof(double)))) {
perror("malloc deltas");
exit(EXIT_FAILURE);
} else if (!(deviants = malloc(samples * sizeof(double)))) {
perror("malloc deviants");
exit(EXIT_FAILURE);
}
CPU_ZERO(&cpuset);
CPU_SET(cpu, &cpuset);
if (sched_setaffinity(0, sizeof(cpuset), &cpuset) == -1) {
perror("setaffinity");
exit(EXIT_FAILURE);
}
sp.sched_priority = priority;
if (sched_setscheduler(0, SCHED_FIFO, &sp) == -1) {
perror("sched_setscheduler");
exit(EXIT_FAILURE);
}
printf("CPU%d priority: %d timer freq: %d Hz tolerance: %d usecs, stats interval: %d %s\n\n",
cpu, sp.sched_priority, frequency, tolerance, delay, "secs");
init_timer(&timer_id);
set_timer(timer_id, period, &then);
while (!quit && reset_timer) {
sigwait(&mysigset,&sig);
set_timer(timer_id, 0, &now);
deltas[i] = (double)delta(&now, &then);
if (i++ >= samples) {
print_stats();
i = 0;
}
set_timer(timer_id, period, &then);
}
clock_gettime(CLOCK_REALTIME, &then);
while (!quit && !reset_timer) {
sigwait(&mysigset,&sig);
clock_gettime(CLOCK_REALTIME, &now);
deltas[i] = (double)delta(&now, &then) - period;
if (i++ >= samples) {
set_timer(timer_id, 0, &then);
print_stats();
i = 0;
set_timer(timer_id, period, &then);
}
clock_gettime(CLOCK_REALTIME, &then);
}
set_timer(timer_id, 0, &now);
exit(EXIT_SUCCESS);
}
next prev parent reply other threads:[~2011-09-22 13:42 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-09-10 9:12 [ANNOUNCE] 3.0.4-rt13 Thomas Gleixner
2011-09-10 14:53 ` Madovsky
2011-09-10 17:27 ` Rolando Martins
2011-09-11 10:35 ` Mike Galbraith
2011-09-11 17:01 ` Mike Galbraith
2011-09-12 7:24 ` Thomas Gleixner
2011-09-12 8:59 ` Peter Zijlstra
2011-09-12 9:05 ` Mike Galbraith
2011-09-12 13:52 ` Mike Galbraith
2011-09-12 14:53 ` Mike Galbraith
2011-09-13 13:36 ` Peter Zijlstra
2011-09-13 15:17 ` Mike Galbraith
2011-09-13 15:08 ` Peter Zijlstra
2011-09-13 15:28 ` Mike Galbraith
2011-09-13 16:13 ` Peter Zijlstra
2011-09-21 10:17 ` rt14: strace -> migrate_disable_atomic imbalance Mike Galbraith
2011-09-21 17:01 ` Peter Zijlstra
2011-09-21 18:50 ` Peter Zijlstra
2011-09-22 4:46 ` Mike Galbraith
2011-09-22 6:31 ` Peter Zijlstra
2011-09-22 8:38 ` Peter Zijlstra
2011-09-22 10:00 ` Peter Zijlstra
2011-09-22 11:55 ` Mike Galbraith
2011-09-22 12:09 ` Peter Zijlstra
2011-09-22 13:42 ` Mike Galbraith [this message]
2011-09-22 14:05 ` Mike Galbraith
2011-09-22 15:20 ` Peter Zijlstra
2011-09-22 14:34 ` Peter Zijlstra
2011-09-22 14:38 ` Mike Galbraith
2011-09-22 14:41 ` Mike Galbraith
2011-09-22 14:41 ` Peter Zijlstra
2011-09-22 14:46 ` Mike Galbraith
2011-09-22 11:31 ` Peter Zijlstra
2011-09-22 11:46 ` Peter Zijlstra
2011-09-22 14:52 ` Oleg Nesterov
2011-09-22 15:13 ` Peter Zijlstra
2011-09-14 9:57 ` [PATCH -rt] ipc/sem: Rework semaphore wakeups Peter Zijlstra
2011-09-14 13:02 ` Mike Galbraith
2011-09-14 18:48 ` Manfred Spraul
2011-09-14 19:23 ` Peter Zijlstra
2011-09-15 17:04 ` Manfred Spraul
2011-09-12 10:04 ` [ANNOUNCE] 3.0.4-rt13 Peter Zijlstra
2011-09-12 11:33 ` Mike Galbraith
2011-09-11 18:14 ` Mike Galbraith
2011-09-12 7:33 ` Thomas Gleixner
2011-09-12 8:05 ` Mike Galbraith
2011-09-12 8:43 ` Mike Galbraith
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1316698943.6348.8.camel@marge.simson.net \
--to=efault@gmx.de \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rt-users@vger.kernel.org \
--cc=miklos@szeredi.hu \
--cc=mingo@redhat.com \
--cc=oleg@redhat.com \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome