提交 af216111 创建 作者: Silas Boyd-Wickizer's avatar Silas Boyd-Wickizer

Some code to help instrument kernel for profiling..

上级 56eccf91
...@@ -46,6 +46,7 @@ OBJS = \ ...@@ -46,6 +46,7 @@ OBJS = \
picirq.o \ picirq.o \
pipe.o \ pipe.o \
proc.o \ proc.o \
prof.o \
rcu.o \ rcu.o \
sched.o \ sched.o \
spinlock.o \ spinlock.o \
......
...@@ -308,6 +308,18 @@ consoleintr(int (*getc)(void)) ...@@ -308,6 +308,18 @@ consoleintr(int (*getc)(void))
case C('W'): // Work queue stats case C('W'): // Work queue stats
wq_dump(); wq_dump();
break; break;
case C('L'): // Prof stats
profdump();
break;
case C('K'): // Prof enable
profreset();
cprintf("prof enabled\n");
profenable = 1;
break;
case C('I'): // Prof disable
profenable = 0;
cprintf("prof disabled\n");
break;
default: default:
if(c != 0 && input.e-input.r < INPUT_BUF){ if(c != 0 && input.e-input.r < INPUT_BUF){
c = (c == '\r') ? '\n' : c; c = (c == '\r') ? '\n' : c;
......
...@@ -13,12 +13,15 @@ ...@@ -13,12 +13,15 @@
#include "elf.h" #include "elf.h"
#include "cpu.h" #include "cpu.h"
#include "vm.h" #include "vm.h"
#include "prof.h"
#define USTACKPAGES 2 #define USTACKPAGES 2
#define BRK (USERTOP >> 1) #define BRK (USERTOP >> 1)
static const int odp = 1; static const int odp = 1;
DEFINE_PROFCTR(dosegment_prof);
struct eargs { struct eargs {
struct inode *ip; struct inode *ip;
struct vmap *vmap; struct vmap *vmap;
...@@ -32,6 +35,7 @@ dosegment(uptr a0, u64 a1) ...@@ -32,6 +35,7 @@ dosegment(uptr a0, u64 a1)
struct vmnode *vmn = NULL; struct vmnode *vmn = NULL;
struct proghdr ph; struct proghdr ph;
prof_start(dosegment_prof);
if(readi(args->ip, (char*)&ph, off, sizeof(ph)) != sizeof(ph)) if(readi(args->ip, (char*)&ph, off, sizeof(ph)) != sizeof(ph))
goto bad; goto bad;
if(ph.type != ELF_PROG_LOAD) { if(ph.type != ELF_PROG_LOAD) {
...@@ -63,6 +67,7 @@ dosegment(uptr a0, u64 a1) ...@@ -63,6 +67,7 @@ dosegment(uptr a0, u64 a1)
if(vmap_insert(args->vmap, vmn, ph.vaddr) < 0) if(vmap_insert(args->vmap, vmn, ph.vaddr) < 0)
goto bad; goto bad;
prof_end(dosegment_prof);
return; return;
bad: bad:
......
...@@ -204,6 +204,11 @@ int wait(void); ...@@ -204,6 +204,11 @@ int wait(void);
void yield(void); void yield(void);
void migrate(struct proc *); void migrate(struct proc *);
// prof.c
extern int profenable;
void profreset(void);
void profdump(void);
// rcu.c // rcu.c
void rcuinit(void); void rcuinit(void);
void rcu_begin_write(struct spinlock *); void rcu_begin_write(struct spinlock *);
......
...@@ -13,6 +13,12 @@ SECTIONS ...@@ -13,6 +13,12 @@ SECTIONS
*(.rodata .rodata.* .gnu.linkonce.r.*) *(.rodata .rodata.* .gnu.linkonce.r.*)
} }
. = ALIGN(0x1000); . = ALIGN(0x1000);
PROVIDE(sprof = .);
.prof : {
*(.prof)
}
PROVIDE(eprof = .);
. = ALIGN(0x1000);
.data : { .data : {
*(.data) *(.data)
} }
......
#include "param.h"
#include "types.h"
#include "spinlock.h"
#include "condvar.h"
#include "fs.h"
#include "file.h"
#include "prof.h"
#include "kernel.h"
extern profctr_t sprof[];
extern profctr_t eprof[];
int profenable;
void
profreset(void)
{
profctr_t *p = sprof;
for (; p != eprof; p++) {
memset(p->rec, 0, sizeof(p->rec));
}
}
static void
profsum(struct profctr *ctr, u64 *tot, u64 *cnt)
{
for (int i = 0; i < NCPU; i++) {
*tot += ctr->rec[i].tot;
*cnt += ctr->rec[i].cnt;
}
}
void
profdump(void)
{
profctr_t *p = sprof;
for (; p != eprof; p++) {
u64 tot = 0, cnt = 0;
profsum(p, &tot, &cnt);
if (cnt)
cprintf("%s %lu\n", p->name, tot/cnt);
}
}
struct profrec {
u64 tot;
u64 cnt;
__padout__;
} __mpalign__;
typedef struct profctr {
const char *name;
struct profrec rec[NCPU] __mpalign__;
__padout__;
} profctr_t;
#define DEFINE_PROFCTR(xname) \
profctr_t xname __attribute__((section(".prof"))) = { .name = #xname };
#define prof_start(name) \
u64 __prof##name = profenable ? rdtsc() : 0;
#define prof_end(name) do { \
if (profenable) { \
u64 __eprof##name = rdtsc(); \
u64 __profid = mycpu()->id; \
name.rec[__profid].tot += __eprof##name - __prof##name; \
name.rec[__profid].cnt++; \
} \
} while (0)
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论