A device file that exports profiling samples.

上级 e65d0098
...@@ -50,3 +50,4 @@ extern struct devsw devsw[]; ...@@ -50,3 +50,4 @@ extern struct devsw devsw[];
#define CONSOLE 1 #define CONSOLE 1
#define NETIF 2 #define NETIF 2
#define SAMPLER 3
...@@ -21,6 +21,8 @@ main(void) ...@@ -21,6 +21,8 @@ main(void)
if (mknod("netif", 2, 1) < 0) if (mknod("netif", 2, 1) < 0)
printf(2, "init: mknod netif failed\n"); printf(2, "init: mknod netif failed\n");
if (mknod("sampler", 3, 1) < 0)
printf(2, "init: mknod netif failed\n");
for(;;){ for(;;){
printf(1, "init: starting sh\n"); printf(1, "init: starting sh\n");
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "bits.h" #include "bits.h"
#include "amd64.h" #include "amd64.h"
#include "cpu.h" #include "cpu.h"
#include "sampler.h"
static const u64 debug_sel = static const u64 debug_sel =
0UL << 32 | 0UL << 32 |
...@@ -27,14 +28,9 @@ struct pmu { ...@@ -27,14 +28,9 @@ struct pmu {
}; };
struct pmu pmu; struct pmu pmu;
struct pmuevent {
u64 rip;
};
struct pmulog { struct pmulog {
u64 head; u64 count;
u64 tail; u64 capacity;
u64 size;
struct pmuevent *event; struct pmuevent *event;
__padout__; __padout__;
} __mpalign__; } __mpalign__;
...@@ -79,9 +75,9 @@ sampdump(void) ...@@ -79,9 +75,9 @@ sampdump(void)
{ {
for (int c = 0; c < NCPU; c++) { for (int c = 0; c < NCPU; c++) {
struct pmulog *l = &pmulog[c]; struct pmulog *l = &pmulog[c];
cprintf("%u samples %lu\n", c, l->head - l->tail); cprintf("%u samples %lu\n", c, l->count);
for (u64 i = l->tail; i < l->tail+4 && i < l->head; i++) for (u64 i = 0; i < 4 && i < l->count; i++)
cprintf(" %lx\n", l->event[i % l->size].rip); cprintf(" %lx\n", l->event[i].rip);
} }
} }
...@@ -111,11 +107,11 @@ samplog(struct trapframe *tf) ...@@ -111,11 +107,11 @@ samplog(struct trapframe *tf)
struct pmulog *l; struct pmulog *l;
l = &pmulog[cpunum()]; l = &pmulog[cpunum()];
if ((l->head - l->tail) == l->size) if (l->count == l->capacity)
return 0; return 0;
l->event[l->head % l->size].rip = tf->rip; l->event[l->count].rip = tf->rip;
l->head++; l->count++;
return 1; return 1;
} }
...@@ -139,6 +135,75 @@ sampintr(struct trapframe *tf) ...@@ -139,6 +135,75 @@ sampintr(struct trapframe *tf)
return 1; return 1;
} }
static int
readlog(char *dst, u32 off, u32 n)
{
struct pmulog *q = &pmulog[NCPU];
struct pmulog *p;
int ret = 0;
u64 cur = 0;
for (p = &pmulog[0]; p != q && n != 0; p++) {
u64 len = p->count * sizeof(struct pmuevent);
char *buf = (char*)p->event;
if (cur <= off && off < cur+len) {
u64 boff = off-cur;
u64 cc = MIN(len-boff, n);
memmove(dst, buf+boff, cc);
n -= cc;
ret += cc;
off += cc;
dst += cc;
}
cur += len;
}
return ret;
}
static int
sampread(struct inode *ip, char *dst, u32 off, u32 n)
{
struct pmulog *q = &pmulog[NCPU];
struct pmulog *p;
struct logheader *hdr;
u64 hdrlen;
int ret;
int i;
ret = 0;
hdrlen = sizeof(*hdr) + sizeof(hdr->cpu[0])*NCPU;
if (off < hdrlen) {
u64 len = hdrlen;
u64 cc;
hdr = kmalloc(len);
if (hdr == NULL)
return -1;
hdr->ncpus = NCPU;
for (p = &pmulog[0]; p != q; p++) {
u64 sz = p->count * sizeof(struct pmuevent);
hdr->cpu[i].offset = len;
hdr->cpu[i].size = sz;
len += sz;
}
cc = MIN(hdrlen-off, n);
memmove(dst, (void*)hdr + off, cc);
kmfree(hdr);
n -= cc;
ret += cc;
off += cc;
dst += cc;
}
if (off > hdrlen)
ret += readlog(dst, off-hdrlen, n);
return ret;
}
void void
initsamp(void) initsamp(void)
{ {
...@@ -165,5 +230,8 @@ initsamp(void) ...@@ -165,5 +230,8 @@ initsamp(void)
if (p == NULL) if (p == NULL)
panic("initprof: ksalloc"); panic("initprof: ksalloc");
pmulog[cpunum()].event = p; pmulog[cpunum()].event = p;
pmulog[cpunum()].size = PERFSIZE / sizeof(struct pmuevent); pmulog[cpunum()].capacity = PERFSIZE / sizeof(struct pmuevent);
devsw[SAMPLER].write = NULL;
devsw[SAMPLER].read = sampread;
} }
struct pmuevent {
u64 rip;
};
struct logheader {
u32 ncpus;
struct {
u64 offset;
u64 size;
} cpu[];
};
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论