overlay: Parse /proc/interrupts in lieu of debugfs/i915_gem_interrupt

So the interrupt counter was removed from i915_gem_interrupt, and if we
do not have the perf API available, we therefore need to read it from
/proc/interrupts instead.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2014-04-30 18:39:27 +01:00
parent bff7ecde7b
commit c864279de6

View File

@ -29,6 +29,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "gem-interrupts.h"
#include "debugfs.h"
@ -48,16 +49,77 @@ static int perf_open(void)
return perf_event_open(&attr, -1, 0, -1, 0);
}
static int debugfs_open(void)
static long long debugfs_read(void)
{
char buf[1024];
struct stat st;
char buf[8192], *b;
int fd, len;
sprintf(buf, "%s/i915_gem_interrupt", debugfs_dri_path);
if (stat(buf, &st))
return errno;
fd = open(buf, 0);
if (fd < 0)
return -1;
return 0;
len = read(fd, buf, sizeof(buf)-1);
close(fd);
if (len < 0)
return -1;
buf[len] = '\0';
b = strstr(buf, "Interrupts received:");
if (b == NULL)
return -1;
return strtoull(b + sizeof("Interrupts received:"), 0, 0);
}
static long long procfs_read(void)
{
char buf[8192], *b;
int fd, len;
unsigned long long val;
/* 44: 51 42446 0 0 PCI-MSI-edge i915*/
fd = open("/proc/interrupts", 0);
if (fd < 0)
return -1;
len = read(fd, buf, sizeof(buf)-1);
close(fd);
if (len < 0)
return -1;
buf[len] = '\0';
b = strstr(buf, "i915");
if (b == NULL)
return -1;
while (*--b != ':')
;
val = 0;
do {
while (isspace(*++b))
;
if (!isdigit(*b))
break;
val += strtoull(b, &b, 0);
} while(1);
return val;
}
static long long interrupts_read(void)
{
long long val;
val = debugfs_read();
if (val < 0)
val = procfs_read();
return val;
}
int gem_interrupts_init(struct gem_interrupts *irqs)
@ -65,8 +127,8 @@ int gem_interrupts_init(struct gem_interrupts *irqs)
memset(irqs, 0, sizeof(*irqs));
irqs->fd = perf_open();
if (irqs->fd < 0)
irqs->error = debugfs_open();
if (irqs->fd < 0 && interrupts_read() < 0)
irqs->error = ENODEV;
return irqs->error;
}
@ -80,26 +142,9 @@ int gem_interrupts_update(struct gem_interrupts *irqs)
return irqs->error;
if (irqs->fd < 0) {
char buf[8192], *b;
int fd, len;
sprintf(buf, "%s/i915_gem_interrupt", debugfs_dri_path);
fd = open(buf, 0);
if (fd < 0)
return irqs->error = errno;
len = read(fd, buf, sizeof(buf)-1);
close(fd);
if (len < 0)
return irqs->error = errno;
buf[len] = '\0';
b = strstr(buf, "Interrupts received:");
if (b == NULL)
return irqs->error = ENOENT;
val = strtoull(b + sizeof("Interrupts received:"), 0, 0);
val = interrupts_read();
if (val < 0)
return irqs->error = ENODEV;
} else {
if (read(irqs->fd, &val, sizeof(val)) < 0)
return irqs->error = errno;