ftrace: Replace record newlist with record page list
[linux-2.6-block.git] / kernel / trace / ftrace.c
index 2e7218869fe981776ea8fc186f2e78448434c252..366d7881f188078ffb9b4ccb12ad34cbc1f9d381 100644 (file)
@@ -977,8 +977,6 @@ static struct ftrace_ops global_ops = {
        .filter_hash            = EMPTY_HASH,
 };
 
-static struct dyn_ftrace *ftrace_new_addrs;
-
 static DEFINE_MUTEX(ftrace_regex_lock);
 
 struct ftrace_page {
@@ -988,6 +986,8 @@ struct ftrace_page {
        int                     size;
 };
 
+static struct ftrace_page *ftrace_new_pgs;
+
 #define ENTRY_SIZE sizeof(struct dyn_ftrace)
 #define ENTRIES_PER_PAGE (PAGE_SIZE / ENTRY_SIZE)
 
@@ -1445,8 +1445,6 @@ ftrace_record_ip(unsigned long ip)
                return NULL;
 
        rec->ip = ip;
-       rec->newlist = ftrace_new_addrs;
-       ftrace_new_addrs = rec;
 
        return rec;
 }
@@ -1936,9 +1934,11 @@ static int ops_traces_mod(struct ftrace_ops *ops)
 
 static int ftrace_update_code(struct module *mod)
 {
+       struct ftrace_page *pg;
        struct dyn_ftrace *p;
        cycle_t start, stop;
        unsigned long ref = 0;
+       int i;
 
        /*
         * When adding a module, we need to check if tracers are
@@ -1960,41 +1960,44 @@ static int ftrace_update_code(struct module *mod)
        start = ftrace_now(raw_smp_processor_id());
        ftrace_update_cnt = 0;
 
-       while (ftrace_new_addrs) {
+       for (pg = ftrace_new_pgs; pg; pg = pg->next) {
 
-               /* If something went wrong, bail without enabling anything */
-               if (unlikely(ftrace_disabled))
-                       return -1;
+               for (i = 0; i < pg->index; i++) {
+                       /* If something went wrong, bail without enabling anything */
+                       if (unlikely(ftrace_disabled))
+                               return -1;
 
-               p = ftrace_new_addrs;
-               ftrace_new_addrs = p->newlist;
-               p->flags = ref;
+                       p = &pg->records[i];
+                       p->flags = ref;
 
-               /*
-                * Do the initial record conversion from mcount jump
-                * to the NOP instructions.
-                */
-               if (!ftrace_code_disable(mod, p))
-                       break;
+                       /*
+                        * Do the initial record conversion from mcount jump
+                        * to the NOP instructions.
+                        */
+                       if (!ftrace_code_disable(mod, p))
+                               break;
 
-               ftrace_update_cnt++;
+                       ftrace_update_cnt++;
 
-               /*
-                * If the tracing is enabled, go ahead and enable the record.
-                *
-                * The reason not to enable the record immediatelly is the
-                * inherent check of ftrace_make_nop/ftrace_make_call for
-                * correct previous instructions.  Making first the NOP
-                * conversion puts the module to the correct state, thus
-                * passing the ftrace_make_call check.
-                */
-               if (ftrace_start_up && ref) {
-                       int failed = __ftrace_replace_code(p, 1);
-                       if (failed)
-                               ftrace_bug(failed, p->ip);
+                       /*
+                        * If the tracing is enabled, go ahead and enable the record.
+                        *
+                        * The reason not to enable the record immediatelly is the
+                        * inherent check of ftrace_make_nop/ftrace_make_call for
+                        * correct previous instructions.  Making first the NOP
+                        * conversion puts the module to the correct state, thus
+                        * passing the ftrace_make_call check.
+                        */
+                       if (ftrace_start_up && ref) {
+                               int failed = __ftrace_replace_code(p, 1);
+                               if (failed)
+                                       ftrace_bug(failed, p->ip);
+                       }
                }
        }
 
+       ftrace_new_pgs = NULL;
+
        stop = ftrace_now(raw_smp_processor_id());
        ftrace_update_time = stop - start;
        ftrace_update_tot_cnt += ftrace_update_cnt;
@@ -3632,6 +3635,9 @@ static int ftrace_process_locs(struct module *mod,
                        break;
        }
 
+       /* These new locations need to be initialized */
+       ftrace_new_pgs = pg;
+
        /*
         * We only need to disable interrupts on start up
         * because we are modifying code that an interrupt