Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 28 Oct 2001 15:17:26 -0800
From:      Luigi Rizzo <rizzo@aciri.org>
To:        murthy kn <knmurthy30@hotmail.com>
Cc:        net@FreeBSD.ORG
Subject:   Re: Polling vs Interrupts (was Re: NEW CODE: polling support...)
Message-ID:  <20011028151726.E90224@iguana.aciri.org>
In-Reply-To: <F49U8cJHiR2CYDksLPe0001d8ac@hotmail.com>
References:  <F49U8cJHiR2CYDksLPe0001d8ac@hotmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, Oct 29, 2001 at 02:17:37AM +0530, murthy kn wrote:
...
> I have a couple of questions.
> 
> 1.   What will happen if a packet some packets arrive DURING the
> current call to XXX_intr() - are they processed by the
> current invocation of XXX_intr() itself without generating a new interrupt 

yes, provided they arrive before the last read of the status register.

> 2. If the answer to the (1) is true,  I am not getting the difference 
> between interrupt mitigation/ coalescing described below and the above 

Because as the traffic level increases, you _will_ be unlucky and
will see a new packet arrive right after you have checked the status
register for the last time.  Basically, in the worst case you might
have 1 intr per packet, which is usually well beyond the interrupt
rate that your system is able to sustain.

With coalescing, you guarantee that the max intr rate is never
larger than 1/timeout (which you get to choose), and this also caps
the overhead (i.e. time wasted in switching context). The time
spent in processing interrupts still grows with the traffic, but
at least you can guarantee that your CPU utilization is above a
certain threshold.

Coalescing does not prevent livelock, but at least moves the point
where you are going to have troubles.

> >As an example, for a simple I/O read from a register on a PCI card,
> >I have often measured times as high as 10,000 clock cycles (for
...
> --------> Any pointers on tools/techniques to perform such measurements for 
> instrumenting the kernel will be very helpful.

see below. You put "TSTMP()" calls in your code, and use sysctl to
fetch the buffer and decode it somehow.

	"Only works for Pentium-class machines, non-SMP."

I have already posted this code a couple of weeks ago, trying to
see if i can commit it, but because of the above limitation, this
ended up in the usual pointless debates on generality and usefulness
(which for 20 lines of conditionally compiled code are absolutely
overkill, in my opinion).

So for the time being I gave up to the commit, I will come back to
this in the future, when i have time to spend in writing a big
disclaimer and a manpage.

	cheers
	luigi


Index: conf/options.i386
===================================================================
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/28 17:28:33
@@ -205,5 +205,8 @@
 SMBFS
 
 # -------------------------------
+KERN_TIMESTAMP		opt_global.h
+
+# -------------------------------
 # EOF
 # -------------------------------
Index: i386/isa/clock.c
===================================================================
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/23 03:08:41
@@ -199,6 +199,28 @@
 SYSCTL_OPAQUE(_debug, OID_AUTO, i8254_timecounter, CTLFLAG_RD, 
 	&i8254_timecounter, sizeof(i8254_timecounter), "S,timecounter", "");
 
+#ifdef KERN_TIMESTAMP
+#define L_TSC_SIZE (1<<16)
+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 ;
+
+    __asm __volatile("pushfl ; cli" : : : "memory");
+
+	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 */
+    __asm __volatile("popfl" : : : "memory");
+}
+#endif KERN_TIMESTAMP
+
 static void
 clkintr(struct clockframe frame)
 {
Index: sys/param.h
===================================================================
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/23 04:35:44
@@ -263,4 +263,20 @@
 void	panic __P((const char *, ...)) __dead2 __printflike(1, 2);
 #endif
 
+#ifdef _KERNEL	/* debugging macros accessing the TSC */
+
+#define NOTSTMP(a,b,c,d)
+#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_int32_t);
+#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_ */

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20011028151726.E90224>