Date: Sun, 14 Oct 2001 20:14:00 -0700 From: Luigi Rizzo <rizzo@aciri.org> To: arch@freebsd.org Subject: where to put support for timestamping kernel events ? Message-ID: <20011014201400.A49458@iguana.aciri.org> In-Reply-To: <20011014134502.B47525@iguana.aciri.org> References: <20011014134502.B47525@iguana.aciri.org>
next in thread | previous in thread | raw e-mail | index | archive | help
[Apparently this kind of question is better asked on -arch,
so sorry for the repost, here it goes again... and in the meantime
i have had some time to elaborate on names and locations.]
for some work i am doing these days, i needed to do some relatively
precise (sub-microsecond resolution, and possibly not very intrusive)
measurements of some kernel events.
What i come up with seems to be relatively simple yet flexible:
I record pairs of 32-bit values <timestamp,tag> into an array which
is then exported via sysctl. Timestamps are recorded using the
TSTMP macro below, which in turn calls the (machine-specific)
_TSTMP() function which does the job. On a 750MHz machine the
whole thing takes about 30-40 cycles, which gives pretty good
resolution (I guess it can be further optimized by writing the
whole thing in assembler).
The whole thing is extremely simple -- the full code is below, basically
(modulo disabling it for architectures where the TSC is not present,
or adapting it to other architectures such as the Alpha).
My question(s) are:
* do you think this is a useful feature to be incorporated in the system ?
* if so, where would you put the two pieces of code below ?
I am thinking of sys/param.h for the header files,
and i386/isa/clock.c for the actual function definition
(and other machine-specific implementation as they get
implemented. Initially, i would put the option in options.i386)
* any suggestion about variables and macro/function names etc ?
Feedback is greatly appreciated -- i would really like to see
this stuff in the system.
Diffs below (not mp-ready, the static variable in _TSTMP
should be read and incremented in a critical section, but
you get the idea).
cheers
luigi
-----------------------------------------------------------------
RCS file: /home/xorpc/u2/freebsd/src/sys/conf/options.i386,v
retrieving revision 1.132.2.7
diff -u -r1.132.2.7 options.i386
--- conf/options.i386 2001/08/15 01:23:48 1.132.2.7
+++ conf/options.i386 2001/10/15 02:44:30
@@ -205,5 +205,6 @@
SMBFS
# -------------------------------
+KERN_TIMESTAMP opt_global.h
# EOF
# -------------------------------
===================================================================
RCS file: /home/xorpc/u2/freebsd/src/sys/i386/isa/clock.c,v
retrieving revision 1.149.2.3
diff -u -r1.149.2.3 clock.c
--- i386/isa/clock.c 2001/04/18 23:17:41 1.149.2.3
+++ i386/isa/clock.c 2001/10/15 02:49:37
@@ -199,6 +199,25 @@
SYSCTL_OPAQUE(_debug, OID_AUTO, i8254_timecounter, CTLFLAG_RD,
&i8254_timecounter, sizeof(i8254_timecounter), "S,timecounter", "");
+#ifdef KERN_TIMESTAMP
+#define L_TSC_SIZE 16384
+static u_long tsc[L_TSC_SIZE] ;
+SYSCTL_OPAQUE(_debug, OID_AUTO, timestamp, CTLFLAG_RD, tsc,
+ sizeof(tsc), "LU", "Kernel timestamps");
+void
+_TSTMP(u_int32_t x)
+{
+ static int i ;
+
+ tsc[i] = (u_int32_t)rdtsc();
+ tsc[i+1] = x ;
+ i = i + 2 ;
+ if (i >= L_TSC_SIZE)
+ i = 0 ;
+ tsc[i] = 0 ; /* mark last entry */
+}
+#endif KERN_TIMESTAMP
+
static void
clkintr(struct clockframe frame)
{
===================================================================
RCS file: /home/xorpc/u2/freebsd/src/sys/sys/param.h,v
retrieving revision 1.61.2.18
diff -u -r1.61.2.18 param.h
--- sys/param.h 2001/09/17 06:54:26 1.61.2.18
+++ sys/param.h 2001/10/15 02:41:24
@@ -263,4 +263,17 @@
void panic __P((const char *, ...)) __dead2 __printflike(1, 2);
#endif
+#ifdef _KERNEL /* timestamping support */
+#ifdef KERN_TIMESTAMP
+#define TSTMP(class, unit, event, par) \
+ _TSTMP( (((class) & 15) << 28 ) | \
+ (((unit) & 15) << 24 ) | \
+ (((event) & 255) << 16 ) | \
+ (((par) & 0xffff) ) )
+extern void _TSTMP(u_long);
+#else /* !KERN_TIMESTAMP */
+#define TSTMP(class, unit, event, par) _TSTMP(0)
+#define _TSTMP(x) do {} while (0)
+#endif /* !KERN_TIMESTAMP */
+#endif
#endif /* _SYS_PARAM_H_ */
----------------------------------+-----------------------------------------
Luigi RIZZO, luigi@iet.unipi.it . ACIRI/ICSI (on leave from Univ. di Pisa)
http://www.iet.unipi.it/~luigi/ . 1947 Center St, Berkeley CA 94704
Phone: (510) 666 2927
----------------------------------+-----------------------------------------
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20011014201400.A49458>
