void sampling_init() { int i ; if (ksym_total() > MAX_KSYM) { dbg_printf(DL_KDB, "ksym %d > MAX_KSYM\n", ksym_total()); return; } for (i = 0; i < MAX_SAMPLING_COUNT; i++) { sampled_pc[i] = 0; } sampled_count = 0; }
void kdb_show_sampling(void) { int i; int symid; int *hitcount, *symid_list; static int init = 0; static struct kprobe k; if (init == 0) { dbg_printf(DL_KDB, "Init sampling...\n"); sampling_init(); sampling_enable(); init++; k.addr = ktimer_handler; k.pre_handler = sampling_handler; k.post_handler = NULL; kprobe_register(&k); return; } sampling_disable(); sampling_stats(&hitcount, &symid_list); for (i = 0; i < ksym_total(); i++) { symid = symid_list[i]; if (hitcount[symid] == 0) break; dbg_printf(DL_KDB, "%5d [ %24s ]\n", hitcount[symid], ksym_id2name(symid)); } sampling_enable(); }
void sampling_stats(int **hitcountp, int **symid_list) { int i, symid; /* init data */ sort(sampled_pc, MAX_SAMPLING_COUNT, sizeof(sampled_pc[0]), cmp_addr); for (i = 0; i < MAX_KSYM; i++) { ksym_hitcount[i] = 0; ksymid_sortedlist[i] = i; } /* calculation total hit for each ksym */ for (i = 0; i < MAX_SAMPLING_COUNT; i++) { symid = ksym_lookup(sampled_pc[i]); if (symid < 0) continue; ksym_hitcount[symid]++; } /* create a list from highest hit to lowest hit */ sort(ksymid_sortedlist, ksym_total(), sizeof(ksymid_sortedlist[0]), cmp_symhit); /* output the result */ *hitcountp = ksym_hitcount; *symid_list = ksymid_sortedlist; }
static int cmp_key(const void *addr, const void *p1) { ksym_t * sym = (ksym_t *)p1; if (sym == (__ksym_tbl+ksym_total()-1)) { return 0; } else if ((addr >= sym->addr) && (addr < (sym+1)->addr)) { return 0; } else { return addr - ((ksym_t *) sym)->addr; } }