--- ../linux.saved/./include/linux/locks.h Mon May 10 09:05:23 1999 +++ ./include/linux/locks.h Thu May 13 00:09:23 1999 @@ -8,6 +8,8 @@ #include #endif +#include + /* * Buffer cache locking - note that interrupts may only unlock, not * lock buffers. @@ -16,8 +18,11 @@ extern inline void wait_on_buffer(struct buffer_head * bh) { - if (test_bit(BH_Lock, &bh->b_state)) + if (test_bit(BH_Lock, &bh->b_state)) { + unsigned t = kgprof_profile_start(); __wait_on_buffer(bh); + kgprof_profile_end(t); + } } extern inline void lock_buffer(struct buffer_head * bh) @@ -41,14 +46,22 @@ extern inline void wait_on_super(struct super_block * sb) { - if (sb->s_lock) + if (sb->s_lock) { + unsigned t = kgprof_profile_start(); __wait_on_super(sb); + kgprof_profile_end(t); + } } -extern inline void lock_super(struct super_block * sb) +#define lock_super(sb) _lock_super(sb, __FUNCTION__) + +extern inline void _lock_super(struct super_block * sb, char *fname) { + extern char *super_locked_by; if (sb->s_lock) __wait_on_super(sb); + super_locked_by = fname; + sb->s_lock = 1; } --- ../linux.saved/./include/linux/pagemap.h Mon May 10 09:05:23 1999 +++ ./include/linux/pagemap.h Thu May 13 00:09:16 1999 @@ -12,6 +12,8 @@ #include #include +#include + static inline unsigned long page_address(struct page * page) { return PAGE_OFFSET + PAGE_SIZE * (page - mem_map); @@ -123,8 +125,11 @@ extern void __wait_on_page(struct page *); static inline void wait_on_page(struct page * page) { - if (PageLocked(page)) + if (PageLocked(page)) { + unsigned t = kgprof_profile_start(); __wait_on_page(page); + kgprof_profile_end(t); + } } extern void update_vm_cache(struct inode *, unsigned long, const char *, int); --- ../linux.saved/./include/linux/kgprof.h Thu May 13 07:57:09 1999 +++ ./include/linux/kgprof.h Tue May 11 18:21:53 1999 @@ -0,0 +1,14 @@ +#define KGPROF_PROFILING 1 + +#if KGPROF_PROFILING + +extern unsigned _kgprof_profile_start(char *fname); +extern void _kgprof_profile_end(char *fname, unsigned t); + +#define kgprof_profile() _kgprof_profile_end(__FUNCTION__, 0) +#define kgprof_profile_start() _kgprof_profile_start(__FUNCTION__) +#define kgprof_profile_end(t) _kgprof_profile_end(__FUNCTION__, t) + +#endif + + --- ../linux.saved/./arch/i386/kernel/setup.c Thu Mar 25 03:35:15 1999 +++ ./arch/i386/kernel/setup.c Wed May 12 16:54:41 1999 @@ -39,6 +39,7 @@ #include #include #include +#include /* * Machine setup.. @@ -859,6 +860,86 @@ printk("\n"); } + +static inline unsigned get_esp(void) +{ + unsigned r; + __asm__("mov %%esp,%0; ":"=r" (r)); + return r; +} + +#define KGPROF_DEPTH 6 +#define KGPROF_SIZE 500 +static struct { + char *name; + char *locked_by; + unsigned addr[KGPROF_DEPTH]; + unsigned count; + unsigned t; +} kgprof_counters[KGPROF_SIZE]; + +char *super_locked_by = NULL; + +/* just call this function from whatever function you think needs it then + look at /proc/cpuinfo to see where the function is being called from + and how often. This gives a type of "kernel gprof" */ +static inline void _kgprof_profile(char *fname, unsigned t) +{ + unsigned ret[KGPROF_DEPTH]; + int i,j; + unsigned long addr, *stack, lastaddr; + extern int _etext; + extern char _stext; + + stack = (unsigned long *)get_esp(); + + for (i=0;i= (unsigned long) &_stext) && + (addr <= (unsigned long) &_etext)) { + ret[i] = addr; + i++; + lastaddr = addr; + } + } + + for (i=0;iloops_per_sec+2500)/500000, ((c->loops_per_sec+2500)/5000) % 100); } + + +#if KGPROF_PROFILING + kgprof_profile(); + + { + int i,j, count=0; + p += sprintf(p,"kgprof profiling:\n"); + for (i=0;i