linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Interrupt Latency test for intel machine
@ 2007-10-26 14:13 Jaswinder Singh
  0 siblings, 0 replies; only message in thread
From: Jaswinder Singh @ 2007-10-26 14:13 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 581 bytes --]

Hello all,

On my Intel Pentium 4 CPU 2.40 GHz machine by using attached file, I
am getting Interrupt latency as follows :-

Configuration               MAX (us)        MIN (us)        AVG (us)
     Samples
-------------                      --------             --------
      --------            -------------
PREEMPT-NONE            43.576          4.190           4.190           119343

Voluntary PREEMPT       44.414          4.190           4.190           108694

PREEMPT low-latency     39.398          4.190           5.028           112717

Thank you,

Jaswinder Singh.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: irq_latency.c --]
[-- Type: text/x-csrc; name=irq_latency.c, Size: 2899 bytes --]

/*
 * Interrupt latency test module
 *
 * (C) 2007 Jaswinder Singh <jaswinderlinux@gmail.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public Licence Version
 * 2 as published by the Free Software Foundation.
 *
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/bcd.h>
#include <asm/time.h>

//#define DBG_IRQ_LAT		/* debug interrupt latency test */

/* getting global time from 8254 */
#define READ_CNT0(var) do {var = inb(0x40); var |= (inb(0x40) << 8);} while (0)

#ifdef DBG_IRQ_LAT
#define TEST_CNT	1000
static long lat_val[TEST_CNT + 1];
static long lat_val_num;
#endif

static volatile long count_c0;

static long lat_max = 0;
static long lat_min = 100000000;
static unsigned long irq_cnt = 0;
static unsigned long lat_avg = 0;

static void irq_lat_hdr(void)
{
	READ_CNT0(count_c0);
	count_c0 = (LATCH - count_c0);
	if (count_c0 > lat_max)
		lat_max = count_c0;
	if (count_c0 < lat_min)
		lat_min = count_c0;
	lat_avg = lat_avg + count_c0;
	irq_cnt++;

#ifdef DBG_IRQ_LAT
	if (irq_cnt <= TEST_CNT)
	{
		lat_val[irq_cnt] = count_c0;
	}
#endif
}

static int __init irq_lat_init(void)
{
	printk("*************************************\n");
	printk("*  Interrupt Latency module loaded  *\n");
	printk("* When you remove this module you   *\n");
	printk("* will get interrupt latency result *\n");
	printk("*************************************\n");

	irq_lat_ptr = irq_lat_hdr;	/* Install interrupt handler */

	return 0;
}

static void __exit irq_lat_exit(void)
{
	unsigned long nanosecs = 1000000000;

	irq_lat_ptr = NULL;		/* Uninstall interrupt handler */

	nanosecs = (nanosecs/CLOCK_TICK_RATE);
	
	printk("Interrupt Latency result\n");
	printk("------------------------\n");

	if (lat_avg)
		lat_avg = lat_avg/irq_cnt;
	else
	{
		printk("Interrupt Latency test Failed\n");
		printk("send info to <jaswinderlinux@gmail.com>\n");
		return;
	}

#ifdef DBG_IRQ_LAT
	if (irq_cnt < TEST_CNT)
		lat_val_num = irq_cnt;
	else
		lat_val_num = TEST_CNT;
	for (count_c0 = 1; count_c0 <= lat_val_num; count_c0++)
	{
		printk("%4lu: %6lu  ", count_c0, lat_val[count_c0]);
		if ((count_c0 % 5) == 0)
			printk("\n");
	}

	printk("\nCLOCK_TICK_RATE: %d TICK: %lu LATCH: %d\n", CLOCK_TICK_RATE, nanosecs, LATCH);
	printk("MAX latency : %lu ticks\n", lat_max);
	printk("MIN latency : %lu ticks\n", lat_min);
	printk("AVG latency : %lu ticks\n", lat_avg);
#endif
	printk("MAX latency : %5lu.%03lu micro-seconds\n", (nanosecs * lat_max)/1000, (nanosecs * lat_max) % 1000);
	printk("MIN latency : %5lu.%03lu micro-seconds\n", (nanosecs * lat_min)/1000, (nanosecs * lat_min) % 1000);
	printk("AVG latency : %5lu.%03lu micro-seconds\n", (nanosecs * lat_avg)/1000, (nanosecs * lat_avg) % 1000);
	printk("Total Samples : %lu\n", irq_cnt);
}

module_init(irq_lat_init);
module_exit(irq_lat_exit);

MODULE_LICENSE("GPL");

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: irq_lat.patch --]
[-- Type: text/x-patch; name=irq_lat.patch, Size: 1161 bytes --]

diff -Naur linux-2.3.23-org/arch/i386/kernel/time.c linux-2.3.23/arch/i386/kernel/time.c
--- linux-2.3.23-org/arch/i386/kernel/time.c	2007-10-26 19:16:38.000000000 +0530
+++ linux-2.3.23/arch/i386/kernel/time.c	2007-10-26 19:17:49.000000000 +0530
@@ -150,6 +150,10 @@
 }
 EXPORT_SYMBOL(profile_pc);
 
+/* Interrupt latency pointer */
+irqlatptr irq_lat_ptr = NULL;
+EXPORT_SYMBOL(irq_lat_ptr);
+
 /*
  * This is the same as the above, except we _also_ save the current
  * Time Stamp Counter value at the time of the timer interrupt, so that
@@ -173,6 +177,10 @@
 	}
 #endif
 
+	/* Interrupt latency pointer */
+	if (irq_lat_ptr)
+		irq_lat_ptr();
+
 	do_timer_interrupt_hook();
 
 	if (MCA_bus) {
diff -Naur linux-2.3.23-org/include/asm-i386/time.h linux-2.3.23/include/asm-i386/time.h
--- linux-2.3.23-org/include/asm-i386/time.h	2007-10-26 19:16:38.000000000 +0530
+++ linux-2.3.23/include/asm-i386/time.h	2007-10-26 19:18:10.000000000 +0530
@@ -28,6 +28,10 @@
 	return retval;
 }
 
+/* interrupt latency pointer */
+typedef void (*irqlatptr)(void);
+extern irqlatptr irq_lat_ptr;
+
 extern void (*late_time_init)(void);
 extern void hpet_time_init(void);
 

[-- Attachment #4: Makefile --]
[-- Type: application/octet-stream, Size: 235 bytes --]

obj-name := irq_latency
obj-m := $(obj-name).o

KDIR := $(HOME)/linux-$(shell uname -r)

PWD := $(shell pwd)

default:
	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules

clean:
	rm -rf *.ko *.o *.mod.c .*.cmd Mod* .$(obj-name)* .tmp_versions

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2007-10-26 14:14 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-10-26 14:13 Interrupt Latency test for intel machine Jaswinder Singh

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).