diff options
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r-- | kernel/trace/ftrace.c | 68 |
1 files changed, 37 insertions, 31 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 2e7218869fe9..366d7881f188 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -977,8 +977,6 @@ static struct ftrace_ops global_ops = { | |||
977 | .filter_hash = EMPTY_HASH, | 977 | .filter_hash = EMPTY_HASH, |
978 | }; | 978 | }; |
979 | 979 | ||
980 | static struct dyn_ftrace *ftrace_new_addrs; | ||
981 | |||
982 | static DEFINE_MUTEX(ftrace_regex_lock); | 980 | static DEFINE_MUTEX(ftrace_regex_lock); |
983 | 981 | ||
984 | struct ftrace_page { | 982 | struct ftrace_page { |
@@ -988,6 +986,8 @@ struct ftrace_page { | |||
988 | int size; | 986 | int size; |
989 | }; | 987 | }; |
990 | 988 | ||
989 | static struct ftrace_page *ftrace_new_pgs; | ||
990 | |||
991 | #define ENTRY_SIZE sizeof(struct dyn_ftrace) | 991 | #define ENTRY_SIZE sizeof(struct dyn_ftrace) |
992 | #define ENTRIES_PER_PAGE (PAGE_SIZE / ENTRY_SIZE) | 992 | #define ENTRIES_PER_PAGE (PAGE_SIZE / ENTRY_SIZE) |
993 | 993 | ||
@@ -1445,8 +1445,6 @@ ftrace_record_ip(unsigned long ip) | |||
1445 | return NULL; | 1445 | return NULL; |
1446 | 1446 | ||
1447 | rec->ip = ip; | 1447 | rec->ip = ip; |
1448 | rec->newlist = ftrace_new_addrs; | ||
1449 | ftrace_new_addrs = rec; | ||
1450 | 1448 | ||
1451 | return rec; | 1449 | return rec; |
1452 | } | 1450 | } |
@@ -1936,9 +1934,11 @@ static int ops_traces_mod(struct ftrace_ops *ops) | |||
1936 | 1934 | ||
1937 | static int ftrace_update_code(struct module *mod) | 1935 | static int ftrace_update_code(struct module *mod) |
1938 | { | 1936 | { |
1937 | struct ftrace_page *pg; | ||
1939 | struct dyn_ftrace *p; | 1938 | struct dyn_ftrace *p; |
1940 | cycle_t start, stop; | 1939 | cycle_t start, stop; |
1941 | unsigned long ref = 0; | 1940 | unsigned long ref = 0; |
1941 | int i; | ||
1942 | 1942 | ||
1943 | /* | 1943 | /* |
1944 | * When adding a module, we need to check if tracers are | 1944 | * When adding a module, we need to check if tracers are |
@@ -1960,41 +1960,44 @@ static int ftrace_update_code(struct module *mod) | |||
1960 | start = ftrace_now(raw_smp_processor_id()); | 1960 | start = ftrace_now(raw_smp_processor_id()); |
1961 | ftrace_update_cnt = 0; | 1961 | ftrace_update_cnt = 0; |
1962 | 1962 | ||
1963 | while (ftrace_new_addrs) { | 1963 | for (pg = ftrace_new_pgs; pg; pg = pg->next) { |
1964 | 1964 | ||
1965 | /* If something went wrong, bail without enabling anything */ | 1965 | for (i = 0; i < pg->index; i++) { |
1966 | if (unlikely(ftrace_disabled)) | 1966 | /* If something went wrong, bail without enabling anything */ |
1967 | return -1; | 1967 | if (unlikely(ftrace_disabled)) |
1968 | return -1; | ||
1968 | 1969 | ||
1969 | p = ftrace_new_addrs; | 1970 | p = &pg->records[i]; |
1970 | ftrace_new_addrs = p->newlist; | 1971 | p->flags = ref; |
1971 | p->flags = ref; | ||
1972 | 1972 | ||
1973 | /* | 1973 | /* |
1974 | * Do the initial record conversion from mcount jump | 1974 | * Do the initial record conversion from mcount jump |
1975 | * to the NOP instructions. | 1975 | * to the NOP instructions. |
1976 | */ | 1976 | */ |
1977 | if (!ftrace_code_disable(mod, p)) | 1977 | if (!ftrace_code_disable(mod, p)) |
1978 | break; | 1978 | break; |
1979 | 1979 | ||
1980 | ftrace_update_cnt++; | 1980 | ftrace_update_cnt++; |
1981 | 1981 | ||
1982 | /* | 1982 | /* |
1983 | * If the tracing is enabled, go ahead and enable the record. | 1983 | * If the tracing is enabled, go ahead and enable the record. |
1984 | * | 1984 | * |
1985 | * The reason not to enable the record immediatelly is the | 1985 | * The reason not to enable the record immediatelly is the |
1986 | * inherent check of ftrace_make_nop/ftrace_make_call for | 1986 | * inherent check of ftrace_make_nop/ftrace_make_call for |
1987 | * correct previous instructions. Making first the NOP | 1987 | * correct previous instructions. Making first the NOP |
1988 | * conversion puts the module to the correct state, thus | 1988 | * conversion puts the module to the correct state, thus |
1989 | * passing the ftrace_make_call check. | 1989 | * passing the ftrace_make_call check. |
1990 | */ | 1990 | */ |
1991 | if (ftrace_start_up && ref) { | 1991 | if (ftrace_start_up && ref) { |
1992 | int failed = __ftrace_replace_code(p, 1); | 1992 | int failed = __ftrace_replace_code(p, 1); |
1993 | if (failed) | 1993 | if (failed) |
1994 | ftrace_bug(failed, p->ip); | 1994 | ftrace_bug(failed, p->ip); |
1995 | } | ||
1995 | } | 1996 | } |
1996 | } | 1997 | } |
1997 | 1998 | ||
1999 | ftrace_new_pgs = NULL; | ||
2000 | |||
1998 | stop = ftrace_now(raw_smp_processor_id()); | 2001 | stop = ftrace_now(raw_smp_processor_id()); |
1999 | ftrace_update_time = stop - start; | 2002 | ftrace_update_time = stop - start; |
2000 | ftrace_update_tot_cnt += ftrace_update_cnt; | 2003 | ftrace_update_tot_cnt += ftrace_update_cnt; |
@@ -3632,6 +3635,9 @@ static int ftrace_process_locs(struct module *mod, | |||
3632 | break; | 3635 | break; |
3633 | } | 3636 | } |
3634 | 3637 | ||
3638 | /* These new locations need to be initialized */ | ||
3639 | ftrace_new_pgs = pg; | ||
3640 | |||
3635 | /* | 3641 | /* |
3636 | * We only need to disable interrupts on start up | 3642 | * We only need to disable interrupts on start up |
3637 | * because we are modifying code that an interrupt | 3643 | * because we are modifying code that an interrupt |