public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Ingo Molnar <mingo@elte.hu>
To: Steven Rostedt <rostedt@goodmis.org>
Cc: Fernando Lopez-Lezcano <nando@ccrma.Stanford.EDU>,
	linux-kernel@vger.kernel.org,
	"Paul E. McKenney" <paulmck@us.ibm.com>,
	"K.R. Foley" <kr@cybsft.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	pluto@agmk.net, john cooper <john.cooper@timesys.com>,
	Benedikt Spranger <bene@linutronix.de>,
	Daniel Walker <dwalker@mvista.com>,
	Tom Rini <trini@kernel.crashing.org>,
	George Anzinger <george@mvista.com>
Subject: Re: test time-warps [was: Re: 2.6.14-rt13]
Date: Tue, 22 Nov 2005 12:16:23 +0100	[thread overview]
Message-ID: <20051122111623.GA948@elte.hu> (raw)
In-Reply-To: <Pine.LNX.4.58.0511212012020.5461@gandalf.stny.rr.com>


* Steven Rostedt <rostedt@goodmis.org> wrote:

> Hi Ingo,
> 
> I'm running -rt13 with the following command line:
> 
> root=/dev/md0 ro console=ttyS0,115200 console=tty0 nmi_watchdog=2 lapic
> earlyprintk=ttyS0,115200 idle=poll
> 
> I just got the following output:
> 
> $ ./time-warp-test
> #CPUs: 2
> running 2 tasks to check for time-warps.
> warp ..        -5 cycles, ... 0000004fc2ab2b7f -> 0000004fc2ab2b7a ?
> warp ..       -12 cycles, ... 000000506d1d558c -> 000000506d1d5580 ?
> warp ..       -97 cycles, ... 000000536c8868d3 -> 000000536c886872 ?
> warp ..       -99 cycles, ... 00000059ae9d49a1 -> 00000059ae9d493e ?
> warp ..      -110 cycles, ... 00000059ed0f05d6 -> 00000059ed0f0568 ?
> warp ..      -118 cycles, ... 0000007392963142 -> 00000073929630cc ?
> warp ..      -122 cycles, ... 0000007d6a94bc76 -> 0000007d6a94bbfc ?
> warp ..      -346 cycles, ... 0000008acf28a18e -> 0000008acf28a034 ?
> warp ..      -390 cycles, ... 0000008b2fc61fef -> 0000008b2fc61e69 ?

i've attached an updated utility below. But i too can see similar output 
on an X2. A TSC-warp of 390 cycles _might_ be OK, but there are no 
guarantees. It wont show up as a usecs-level (i.e. gettimeofday()) warp, 
because 390 cycles is still much lower than the ~2000 cycles one 
microsecond takes, but it could cause problems for other TSC users.
 
Basically if there is an observable and provable warp in the TSC output 
then it must not be used for any purpose that is not strictly 
per-CPU-ified (such as userspace threads bound to a single CPU, and the 
TSC never used between threads).

	Ingo

---------{ time-warp-test.c }--------->
/*
 * Copyright (C) 2005, Ingo Molnar
 *
 * time-warp-test.c: check TSC synchronity on x86 CPUs. Also detects
 *                   gettimeofday()-level time warps.
 */
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>
#include <linux/unistd.h>
#include <unistd.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <regex.h>
#include <fcntl.h>
#include <time.h>
#include <sys/mman.h>
#include <dlfcn.h>
#include <popt.h>
#include <sys/socket.h>
#include <ctype.h>
#include <assert.h>
#include <sched.h>

#define TEST_TSC 1
#define TEST_TOD 1

#if !TEST_TSC && !TEST_TOD
# error this makes no sense ...
#endif

#if DEBUG
# define Printf(x...) printf(x)
#else
# define Printf(x...) do { } while (0)
#endif

/*
 * Shared locks and variables between the test tasks:
 */
enum {
	SHARED_TSC = 0,
	SHARED_LOCK = 2,
	SHARED_TOD = 3,
	SHARED_WORST_TSC = 5,
	SHARED_WORST_TOD = 7,
	SHARED_NR_TSC_WARPS = 9,
	SHARED_NR_TOD_WARPS = 10,
};

#define SHARED(x)	(*(shared + SHARED_##x))
#define SHARED_LL(x)	(*(long long *)(shared + SHARED_##x))

#define BUG_ON(c) assert(!(c))

typedef unsigned long long cycles_t;
typedef unsigned long long usecs_t;

#define rdtscll(val)					\
do {							\
	__asm__ __volatile__("rdtsc" : "=A" (val));	\
} while (0)

#define rdtod(val)					\
do {							\
	struct timeval tv;				\
							\
	gettimeofday(&tv, NULL);			\
	(val) = tv.tv_sec * 1000000LL + tv.tv_usec;	\
} while (0)

static unsigned long *setup_shared_var(void)
{
	char zerobuff [4096] = { 0, };
	int ret, fd;
	unsigned long *buf;

	fd = creat(".tmp_mmap", 0700);
	BUG_ON(fd == -1);
	close(fd);

	fd = open(".tmp_mmap", O_RDWR|O_CREAT|O_TRUNC);
	BUG_ON(fd == -1);
	ret = write(fd, zerobuff, 4096);
	BUG_ON(ret != 4096);

	buf = (void *)mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
	BUG_ON(buf == (void *)-1);

	close(fd);

	return buf;
}

#define LOOPS 1000000

static inline unsigned long
cmpxchg(volatile unsigned long *ptr, unsigned long old, unsigned long new)
{
	unsigned long prev;

	__asm__ __volatile__("lock; cmpxchg %b1,%2"
			     : "=a"(prev)
			     : "q"(new), "m"(*(ptr)), "0"(old)
			     : "memory");
	return prev;
}

static inline void lock(unsigned long *flag)
{
	while (cmpxchg(flag, 0, 1) != 0)
		/* nothing */;
}

static inline void unlock(unsigned long *flag)
{
	*flag = 0;
}

static void print_status(unsigned long *shared)
{
	const char progress[] = "\\|/-";
	static usecs_t prev_tod;
	static int count1, count2;

	usecs_t tod;

	count1++;
	if (count1 < 1000)
		return;
	count1 = 0;

	rdtod(tod);
	if (tod - prev_tod < 100000ULL)
		return;
	prev_tod = tod;
	count2++;

	if (TEST_TSC)
		printf("| # of TSC-warps:%ld", SHARED(NR_TSC_WARPS));

	if (TEST_TOD)
		printf(" | # of TOD-warps:%ld", SHARED(NR_TOD_WARPS));

	printf(" %c\r", progress[count2 & 3]);
	fflush(stdout);
}

static inline void test_TSC(unsigned long *shared)
{
#if TEST_TSC
	cycles_t t0, t1;
	long long delta;

	lock(&SHARED(LOCK));
	rdtscll(t1);
	t0 = SHARED_LL(TSC);
	SHARED_LL(TSC) = t1;

	delta = t1-t0;
	if (delta < 0) {
		SHARED(NR_TSC_WARPS)++;
		if (delta < SHARED_LL(WORST_TSC)) {
			SHARED_LL(WORST_TSC) = delta;
			fprintf(stderr, "\rnew TSC-warp maximum: %9Ld cycles, %016Lx -> %016Lx\n",
				delta, t0, t1);
		}
	}
	unlock(&SHARED(LOCK));
#endif
}

static inline void test_TOD(unsigned long *shared)
{
#if TEST_TOD
	usecs_t T0, T1;
	long long delta;

	lock(&SHARED(LOCK));
	rdtod(T1);
	T0 = SHARED_LL(TOD);
	SHARED_LL(TOD) = T1;

	delta = T1-T0;
	if (delta < 0) {
		SHARED(NR_TOD_WARPS)++;
		if (delta < SHARED_LL(WORST_TOD)) {
			SHARED_LL(WORST_TOD) = delta;
			fprintf(stderr, "\rnew TOD-warp maximum: %9Ld usecs,  %016Lx -> %016Lx\n",
				delta, T0, T1);
		}
	}
	unlock(&SHARED(LOCK));
#endif
}

int main(int argc, char **argv)
{
	int i, parent, me;
	unsigned long *shared;
	unsigned long cpus, tasks;

	cpus = system("exit `grep processor /proc/cpuinfo  | wc -l`");
	cpus = WEXITSTATUS(cpus);

	if (argc > 2) {
usage:
		fprintf(stderr,
			"usage: tsc-sync-test <threads>\n");
		exit(-1);
	}
	if (argc == 2) {
		tasks = atol(argv[1]);
		if (!tasks)
			goto usage;
	} else
		tasks = cpus;

	printf("%ld CPUs, running %ld parallel test-tasks.\n", cpus, tasks);
	printf("checking for time-warps via:\n"
#if TEST_TSC
	"- read time stamp counter (RDTSC) instruction (cycle resolution)\n"
#endif
#if TEST_TOD
	"- gettimeofday (TOD) syscall (usec resolution)\n"
#endif
		"\n"
		);
	shared = setup_shared_var();

	parent = getpid();

	for (i = 1; i < tasks; i++)
		if (!fork())
			break;
	me = getpid();

	while (1) {
		test_TSC(shared);
		test_TOD(shared);

		if (me == parent)
			print_status(shared);
	}

	return 0;
}

  reply	other threads:[~2005-11-22 11:16 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-11-15  9:08 2.6.14-rt13 Ingo Molnar
2005-11-15 16:36 ` 2.6.14-rt13 Mark Knecht
2005-11-15 19:57   ` 2.6.14-rt13 Paul E. McKenney
2005-11-16  3:48 ` 2.6.14-rt13 K.R. Foley
2005-11-16  8:40   ` 2.6.14-rt13 Ingo Molnar
2005-11-16 17:02     ` 2.6.14-rt13 Paul E. McKenney
2005-11-18 18:02 ` 2.6.14-rt13 Fernando Lopez-Lezcano
2005-11-18 21:54   ` 2.6.14-rt13 Lee Revell
2005-11-18 22:05     ` 2.6.14-rt13 Fernando Lopez-Lezcano
2005-11-18 22:07       ` 2.6.14-rt13 Ingo Molnar
2005-11-18 22:15         ` 2.6.14-rt13 Lee Revell
2005-11-18 22:25           ` 2.6.14-rt13 Steven Rostedt
2005-11-18 23:36             ` 2.6.14-rt13 Fernando Lopez-Lezcano
2005-11-18 23:57               ` 2.6.14-rt13 Steven Rostedt
2005-11-18 22:41         ` 2.6.14-rt13 Fernando Lopez-Lezcano
2005-11-19  2:39           ` 2.6.14-rt13 Steven Rostedt
2005-11-24 15:07             ` 2.6.14-rt13 Ingo Molnar
2005-11-24 15:21               ` 2.6.14-rt13 Steven Rostedt
2005-11-25 20:56               ` [RFC][PATCH] Runtime switching to idle_poll (was: Re: 2.6.14-rt13) Steven Rostedt
2005-11-26 13:05                 ` Ingo Molnar
2005-11-29  2:48                   ` [RFC][PATCH] Runtime switching of the idle function [take 2] Steven Rostedt
2005-11-29  3:02                     ` Andrew Morton
2005-11-29  3:42                       ` Steven Rostedt
2005-11-29  4:01                         ` Andrew Morton
2005-11-29  6:44                           ` Ingo Molnar
2005-11-29  6:55                             ` Nick Piggin
2005-11-29 18:05                             ` Andi Kleen
2005-11-29 14:19                               ` Steven Rostedt
2005-11-29 14:50                                 ` Andi Kleen
2005-11-29 15:42                                   ` Steven Rostedt
2005-12-02  1:27                               ` Max Krasnyansky
2005-12-02  1:45                                 ` Andi Kleen
2005-12-03  2:17                                   ` Max Krasnyansky
2005-11-29  4:22                         ` john stultz
2005-11-29 14:22                           ` Steven Rostedt
2005-11-29 13:08                     ` Pavel Machek
2005-12-18 15:26                       ` Steven Rostedt
2005-11-18 22:13       ` 2.6.14-rt13 Lee Revell
2005-11-18 22:32         ` 2.6.14-rt13 Vojtech Pavlik
2005-11-19  2:28           ` 2.6.14-rt13 George Anzinger
2005-11-19  7:45             ` 2.6.14-rt13 Vojtech Pavlik
2005-11-19 18:27               ` 2.6.14-rt13 Lee Revell
2005-11-21 21:32 ` 2.6.14-rt13 Fernando Lopez-Lezcano
2005-11-21 21:41   ` 2.6.14-rt13 john stultz
     [not found]   ` <20051121221511.GA7255@elte.hu>
2005-11-21 22:19     ` test time-warps [was: Re: 2.6.14-rt13] Ingo Molnar
2005-11-21 23:08       ` Fernando Lopez-Lezcano
2005-11-21 23:38       ` Fernando Lopez-Lezcano
2005-11-21 23:41       ` john stultz
2005-11-22  1:31         ` Lee Revell
2005-11-22  1:15       ` Steven Rostedt
2005-11-22 11:16         ` Ingo Molnar [this message]
2005-11-22 17:49           ` Fernando Lopez-Lezcano
2005-11-22 18:01             ` Christopher Friesen
2005-11-22 18:22               ` Steven Rostedt
2005-11-22 20:52                 ` Ingo Molnar
2005-11-22 11:19   ` 2.6.14-rt13 Ingo Molnar

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=20051122111623.GA948@elte.hu \
    --to=mingo@elte.hu \
    --cc=bene@linutronix.de \
    --cc=dwalker@mvista.com \
    --cc=george@mvista.com \
    --cc=john.cooper@timesys.com \
    --cc=kr@cybsft.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nando@ccrma.Stanford.EDU \
    --cc=paulmck@us.ibm.com \
    --cc=pluto@agmk.net \
    --cc=rostedt@goodmis.org \
    --cc=tglx@linutronix.de \
    --cc=trini@kernel.crashing.org \
    /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