__cyg_profile_func_enter() adds timer information to function traces.
Commit 852d4dbd70ba ("trace: Detect an infinite loop") introduced a logic
letting any recursive call to __cyg_profile_func_enter() deactivate
tracing.
This implies that a lot of the DM core and timer drivers functions need to
be marked as `notrace`. This in not desirable as those functions are part
of what we want to trace when not invoked by __cyg_profile_func_enter().
A better approach than switching of tracing is to immediately leave
__cyg_profile_func_enter() when reentered.
Reported-by: Patrick Rudolph <[email protected]>
Signed-off-by: Heinrich Schuchardt <[email protected]>
---
lib/trace.c | 59 ++++++++++++++++++++++++-----------------------------
1 file changed, 27 insertions(+), 32 deletions(-)
diff --git a/lib/trace.c b/lib/trace.c
index 3d54dfaddc0..2dea8fc85f2 100644
--- a/lib/trace.c
+++ b/lib/trace.c
@@ -131,32 +131,26 @@ static void notrace add_ftrace(void *func_ptr, void
*caller, ulong flags)
*/
void notrace __cyg_profile_func_enter(void *func_ptr, void *caller)
{
- if (trace_enabled) {
- int func;
-
- if (hdr->trace_locked) {
- trace_enabled = 0;
- puts("trace: recursion detected, disabling\n");
- hdr->trace_locked = false;
- return;
- }
+ int func;
- hdr->trace_locked = true;
- trace_swap_gd();
- add_ftrace(func_ptr, caller, FUNCF_ENTRY);
- func = func_ptr_to_num(func_ptr);
- if (func < hdr->func_count) {
- hdr->call_accum[func]++;
- hdr->call_count++;
- } else {
- hdr->untracked_count++;
- }
- hdr->depth++;
- if (hdr->depth > hdr->max_depth)
- hdr->max_depth = hdr->depth;
- trace_swap_gd();
- hdr->trace_locked = false;
+ if (!trace_enabled || hdr->trace_locked)
+ return;
+
+ hdr->trace_locked = true;
+ trace_swap_gd();
+ add_ftrace(func_ptr, caller, FUNCF_ENTRY);
+ func = func_ptr_to_num(func_ptr);
+ if (func < hdr->func_count) {
+ hdr->call_accum[func]++;
+ hdr->call_count++;
+ } else {
+ hdr->untracked_count++;
}
+ hdr->depth++;
+ if (hdr->depth > hdr->max_depth)
+ hdr->max_depth = hdr->depth;
+ trace_swap_gd();
+ hdr->trace_locked = false;
}
/**
@@ -167,14 +161,15 @@ void notrace __cyg_profile_func_enter(void *func_ptr,
void *caller)
*/
void notrace __cyg_profile_func_exit(void *func_ptr, void *caller)
{
- if (trace_enabled) {
- trace_swap_gd();
- hdr->depth--;
- add_ftrace(func_ptr, caller, FUNCF_EXIT);
- if (hdr->depth < hdr->min_depth)
- hdr->min_depth = hdr->depth;
- trace_swap_gd();
- }
+ if (!trace_enabled || hdr->trace_locked)
+ return;
+
+ trace_swap_gd();
+ hdr->depth--;
+ add_ftrace(func_ptr, caller, FUNCF_EXIT);
+ if (hdr->depth < hdr->min_depth)
+ hdr->min_depth = hdr->depth;
+ trace_swap_gd();
}
/**
--
2.51.0