ftrace: Add ftrace_add_rec_direct function
authorJiri Olsa <jolsa@redhat.com>
Fri, 8 Oct 2021 09:13:33 +0000 (11:13 +0200)
committerSteven Rostedt (VMware) <rostedt@goodmis.org>
Thu, 21 Oct 2021 18:19:00 +0000 (14:19 -0400)
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: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
kernel/trace/ftrace.c

index 8b58018..ccbd837 100644 (file)
@@ -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)