]> xenbits.xensource.com Git - xentesttools/bootstrap.git/commitdiff
read_intr: Add tool to show what interrupts are being used right now.
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Tue, 26 Jul 2011 14:47:55 +0000 (10:47 -0400)
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Tue, 26 Jul 2011 14:49:54 +0000 (10:49 -0400)
root_image/Makefile
root_image/tools/Makefile
root_image/tools/read_intr/Makefile [new file with mode: 0644]
root_image/tools/read_intr/read_intr.c [new file with mode: 0644]

index 20d36f98e852c6f47c039f1802f4602436bccd6b..66a918a54b5bf21dc902a01615d3515fd8520de5 100644 (file)
@@ -866,6 +866,7 @@ xtt-tools-install: directfb-install
        $(INSTALL_SCRIPT) tools/load_xen_modules/load_xen_modules       userspace/usr/bin/
        $(INSTALL_PROG)   tools/iostat-2.2/iostat     userspace/usr/bin/
        $(INSTALL_PROG)   tools/debug/test_gnt     userspace/usr/bin/
+       $(INSTALL_PROG)   tools/read_intr/read_intr     userspace/usr/bin/
        $(INSTALL_PROG)   tools/debug/fb_test     userspace/usr/bin/
        $(INSTALL_PROG)   tools/crashme/crashme     userspace/usr/bin/
        $(INSTALL_PROG)   tools/eatmem/eatmem     userspace/usr/bin/
index d4c0173fa6ea9acd66a919ab76df1ac3c80a3b6a..fe9ebbffcdaf0ebabbb329ad9934b1f740680cf9 100644 (file)
@@ -6,6 +6,7 @@ SUBDIRS += eatmem
 SUBDIRS += crashme
 SUBDIRS += drfb_load
 SUBDIRS += drfb_test
+SUBDIRS += read_intr
 
 .PHONY:        all
 all:
diff --git a/root_image/tools/read_intr/Makefile b/root_image/tools/read_intr/Makefile
new file mode 100644 (file)
index 0000000..f1e75a4
--- /dev/null
@@ -0,0 +1,25 @@
+TARGETS-y := read_intr
+TARGETS := $(TARGETS-y)
+
+INSTALL_BIN-y := read_intr
+INSTALL_BIN := $(INSTALL_BIN-y)
+
+
+.PHONY: all
+all: build
+
+.PHONY: build
+build: $(TARGETS)
+
+.PHONY: install
+install: build
+       $(INSTALL_DIR) $(DESTDIR)$(BINDIR)
+       $(INSTALL_DIR) $(DESTDIR)$(SBINDIR)
+
+.PHONY: clean
+clean:
+       $(RM) *.o $(TARGETS) *~ $(DEPS)
+
+%.o: %.c $(HDRS) Makefile
+       $(CC) -c $(CFLAGS) -o $@ $<
+
diff --git a/root_image/tools/read_intr/read_intr.c b/root_image/tools/read_intr/read_intr.c
new file mode 100644 (file)
index 0000000..e698f4a
--- /dev/null
@@ -0,0 +1,262 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+/*
+*/
+char *interrupts = "/proc/interrupts";
+static int DELTA = 30;
+static int MAX_CNT = -1;
+static int MAX_SLEEP = 5;
+#define MAX_CPUS 64
+#define MAX_NAME 64
+#define MAX_LINE 400
+struct irq {
+       int nr;
+       char name[5];
+       int number[MAX_CPUS];
+       int avg[MAX_CPUS];
+       int max[MAX_CPUS];
+       char type[MAX_NAME];
+       char drivers[MAX_NAME];
+       struct irq *next;
+};
+struct snapshot {
+       int     cpu_cnt;
+       int     cnt;
+       struct irq *irq;
+};
+int get_cpu_count()
+{
+       FILE *fp;
+       int cpu_count;
+       char buf[MAX_LINE];
+       char *s;
+       fp = fopen("/proc/cpuinfo","r");
+       if (!fp)
+               return -1;
+
+       cpu_count = 0;
+       // Get CPUs out of the way.
+       while (1) {
+               s = fgets(buf, MAX_LINE, fp);
+               if (!s) {
+                       if (!feof(fp)) {
+                               printf("%s: terminated before eof.\n", __FUNCTION__);
+                       }
+                       break;
+               }
+               if (strlen(buf) < 1)
+                       continue;
+               if (buf[strlen(buf)-1] == '\n')
+                       buf[strlen(buf)-1] = '\0';
+
+               s = strchr(buf, ':');
+               if (!s)
+                       continue;
+               if (strncmp(buf,"processor", strlen("processor")) == 0) {
+                       cpu_count ++;
+               }
+       }
+       fclose(fp);
+       return cpu_count;
+}
+
+static struct snapshot  *
+get_snapshot(int cpu_count)
+{
+       FILE *fp;
+       int i;
+       char buf[MAX_LINE];
+       char *s,*temp;
+       struct snapshot *now;
+       struct irq *irq;
+
+       now = malloc(sizeof(struct snapshot));
+       now->cpu_cnt = cpu_count;
+       now->irq = NULL;
+       fp = fopen(interrupts,"r");
+       if (!fp)
+               return NULL;
+
+       while (1) {
+               s = fgets(buf, MAX_LINE-1, fp);
+               if (!s) {
+                       if (!feof(fp)) {
+                               printf("%s: terminated before eof.\n", __FUNCTION__);
+                       }
+                       break;
+               }
+               if (strlen(buf) < 1)
+                       continue;
+               if (buf[strlen(buf)-1] == '\n')
+                       buf[strlen(buf)-1] = '\0';
+               // Skip the CPU0.. CPU1..
+               s = buf;
+               while (s) {
+                       char *p;
+                       p = strstr(s, "CPU");
+                       if (!p)
+                               break;
+                       if (s-buf > MAX_LINE || s+4-buf >= MAX_LINE) {
+                               printf("%s: Need bigger buffer!\n", __func__);
+                               break;
+                       }
+                       s = strchr(s+3, ' ');
+                       while (*s == ' ')
+                               s++;
+               }
+               if (*s == '\0')
+                       continue;
+               /* List re-order */
+               irq = malloc(sizeof(struct irq));
+               memset(irq, 0, sizeof(struct irq));
+               irq->next = now->irq;
+               now->irq = irq;
+#if VERBOSE
+               printf("[%s]\n", s);
+#endif
+               /* Get IRQ, or the string value */
+               temp = strchr(s,':');
+               strncpy(irq->name, s, 4);
+               irq->nr = 0;
+               irq->nr = atoi(irq->name);
+               s = ++temp;
+               // For CPU count write values
+               for (i = 0; i <  cpu_count; i++) {
+                       while (isblank(*s))
+                               s++;
+#if VERBOSE
+                       if (i == 0)
+                               printf("%d:%d<---", irq->nr, atoi(s));
+#endif
+                       irq->number[i] = atoi(s);
+                       while (isdigit(*s))
+                               s++;
+               }
+               while (isblank(*s))
+                       s++;
+               temp = strchr(s,' ');
+               if (!temp)
+                       temp = s + strlen(s);
+#if VERBOSE
+               printf("![%s]\n", s);
+#endif
+               strncpy(irq->type, s, temp-s > MAX_NAME ? MAX_NAME : temp-s);
+               s = temp;
+               while (isblank(*s))
+                       s++;
+#if VERBOSE
+               printf("[%s]\n",s);
+#endif
+               strncpy(irq->drivers, s, strlen(s) >MAX_NAME ? MAX_NAME : strlen(s));
+               
+       }
+/*            CPU0       CPU1       CPU2       CPU3       
+16:          9          0          0          0  xen-pirq-ioapic-level  uhci_hcd:usb3, nouveau, pata_jmicron
+274:         47          0          0          0   xen-dyn-event     pcifront
+275:          0          0          0          0   xen-dyn-event     vkbd
+276:         54          0          0          0   xen-dyn-event     eth0
+277:        324         21          0          0   xen-dyn-event     hvc_console
+*/
+       fclose(fp);
+
+       return now;
+
+
+}
+void cleanup(struct snapshot *now) {
+
+       struct irq *p,*q;
+
+       p = now->irq;
+       while (p) {
+               q = p->next;
+               free(p);
+               p = q;
+       }
+       free(now);
+}
+
+static const char *blacklist[] = {"timer", "resched","interrupts", "call",NULL}; 
+void get_delta(struct snapshot *b, struct snapshot *n, unsigned long tick)
+{
+       struct irq *p_old,*q_old, *p_new, *q_new;
+       int i, delta;
+       char *p;
+
+       p_old = b->irq;
+       p_new = n->irq;
+       while (p_new && p_old) {
+               q_old = p_old->next;
+               q_new = p_new->next;
+
+               for (i = 0; blacklist[i]; i++) {
+                       if (blacklist[i] == NULL)
+                               break;
+                       if (strncmp(blacklist[i],
+                                   p_old->drivers,
+                                   strlen(blacklist[i])) == 0) {
+                               goto skip;      
+                       }
+               }
+               for (i = 0; i < b->cpu_cnt; i++) {
+                       p_new->avg[i] = p_old->avg[i];
+                       p_new->max[i] = p_old->max[i];
+
+                       delta = 0;
+                       delta = p_new->number[i] - p_old->number[i];
+                       if ((delta == p_old->number[i]) ||
+                               delta == p_new->number[i])
+                               continue;
+
+                       if (delta < 0) {
+                               printf("%s CPU%d going backwards (%d)!\n", p_old->name, i, delta);
+                               continue;
+                       }
+                       p_new->avg[i] = (delta + p_old->avg[i]) / 2;
+                       if (delta > p_new->max[i])
+                               p_new->max[i] = delta;
+                       if (delta > DELTA) {
+                               printf("%-5s %2d: %-5d %-5d %-5d %-20s %ldsec\n",
+                                       p_old->name, i, delta / MAX_SLEEP,
+                                       p_new->avg[i] / MAX_SLEEP, p_new->max[i] / MAX_SLEEP,
+                                       p_old->drivers, tick);
+                       }
+                       
+               }
+skip:
+               p_old = q_old;
+               p_new = q_new;
+       }
+}
+int main(int argc, char *argv[])
+{
+       struct snapshot *before, *now;
+       struct irq *p,*q;
+       int cnt;
+       int cpu_count;
+       unsigned long tick;
+
+       cpu_count = get_cpu_count();
+       if (cpu_count == 0)
+               return;
+
+       cnt = MAX_CNT;
+       printf("-----------------------------------------------------------\n");
+       printf("irq  cpu: delta avg/s max/s driver               time\n");
+       before = get_snapshot(cpu_count);
+       tick = 0;
+       while (cnt--) {
+               sleep(MAX_SLEEP);
+               tick += MAX_SLEEP;
+               now = get_snapshot(cpu_count);
+               get_delta(before ,now, tick);
+               cleanup(before);
+               before = now;
+               if (cnt - 1 == 0 && MAX_CNT == -1)
+                       cnt = MAX_CNT;
+       }
+       cleanup(before);
+
+       return cnt;
+}