Commit 1904a814 authored by Jiri Olsa's avatar Jiri Olsa Committed by Steven Rostedt (VMware)
Browse files

ftrace: Add ftrace_add_rec_direct function

Factor out the code that adds (ip, addr) tuple to direct_functions
hash in new ftrace_add_rec_direct function. It will be used in
following patches.

Link: https://lkml.kernel.org/r/20211008091336.33616-6-jolsa@kernel.org



Signed-off-by: default avatarJiri Olsa <jolsa@kernel.org>
Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
parent 4e341cad
Loading
Loading
Loading
Loading
+37 −27
Original line number Diff line number Diff line
@@ -2390,6 +2390,39 @@ unsigned long ftrace_find_rec_direct(unsigned long ip)
	return entry->direct;
}

static struct ftrace_func_entry*
ftrace_add_rec_direct(unsigned long ip, unsigned long addr,
		      struct ftrace_hash **free_hash)
{
	struct ftrace_func_entry *entry;

	if (ftrace_hash_empty(direct_functions) ||
	    direct_functions->count > 2 * (1 << direct_functions->size_bits)) {
		struct ftrace_hash *new_hash;
		int size = ftrace_hash_empty(direct_functions) ? 0 :
			direct_functions->count + 1;

		if (size < 32)
			size = 32;

		new_hash = dup_hash(direct_functions, size);
		if (!new_hash)
			return NULL;

		*free_hash = direct_functions;
		direct_functions = new_hash;
	}

	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
	if (!entry)
		return NULL;

	entry->ip = ip;
	entry->direct = addr;
	__add_hash_entry(direct_functions, entry);
	return entry;
}

static void call_direct_funcs(unsigned long ip, unsigned long pip,
			      struct ftrace_ops *ops, struct ftrace_regs *fregs)
{
@@ -5106,39 +5139,16 @@ int register_ftrace_direct(unsigned long ip, unsigned long addr)
	}

	ret = -ENOMEM;
	if (ftrace_hash_empty(direct_functions) ||
	    direct_functions->count > 2 * (1 << direct_functions->size_bits)) {
		struct ftrace_hash *new_hash;
		int size = ftrace_hash_empty(direct_functions) ? 0 :
			direct_functions->count + 1;

		if (size < 32)
			size = 32;

		new_hash = dup_hash(direct_functions, size);
		if (!new_hash)
			goto out_unlock;

		free_hash = direct_functions;
		direct_functions = new_hash;
	}

	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
	if (!entry)
		goto out_unlock;

	direct = ftrace_find_direct_func(addr);
	if (!direct) {
		direct = ftrace_alloc_direct_func(addr);
		if (!direct) {
			kfree(entry);
		if (!direct)
			goto out_unlock;
	}
	}

	entry->ip = ip;
	entry->direct = addr;
	__add_hash_entry(direct_functions, entry);
	entry = ftrace_add_rec_direct(ip, addr, &free_hash);
	if (!entry)
		goto out_unlock;

	ret = ftrace_set_filter_ip(&direct_ops, ip, 0, 0);
	if (ret)