Now we have two similar infrastructure to iterate ftrace_page and
dyn_ftrace:

  * do_for_each_ftrace_rec()
  * for_ftrace_rec_iter()

The 2nd one, for_ftrace_rec_iter(), looks more generic, so preserve it
and replace do_for_each_ftrace_rec() with it.

Signed-off-by: Wei Yang <[email protected]>
---
 kernel/trace/ftrace.c | 94 ++++++++++++++++++++-----------------------
 1 file changed, 44 insertions(+), 50 deletions(-)

diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 15fcfa16895d..4def668f45ba 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1501,21 +1501,6 @@ ftrace_ops_test(struct ftrace_ops *ops, unsigned long 
ip, void *regs)
        return ret;
 }
 
-/*
- * This is a double for. Do not use 'break' to break out of the loop,
- * you must use a goto.
- */
-#define do_for_each_ftrace_rec(pg, rec)                                        
\
-       for (pg = ftrace_pages_start; pg; pg = pg->next) {              \
-               int _____i;                                             \
-               for (_____i = 0; _____i < pg->index; _____i++) {        \
-                       rec = &pg->records[_____i];
-
-#define while_for_each_ftrace_rec()            \
-               }                               \
-       }
-
-
 static int ftrace_cmp_recs(const void *a, const void *b)
 {
        const struct dyn_ftrace *key = a;
@@ -1638,7 +1623,7 @@ static bool __ftrace_hash_rec_update(struct ftrace_ops 
*ops,
 {
        struct ftrace_hash *hash;
        struct ftrace_hash *other_hash;
-       struct ftrace_page *pg;
+       struct ftrace_rec_iter *iter;
        struct dyn_ftrace *rec;
        bool update = false;
        int count = 0;
@@ -1676,11 +1661,13 @@ static bool __ftrace_hash_rec_update(struct ftrace_ops 
*ops,
                        return false;
        }
 
-       do_for_each_ftrace_rec(pg, rec) {
+       for_ftrace_rec_iter(iter) {
                int in_other_hash = 0;
                int in_hash = 0;
                int match = 0;
 
+               rec = ftrace_rec_iter_record(iter);
+
                if (rec->flags & FTRACE_FL_DISABLED)
                        continue;
 
@@ -1797,7 +1784,7 @@ static bool __ftrace_hash_rec_update(struct ftrace_ops 
*ops,
                /* Shortcut, if we handled all records, we are done. */
                if (!all && count == hash->count)
                        return update;
-       } while_for_each_ftrace_rec();
+       }
 
        return update;
 }
@@ -1862,7 +1849,7 @@ static int __ftrace_hash_update_ipmodify(struct 
ftrace_ops *ops,
                                         struct ftrace_hash *old_hash,
                                         struct ftrace_hash *new_hash)
 {
-       struct ftrace_page *pg;
+       struct ftrace_rec_iter *iter;
        struct dyn_ftrace *rec, *end = NULL;
        int in_old, in_new;
 
@@ -1881,7 +1868,8 @@ static int __ftrace_hash_update_ipmodify(struct 
ftrace_ops *ops,
                return -EINVAL;
 
        /* Update rec->flags */
-       do_for_each_ftrace_rec(pg, rec) {
+       for_ftrace_rec_iter(iter) {
+               rec = ftrace_rec_iter_record(iter);
 
                if (rec->flags & FTRACE_FL_DISABLED)
                        continue;
@@ -1899,7 +1887,7 @@ static int __ftrace_hash_update_ipmodify(struct 
ftrace_ops *ops,
                        rec->flags |= FTRACE_FL_IPMODIFY;
                } else /* Removed entry */
                        rec->flags &= ~FTRACE_FL_IPMODIFY;
-       } while_for_each_ftrace_rec();
+       }
 
        return 0;
 
@@ -1907,7 +1895,8 @@ static int __ftrace_hash_update_ipmodify(struct 
ftrace_ops *ops,
        end = rec;
 
        /* Roll back what we did above */
-       do_for_each_ftrace_rec(pg, rec) {
+       for_ftrace_rec_iter(iter) {
+               rec = ftrace_rec_iter_record(iter);
 
                if (rec->flags & FTRACE_FL_DISABLED)
                        continue;
@@ -1924,7 +1913,7 @@ static int __ftrace_hash_update_ipmodify(struct 
ftrace_ops *ops,
                        rec->flags &= ~FTRACE_FL_IPMODIFY;
                else
                        rec->flags |= FTRACE_FL_IPMODIFY;
-       } while_for_each_ftrace_rec();
+       }
 
 err_out:
        return -EBUSY;
@@ -2517,8 +2506,8 @@ __ftrace_replace_code(struct dyn_ftrace *rec, bool enable)
 
 void __weak ftrace_replace_code(int mod_flags)
 {
+       struct ftrace_rec_iter *iter;
        struct dyn_ftrace *rec;
-       struct ftrace_page *pg;
        bool enable = mod_flags & FTRACE_MODIFY_ENABLE_FL;
        int schedulable = mod_flags & FTRACE_MODIFY_MAY_SLEEP_FL;
        int failed;
@@ -2526,7 +2515,8 @@ void __weak ftrace_replace_code(int mod_flags)
        if (unlikely(ftrace_disabled))
                return;
 
-       do_for_each_ftrace_rec(pg, rec) {
+       for_ftrace_rec_iter(iter) {
+               rec = ftrace_rec_iter_record(iter);
 
                if (rec->flags & FTRACE_FL_DISABLED)
                        continue;
@@ -2539,7 +2529,7 @@ void __weak ftrace_replace_code(int mod_flags)
                }
                if (schedulable)
                        cond_resched();
-       } while_for_each_ftrace_rec();
+       }
 }
 
 struct ftrace_rec_iter {
@@ -2940,14 +2930,15 @@ int ftrace_shutdown(struct ftrace_ops *ops, int command)
         */
        if (rcu_dereference_protected(ftrace_ops_list,
                        lockdep_is_held(&ftrace_lock)) == &ftrace_list_end) {
-               struct ftrace_page *pg;
+               struct ftrace_rec_iter *iter;
                struct dyn_ftrace *rec;
 
-               do_for_each_ftrace_rec(pg, rec) {
+               for_ftrace_rec_iter(iter) {
+                       rec = ftrace_rec_iter_record(iter);
                        if (FTRACE_WARN_ON_ONCE(rec->flags & 
~FTRACE_FL_DISABLED))
                                pr_warn("  %pS flags:%lx\n",
                                        (void *)rec->ip, rec->flags);
-               } while_for_each_ftrace_rec();
+               }
        }
 
        ops->old_hash.filter_hash = NULL;
@@ -3917,6 +3908,7 @@ add_rec_by_index(struct ftrace_hash *hash, struct 
ftrace_glob *func_g,
                 int clear_filter)
 {
        long index = simple_strtoul(func_g->search, NULL, 0);
+       struct ftrace_rec_iter *iter;
        struct ftrace_page *pg;
        struct dyn_ftrace *rec;
 
@@ -3924,16 +3916,17 @@ add_rec_by_index(struct ftrace_hash *hash, struct 
ftrace_glob *func_g,
        if (--index < 0)
                return 0;
 
-       do_for_each_ftrace_rec(pg, rec) {
+       for_ftrace_rec_iter(iter) {
+               pg = iter->pg;
                if (pg->index <= index) {
+                       iter->index = pg->index;
                        index -= pg->index;
-                       /* this is a double loop, break goes to the next page */
-                       break;
+                       continue;
                }
                rec = &pg->records[index];
                enter_record(hash, rec, clear_filter);
                return 1;
-       } while_for_each_ftrace_rec();
+       }
        return 0;
 }
 
@@ -3978,7 +3971,7 @@ ftrace_match_record(struct dyn_ftrace *rec, struct 
ftrace_glob *func_g,
 static int
 match_records(struct ftrace_hash *hash, char *func, int len, char *mod)
 {
-       struct ftrace_page *pg;
+       struct ftrace_rec_iter *iter;
        struct dyn_ftrace *rec;
        struct ftrace_glob func_g = { .type = MATCH_FULL };
        struct ftrace_glob mod_g = { .type = MATCH_FULL };
@@ -4010,7 +4003,8 @@ match_records(struct ftrace_hash *hash, char *func, int 
len, char *mod)
                goto out_unlock;
        }
 
-       do_for_each_ftrace_rec(pg, rec) {
+       for_ftrace_rec_iter(iter) {
+               rec = ftrace_rec_iter_record(iter);
 
                if (rec->flags & FTRACE_FL_DISABLED)
                        continue;
@@ -4023,7 +4017,7 @@ match_records(struct ftrace_hash *hash, char *func, int 
len, char *mod)
                        }
                        found = 1;
                }
-       } while_for_each_ftrace_rec();
+       }
  out_unlock:
        mutex_unlock(&ftrace_lock);
 
@@ -5945,7 +5939,7 @@ ftrace_graph_set_hash(struct ftrace_hash *hash, char 
*buffer)
 {
        struct ftrace_glob func_g;
        struct dyn_ftrace *rec;
-       struct ftrace_page *pg;
+       struct ftrace_rec_iter *iter;
        struct ftrace_func_entry *entry;
        int fail = 1;
        int not;
@@ -5963,7 +5957,8 @@ ftrace_graph_set_hash(struct ftrace_hash *hash, char 
*buffer)
                return -ENODEV;
        }
 
-       do_for_each_ftrace_rec(pg, rec) {
+       for_ftrace_rec_iter(iter) {
+               rec = ftrace_rec_iter_record(iter);
 
                if (rec->flags & FTRACE_FL_DISABLED)
                        continue;
@@ -5985,7 +5980,7 @@ ftrace_graph_set_hash(struct ftrace_hash *hash, char 
*buffer)
                                }
                        }
                }
-       } while_for_each_ftrace_rec();
+       }
 out:
        mutex_unlock(&ftrace_lock);
 
@@ -6407,7 +6402,7 @@ void ftrace_release_mod(struct module *mod)
 void ftrace_module_enable(struct module *mod)
 {
        struct dyn_ftrace *rec;
-       struct ftrace_page *pg;
+       struct ftrace_rec_iter *iter;
 
        mutex_lock(&ftrace_lock);
 
@@ -6430,17 +6425,16 @@ void ftrace_module_enable(struct module *mod)
        if (ftrace_start_up)
                ftrace_arch_code_modify_prepare();
 
-       do_for_each_ftrace_rec(pg, rec) {
+       for_ftrace_rec_iter(iter) {
                int cnt;
-               /*
-                * do_for_each_ftrace_rec() is a double loop.
-                * module text shares the pg. If a record is
-                * not part of this module, then skip this pg,
-                * which the "break" will do.
-                */
+               rec = ftrace_rec_iter_record(iter);
+
                if (!within_module_core(rec->ip, mod) &&
-                   !within_module_init(rec->ip, mod))
-                       break;
+                   !within_module_init(rec->ip, mod)) {
+                       /* skip current ftrace_page */
+                       iter->index = iter->pg->index;
+                       continue;
+               }
 
                cnt = 0;
 
@@ -6464,7 +6458,7 @@ void ftrace_module_enable(struct module *mod)
                        }
                }
 
-       } while_for_each_ftrace_rec();
+       }
 
  out_loop:
        if (ftrace_start_up)
-- 
2.20.1 (Apple Git-117)

Reply via email to