Signed-off-by: Wang Nan <wangn...@huawei.com>
---
 kernel/trace/ftrace.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index a6a6b09..79b3e88 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1539,6 +1539,8 @@ static unsigned long ftrace_location_range(unsigned long 
start, unsigned long en
        return 0;
 }
 
+static unsigned long ftrace_search_mcount_ip(unsigned long ip);
+
 /**
  * ftrace_location - return true if the ip giving is a traced location
  * @ip: the instruction pointer to check
@@ -1550,6 +1552,9 @@ static unsigned long ftrace_location_range(unsigned long 
start, unsigned long en
  */
 unsigned long ftrace_location(unsigned long ip)
 {
+       if (unlikely(!ftrace_pages_start))
+               return ftrace_search_mcount_ip(ip);
+
        return ftrace_location_range(ip, ip);
 }
 
@@ -4733,6 +4738,18 @@ static int ftrace_cmp_ips(const void *a, const void *b)
        return 0;
 }
 
+static int ftrace_cmp_ips_insn(const void *a, const void *b)
+{
+       const unsigned long *ipa = a;
+       const unsigned long *ipb = b;
+
+       if (*ipa >= *ipb + MCOUNT_INSN_SIZE)
+               return 1;
+       if (*ipa < *ipb)
+               return -1;
+       return 0;
+}
+
 static void ftrace_swap_ips(void *a, void *b, int size)
 {
        unsigned long *ipa = a;
@@ -4764,6 +4781,27 @@ static void ftrace_sort_mcount_area(void)
        }
 }
 
+static unsigned long ftrace_search_mcount_ip(unsigned long ip)
+{
+       extern unsigned long __start_mcount_loc[];
+       extern unsigned long __stop_mcount_loc[];
+
+       unsigned long *mcount_start = __start_mcount_loc;
+       unsigned long *mcount_end = __stop_mcount_loc;
+       unsigned long count = mcount_end - mcount_start;
+       unsigned long *retval;
+
+       if (!mcount_sorted)
+               return 0;
+
+       retval = bsearch(&ip, mcount_start, count,
+                       sizeof(unsigned long), ftrace_cmp_ips_insn);
+       if (!retval)
+               return 0;
+
+       return ftrace_call_adjust(ip);
+}
+
 static int ftrace_process_locs(struct module *mod,
                               unsigned long *start,
                               unsigned long *end)
-- 
1.8.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to