aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2011-12-16 16:30:31 -0500
committerSteven Rostedt <rostedt@goodmis.org>2011-12-21 07:19:03 -0500
commit85ae32ae019bc1c2cc22e5f51fe0c9f2812ef68c (patch)
tree38ce2528dd0af0190e61cbf1dcc9f6d0c4ac3cf6 /kernel
parenta79008755497daff157f5294c02e3b940641cc11 (diff)
ftrace: Replace record newlist with record page list
As new functions come in to be initalized from mcount to nop, they are done by groups of pages. Whether it is the core kernel or a module. There's no need to keep track of these on a per record basis. At startup, and as any module is loaded, the functions to be traced are stored in a group of pages and added to the function list at the end. We just need to keep a pointer to the first page of the list that was added, and use that to know where to start on the list for initializing functions. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/ftrace.c68
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
980static struct dyn_ftrace *ftrace_new_addrs;
981
982static DEFINE_MUTEX(ftrace_regex_lock); 980static DEFINE_MUTEX(ftrace_regex_lock);
983 981
984struct ftrace_page { 982struct ftrace_page {
@@ -988,6 +986,8 @@ struct ftrace_page {
988 int size; 986 int size;
989}; 987};
990 988
989static 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
1937static int ftrace_update_code(struct module *mod) 1935static 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