static void __notrace vmm_profile_enter(void *ip, void *parent_ip) { int index; irq_flags_t flags; if (pctrl.is_in_trace) return; pctrl.is_in_trace = 1; index = kallsyms_get_symbol_pos((long unsigned int)ip, NULL, NULL); if (pctrl.stat[index].is_tracing == 1) { goto out; } if (pctrl.stat[index].time_in != 0) { goto out; } flags = vmm_spin_lock_irqsave(&pctrl.lock); pctrl.stat[index].counter++; pctrl.stat[index].is_tracing = 1; pctrl.stat[index].time_in = vmm_timer_timestamp_for_profile(); vmm_spin_unlock_irqrestore(&pctrl.lock, flags); out: pctrl.is_in_trace = 0; }
__notrace int kallsyms_lookup_symbol_name(unsigned long addr, char *symname) { unsigned long pos; symname[0] = '\0'; symname[KSYM_NAME_LEN - 1] = '\0'; pos = kallsyms_get_symbol_pos(addr, NULL, NULL); /* Grab name */ kallsyms_expand_symbol(kallsyms_get_symbol_offset(pos), symname); return 0; }
__notrace int kallsyms_lookup_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *name) { unsigned long pos; name[0] = '\0'; name[KSYM_NAME_LEN - 1] = '\0'; pos = kallsyms_get_symbol_pos(addr, size, offset); /* Grab name */ kallsyms_expand_symbol(kallsyms_get_symbol_offset(pos), name); return 0; }
const __notrace char *kallsyms_lookup(unsigned long addr, unsigned long *symbolsize, unsigned long *offset, char *namebuf) { unsigned long pos; namebuf[KSYM_NAME_LEN - 1] = 0; namebuf[0] = 0; pos = kallsyms_get_symbol_pos(addr, symbolsize, offset); /* Grab name */ kallsyms_expand_symbol(kallsyms_get_symbol_offset(pos), namebuf); return namebuf; }
static void __notrace vmm_profile_exit(void *ip, void *parent_ip) { int index; u64 time; irq_flags_t flags; if (pctrl.is_in_trace) { return; } pctrl.is_in_trace = 1; index = kallsyms_get_symbol_pos((long unsigned int)ip, NULL, NULL); // If this function was no traced yet ... // we just return as we can't get the start timer if (pctrl.stat[index].is_tracing != 1) { goto out; } if (pctrl.stat[index].time_in == 0) { goto out; } flags = vmm_spin_lock_irqsave(&pctrl.lock); time = vmm_timer_timestamp_for_profile(); if (pctrl.stat[index].time_in < time) { pctrl.stat[index].time += time - pctrl.stat[index].time_in; } else { //vmm_printf("negative time\n"); } vmm_spin_unlock_irqrestore(&pctrl.lock, flags); out: pctrl.stat[index].time_in = 0; // OK we don't trace this function anymore pctrl.stat[index].is_tracing = 0; pctrl.is_in_trace = 0; }
static int cmd_profile_count_iterator(void *data, const char *name, unsigned long addr) { struct count_record *ptr = data; u32 index = kallsyms_get_symbol_pos(addr, NULL, NULL); u32 count = vmm_profiler_get_function_count(addr); u64 time = vmm_profiler_get_function_total_time(addr); ptr += index; /* It would be nice to have the strncpy variant */ strcpy(ptr->function_name, name); ptr->function_name[39] = 0; ptr->count = count; ptr->total_time = time; if (count) { ptr->time_per_call = udiv64(time, (u64)count); } return VMM_OK; }
u64 vmm_profiler_get_function_total_time(unsigned long addr) { return pctrl.stat[kallsyms_get_symbol_pos(addr, NULL, NULL)].time; }
u64 vmm_profiler_get_function_count(unsigned long addr) { return pctrl.stat[kallsyms_get_symbol_pos(addr, NULL, NULL)].counter; }
/* * Lookup an address but don't bother to find any names. */ __notrace int kallsyms_lookup_size_offset(unsigned long addr, unsigned long *symbolsize, unsigned long *offset) { return ! !kallsyms_get_symbol_pos(addr, symbolsize, offset); }