예제 #1
0
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;
}
예제 #2
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;
}
예제 #3
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;
}
예제 #4
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;
}
예제 #5
0
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;
}
예제 #6
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;
}
예제 #7
0
u64 vmm_profiler_get_function_total_time(unsigned long addr)
{
	return pctrl.stat[kallsyms_get_symbol_pos(addr, NULL, NULL)].time;
}
예제 #8
0
u64 vmm_profiler_get_function_count(unsigned long addr)
{
	return pctrl.stat[kallsyms_get_symbol_pos(addr, NULL, NULL)].counter;
}
예제 #9
0
/*
 * 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);
}