aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/ftrace.c
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2011-05-02 12:29:25 -0400
committerSteven Rostedt <rostedt@goodmis.org>2011-05-18 15:29:45 -0400
commitf45948e898e7bc76a73a468796d2ce80dd040058 (patch)
tree483979d8030cc2cf156ed65218c03a2d6825d9f5 /kernel/trace/ftrace.c
parent1cf41dd79993389b012e4542ab502ce36ae7343f (diff)
ftrace: Create a global_ops to hold the filter and notrace hashes
Combine the filter and notrace hashes to be accessed by a single entity, the global_ops. The global_ops is a ftrace_ops structure that is passed to different functions that can read or modify the filtering of the function tracer. The ftrace_ops structure was modified to hold a filter and notrace hashes so that later patches may allow each ftrace_ops to have its own set of rules to what functions may be filtered. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r--kernel/trace/ftrace.c65
1 files changed, 46 insertions, 19 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 222eca4c3022..a517a6c40645 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -889,6 +889,12 @@ static struct ftrace_hash filter_hash = {
889 .buckets = filter_buckets, 889 .buckets = filter_buckets,
890}; 890};
891 891
892struct ftrace_ops global_ops = {
893 .func = ftrace_stub,
894 .notrace_hash = &notrace_hash,
895 .filter_hash = &filter_hash,
896};
897
892static struct dyn_ftrace *ftrace_new_addrs; 898static struct dyn_ftrace *ftrace_new_addrs;
893 899
894static DEFINE_MUTEX(ftrace_regex_lock); 900static DEFINE_MUTEX(ftrace_regex_lock);
@@ -1112,6 +1118,7 @@ int ftrace_text_reserved(void *start, void *end)
1112static int 1118static int
1113__ftrace_replace_code(struct dyn_ftrace *rec, int enable) 1119__ftrace_replace_code(struct dyn_ftrace *rec, int enable)
1114{ 1120{
1121 struct ftrace_ops *ops = &global_ops;
1115 unsigned long ftrace_addr; 1122 unsigned long ftrace_addr;
1116 unsigned long flag = 0UL; 1123 unsigned long flag = 0UL;
1117 1124
@@ -1126,8 +1133,9 @@ __ftrace_replace_code(struct dyn_ftrace *rec, int enable)
1126 * If we want to enable it and filtering is on, enable it only if 1133 * If we want to enable it and filtering is on, enable it only if
1127 * it's filtered 1134 * it's filtered
1128 */ 1135 */
1129 if (enable && !ftrace_lookup_ip(&notrace_hash, rec->ip)) { 1136 if (enable && !ftrace_lookup_ip(ops->notrace_hash, rec->ip)) {
1130 if (!filter_hash.count || ftrace_lookup_ip(&filter_hash, rec->ip)) 1137 if (!ops->filter_hash->count ||
1138 ftrace_lookup_ip(ops->filter_hash, rec->ip))
1131 flag = FTRACE_FL_ENABLED; 1139 flag = FTRACE_FL_ENABLED;
1132 } 1140 }
1133 1141
@@ -1531,6 +1539,7 @@ static void *
1531t_next(struct seq_file *m, void *v, loff_t *pos) 1539t_next(struct seq_file *m, void *v, loff_t *pos)
1532{ 1540{
1533 struct ftrace_iterator *iter = m->private; 1541 struct ftrace_iterator *iter = m->private;
1542 struct ftrace_ops *ops = &global_ops;
1534 struct dyn_ftrace *rec = NULL; 1543 struct dyn_ftrace *rec = NULL;
1535 1544
1536 if (unlikely(ftrace_disabled)) 1545 if (unlikely(ftrace_disabled))
@@ -1557,10 +1566,10 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
1557 if ((rec->flags & FTRACE_FL_FREE) || 1566 if ((rec->flags & FTRACE_FL_FREE) ||
1558 1567
1559 ((iter->flags & FTRACE_ITER_FILTER) && 1568 ((iter->flags & FTRACE_ITER_FILTER) &&
1560 !(ftrace_lookup_ip(&filter_hash, rec->ip))) || 1569 !(ftrace_lookup_ip(ops->filter_hash, rec->ip))) ||
1561 1570
1562 ((iter->flags & FTRACE_ITER_NOTRACE) && 1571 ((iter->flags & FTRACE_ITER_NOTRACE) &&
1563 !ftrace_lookup_ip(&notrace_hash, rec->ip))) { 1572 !ftrace_lookup_ip(ops->notrace_hash, rec->ip))) {
1564 rec = NULL; 1573 rec = NULL;
1565 goto retry; 1574 goto retry;
1566 } 1575 }
@@ -1584,6 +1593,7 @@ static void reset_iter_read(struct ftrace_iterator *iter)
1584static void *t_start(struct seq_file *m, loff_t *pos) 1593static void *t_start(struct seq_file *m, loff_t *pos)
1585{ 1594{
1586 struct ftrace_iterator *iter = m->private; 1595 struct ftrace_iterator *iter = m->private;
1596 struct ftrace_ops *ops = &global_ops;
1587 void *p = NULL; 1597 void *p = NULL;
1588 loff_t l; 1598 loff_t l;
1589 1599
@@ -1603,7 +1613,7 @@ static void *t_start(struct seq_file *m, loff_t *pos)
1603 * off, we can short cut and just print out that all 1613 * off, we can short cut and just print out that all
1604 * functions are enabled. 1614 * functions are enabled.
1605 */ 1615 */
1606 if (iter->flags & FTRACE_ITER_FILTER && !filter_hash.count) { 1616 if (iter->flags & FTRACE_ITER_FILTER && !ops->filter_hash->count) {
1607 if (*pos > 0) 1617 if (*pos > 0)
1608 return t_hash_start(m, pos); 1618 return t_hash_start(m, pos);
1609 iter->flags |= FTRACE_ITER_PRINTALL; 1619 iter->flags |= FTRACE_ITER_PRINTALL;
@@ -1708,10 +1718,11 @@ static void ftrace_filter_reset(struct ftrace_hash *hash)
1708} 1718}
1709 1719
1710static int 1720static int
1711ftrace_regex_open(struct ftrace_hash *hash, int flag, 1721ftrace_regex_open(struct ftrace_ops *ops, int flag,
1712 struct inode *inode, struct file *file) 1722 struct inode *inode, struct file *file)
1713{ 1723{
1714 struct ftrace_iterator *iter; 1724 struct ftrace_iterator *iter;
1725 struct ftrace_hash *hash;
1715 int ret = 0; 1726 int ret = 0;
1716 1727
1717 if (unlikely(ftrace_disabled)) 1728 if (unlikely(ftrace_disabled))
@@ -1726,6 +1737,11 @@ ftrace_regex_open(struct ftrace_hash *hash, int flag,
1726 return -ENOMEM; 1737 return -ENOMEM;
1727 } 1738 }
1728 1739
1740 if (flag & FTRACE_ITER_NOTRACE)
1741 hash = ops->notrace_hash;
1742 else
1743 hash = ops->filter_hash;
1744
1729 iter->hash = hash; 1745 iter->hash = hash;
1730 1746
1731 mutex_lock(&ftrace_regex_lock); 1747 mutex_lock(&ftrace_regex_lock);
@@ -1755,14 +1771,14 @@ ftrace_regex_open(struct ftrace_hash *hash, int flag,
1755static int 1771static int
1756ftrace_filter_open(struct inode *inode, struct file *file) 1772ftrace_filter_open(struct inode *inode, struct file *file)
1757{ 1773{
1758 return ftrace_regex_open(&filter_hash, FTRACE_ITER_FILTER, 1774 return ftrace_regex_open(&global_ops, FTRACE_ITER_FILTER,
1759 inode, file); 1775 inode, file);
1760} 1776}
1761 1777
1762static int 1778static int
1763ftrace_notrace_open(struct inode *inode, struct file *file) 1779ftrace_notrace_open(struct inode *inode, struct file *file)
1764{ 1780{
1765 return ftrace_regex_open(&notrace_hash, FTRACE_ITER_NOTRACE, 1781 return ftrace_regex_open(&global_ops, FTRACE_ITER_NOTRACE,
1766 inode, file); 1782 inode, file);
1767} 1783}
1768 1784
@@ -1923,6 +1939,7 @@ ftrace_match_module_records(struct ftrace_hash *hash, char *buff, char *mod)
1923static int 1939static int
1924ftrace_mod_callback(char *func, char *cmd, char *param, int enable) 1940ftrace_mod_callback(char *func, char *cmd, char *param, int enable)
1925{ 1941{
1942 struct ftrace_ops *ops = &global_ops;
1926 struct ftrace_hash *hash; 1943 struct ftrace_hash *hash;
1927 char *mod; 1944 char *mod;
1928 int ret = -EINVAL; 1945 int ret = -EINVAL;
@@ -1944,9 +1961,9 @@ ftrace_mod_callback(char *func, char *cmd, char *param, int enable)
1944 return ret; 1961 return ret;
1945 1962
1946 if (enable) 1963 if (enable)
1947 hash = &filter_hash; 1964 hash = ops->filter_hash;
1948 else 1965 else
1949 hash = &notrace_hash; 1966 hash = ops->notrace_hash;
1950 1967
1951 ret = ftrace_match_module_records(hash, func, mod); 1968 ret = ftrace_match_module_records(hash, func, mod);
1952 if (!ret) 1969 if (!ret)
@@ -2245,14 +2262,15 @@ int unregister_ftrace_command(struct ftrace_func_command *cmd)
2245static int ftrace_process_regex(char *buff, int len, int enable) 2262static int ftrace_process_regex(char *buff, int len, int enable)
2246{ 2263{
2247 char *func, *command, *next = buff; 2264 char *func, *command, *next = buff;
2265 struct ftrace_ops *ops = &global_ops;
2248 struct ftrace_func_command *p; 2266 struct ftrace_func_command *p;
2249 struct ftrace_hash *hash; 2267 struct ftrace_hash *hash;
2250 int ret; 2268 int ret;
2251 2269
2252 if (enable) 2270 if (enable)
2253 hash = &filter_hash; 2271 hash = ops->filter_hash;
2254 else 2272 else
2255 hash = &notrace_hash; 2273 hash = ops->notrace_hash;
2256 2274
2257 func = strsep(&next, ":"); 2275 func = strsep(&next, ":");
2258 2276
@@ -2339,11 +2357,19 @@ ftrace_notrace_write(struct file *file, const char __user *ubuf,
2339} 2357}
2340 2358
2341static void 2359static void
2342ftrace_set_regex(struct ftrace_hash *hash, unsigned char *buf, int len, int reset) 2360ftrace_set_regex(struct ftrace_ops *ops, unsigned char *buf, int len,
2361 int reset, int enable)
2343{ 2362{
2363 struct ftrace_hash *hash;
2364
2344 if (unlikely(ftrace_disabled)) 2365 if (unlikely(ftrace_disabled))
2345 return; 2366 return;
2346 2367
2368 if (enable)
2369 hash = ops->filter_hash;
2370 else
2371 hash = ops->notrace_hash;
2372
2347 mutex_lock(&ftrace_regex_lock); 2373 mutex_lock(&ftrace_regex_lock);
2348 if (reset) 2374 if (reset)
2349 ftrace_filter_reset(hash); 2375 ftrace_filter_reset(hash);
@@ -2363,7 +2389,7 @@ ftrace_set_regex(struct ftrace_hash *hash, unsigned char *buf, int len, int rese
2363 */ 2389 */
2364void ftrace_set_filter(unsigned char *buf, int len, int reset) 2390void ftrace_set_filter(unsigned char *buf, int len, int reset)
2365{ 2391{
2366 ftrace_set_regex(&filter_hash, buf, len, reset); 2392 ftrace_set_regex(&global_ops, buf, len, reset, 1);
2367} 2393}
2368 2394
2369/** 2395/**
@@ -2378,7 +2404,7 @@ void ftrace_set_filter(unsigned char *buf, int len, int reset)
2378 */ 2404 */
2379void ftrace_set_notrace(unsigned char *buf, int len, int reset) 2405void ftrace_set_notrace(unsigned char *buf, int len, int reset)
2380{ 2406{
2381 ftrace_set_regex(&notrace_hash, buf, len, reset); 2407 ftrace_set_regex(&global_ops, buf, len, reset, 0);
2382} 2408}
2383 2409
2384/* 2410/*
@@ -2430,22 +2456,23 @@ static void __init set_ftrace_early_graph(char *buf)
2430} 2456}
2431#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ 2457#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
2432 2458
2433static void __init set_ftrace_early_filter(struct ftrace_hash *hash, char *buf) 2459static void __init
2460set_ftrace_early_filter(struct ftrace_ops *ops, char *buf, int enable)
2434{ 2461{
2435 char *func; 2462 char *func;
2436 2463
2437 while (buf) { 2464 while (buf) {
2438 func = strsep(&buf, ","); 2465 func = strsep(&buf, ",");
2439 ftrace_set_regex(hash, func, strlen(func), 0); 2466 ftrace_set_regex(ops, func, strlen(func), 0, enable);
2440 } 2467 }
2441} 2468}
2442 2469
2443static void __init set_ftrace_early_filters(void) 2470static void __init set_ftrace_early_filters(void)
2444{ 2471{
2445 if (ftrace_filter_buf[0]) 2472 if (ftrace_filter_buf[0])
2446 set_ftrace_early_filter(&filter_hash, ftrace_filter_buf); 2473 set_ftrace_early_filter(&global_ops, ftrace_filter_buf, 1);
2447 if (ftrace_notrace_buf[0]) 2474 if (ftrace_notrace_buf[0])
2448 set_ftrace_early_filter(&notrace_hash, ftrace_notrace_buf); 2475 set_ftrace_early_filter(&global_ops, ftrace_notrace_buf, 0);
2449#ifdef CONFIG_FUNCTION_GRAPH_TRACER 2476#ifdef CONFIG_FUNCTION_GRAPH_TRACER
2450 if (ftrace_graph_buf[0]) 2477 if (ftrace_graph_buf[0])
2451 set_ftrace_early_graph(ftrace_graph_buf); 2478 set_ftrace_early_graph(ftrace_graph_buf);