Commit f45948e898e7bc76a73a468796d2ce80dd040058
Committed by
Steven Rostedt
1 parent
1cf41dd799
Exists in
master
and in
7 other branches
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>
Showing 2 changed files with 54 additions and 21 deletions Side-by-side Diff
include/linux/ftrace.h
... | ... | @@ -29,9 +29,15 @@ |
29 | 29 | |
30 | 30 | typedef void (*ftrace_func_t)(unsigned long ip, unsigned long parent_ip); |
31 | 31 | |
32 | +struct ftrace_hash; | |
33 | + | |
32 | 34 | struct ftrace_ops { |
33 | - ftrace_func_t func; | |
34 | - struct ftrace_ops *next; | |
35 | + ftrace_func_t func; | |
36 | + struct ftrace_ops *next; | |
37 | +#ifdef CONFIG_DYNAMIC_FTRACE | |
38 | + struct ftrace_hash *notrace_hash; | |
39 | + struct ftrace_hash *filter_hash; | |
40 | +#endif | |
35 | 41 | }; |
36 | 42 | |
37 | 43 | extern int function_trace_stop; |
kernel/trace/ftrace.c
... | ... | @@ -889,6 +889,12 @@ |
889 | 889 | .buckets = filter_buckets, |
890 | 890 | }; |
891 | 891 | |
892 | +struct ftrace_ops global_ops = { | |
893 | + .func = ftrace_stub, | |
894 | + .notrace_hash = ¬race_hash, | |
895 | + .filter_hash = &filter_hash, | |
896 | +}; | |
897 | + | |
892 | 898 | static struct dyn_ftrace *ftrace_new_addrs; |
893 | 899 | |
894 | 900 | static DEFINE_MUTEX(ftrace_regex_lock); |
... | ... | @@ -1112,6 +1118,7 @@ |
1112 | 1118 | static int |
1113 | 1119 | __ftrace_replace_code(struct dyn_ftrace *rec, int enable) |
1114 | 1120 | { |
1121 | + struct ftrace_ops *ops = &global_ops; | |
1115 | 1122 | unsigned long ftrace_addr; |
1116 | 1123 | unsigned long flag = 0UL; |
1117 | 1124 | |
... | ... | @@ -1126,8 +1133,9 @@ |
1126 | 1133 | * If we want to enable it and filtering is on, enable it only if |
1127 | 1134 | * it's filtered |
1128 | 1135 | */ |
1129 | - if (enable && !ftrace_lookup_ip(¬race_hash, rec->ip)) { | |
1130 | - if (!filter_hash.count || ftrace_lookup_ip(&filter_hash, rec->ip)) | |
1136 | + if (enable && !ftrace_lookup_ip(ops->notrace_hash, rec->ip)) { | |
1137 | + if (!ops->filter_hash->count || | |
1138 | + ftrace_lookup_ip(ops->filter_hash, rec->ip)) | |
1131 | 1139 | flag = FTRACE_FL_ENABLED; |
1132 | 1140 | } |
1133 | 1141 | |
... | ... | @@ -1531,6 +1539,7 @@ |
1531 | 1539 | t_next(struct seq_file *m, void *v, loff_t *pos) |
1532 | 1540 | { |
1533 | 1541 | struct ftrace_iterator *iter = m->private; |
1542 | + struct ftrace_ops *ops = &global_ops; | |
1534 | 1543 | struct dyn_ftrace *rec = NULL; |
1535 | 1544 | |
1536 | 1545 | if (unlikely(ftrace_disabled)) |
1537 | 1546 | |
... | ... | @@ -1557,10 +1566,10 @@ |
1557 | 1566 | if ((rec->flags & FTRACE_FL_FREE) || |
1558 | 1567 | |
1559 | 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 | 1571 | ((iter->flags & FTRACE_ITER_NOTRACE) && |
1563 | - !ftrace_lookup_ip(¬race_hash, rec->ip))) { | |
1572 | + !ftrace_lookup_ip(ops->notrace_hash, rec->ip))) { | |
1564 | 1573 | rec = NULL; |
1565 | 1574 | goto retry; |
1566 | 1575 | } |
... | ... | @@ -1584,6 +1593,7 @@ |
1584 | 1593 | static void *t_start(struct seq_file *m, loff_t *pos) |
1585 | 1594 | { |
1586 | 1595 | struct ftrace_iterator *iter = m->private; |
1596 | + struct ftrace_ops *ops = &global_ops; | |
1587 | 1597 | void *p = NULL; |
1588 | 1598 | loff_t l; |
1589 | 1599 | |
... | ... | @@ -1603,7 +1613,7 @@ |
1603 | 1613 | * off, we can short cut and just print out that all |
1604 | 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 | 1617 | if (*pos > 0) |
1608 | 1618 | return t_hash_start(m, pos); |
1609 | 1619 | iter->flags |= FTRACE_ITER_PRINTALL; |
1610 | 1620 | |
... | ... | @@ -1708,10 +1718,11 @@ |
1708 | 1718 | } |
1709 | 1719 | |
1710 | 1720 | static int |
1711 | -ftrace_regex_open(struct ftrace_hash *hash, int flag, | |
1721 | +ftrace_regex_open(struct ftrace_ops *ops, int flag, | |
1712 | 1722 | struct inode *inode, struct file *file) |
1713 | 1723 | { |
1714 | 1724 | struct ftrace_iterator *iter; |
1725 | + struct ftrace_hash *hash; | |
1715 | 1726 | int ret = 0; |
1716 | 1727 | |
1717 | 1728 | if (unlikely(ftrace_disabled)) |
... | ... | @@ -1726,6 +1737,11 @@ |
1726 | 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 | 1745 | iter->hash = hash; |
1730 | 1746 | |
1731 | 1747 | mutex_lock(&ftrace_regex_lock); |
1732 | 1748 | |
... | ... | @@ -1755,14 +1771,14 @@ |
1755 | 1771 | static int |
1756 | 1772 | ftrace_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 | 1775 | inode, file); |
1760 | 1776 | } |
1761 | 1777 | |
1762 | 1778 | static int |
1763 | 1779 | ftrace_notrace_open(struct inode *inode, struct file *file) |
1764 | 1780 | { |
1765 | - return ftrace_regex_open(¬race_hash, FTRACE_ITER_NOTRACE, | |
1781 | + return ftrace_regex_open(&global_ops, FTRACE_ITER_NOTRACE, | |
1766 | 1782 | inode, file); |
1767 | 1783 | } |
1768 | 1784 | |
... | ... | @@ -1923,6 +1939,7 @@ |
1923 | 1939 | static int |
1924 | 1940 | ftrace_mod_callback(char *func, char *cmd, char *param, int enable) |
1925 | 1941 | { |
1942 | + struct ftrace_ops *ops = &global_ops; | |
1926 | 1943 | struct ftrace_hash *hash; |
1927 | 1944 | char *mod; |
1928 | 1945 | int ret = -EINVAL; |
1929 | 1946 | |
... | ... | @@ -1944,9 +1961,9 @@ |
1944 | 1961 | return ret; |
1945 | 1962 | |
1946 | 1963 | if (enable) |
1947 | - hash = &filter_hash; | |
1964 | + hash = ops->filter_hash; | |
1948 | 1965 | else |
1949 | - hash = ¬race_hash; | |
1966 | + hash = ops->notrace_hash; | |
1950 | 1967 | |
1951 | 1968 | ret = ftrace_match_module_records(hash, func, mod); |
1952 | 1969 | if (!ret) |
1953 | 1970 | |
1954 | 1971 | |
... | ... | @@ -2245,14 +2262,15 @@ |
2245 | 2262 | static int ftrace_process_regex(char *buff, int len, int enable) |
2246 | 2263 | { |
2247 | 2264 | char *func, *command, *next = buff; |
2265 | + struct ftrace_ops *ops = &global_ops; | |
2248 | 2266 | struct ftrace_func_command *p; |
2249 | 2267 | struct ftrace_hash *hash; |
2250 | 2268 | int ret; |
2251 | 2269 | |
2252 | 2270 | if (enable) |
2253 | - hash = &filter_hash; | |
2271 | + hash = ops->filter_hash; | |
2254 | 2272 | else |
2255 | - hash = ¬race_hash; | |
2273 | + hash = ops->notrace_hash; | |
2256 | 2274 | |
2257 | 2275 | func = strsep(&next, ":"); |
2258 | 2276 | |
2259 | 2277 | |
2260 | 2278 | |
... | ... | @@ -2339,11 +2357,19 @@ |
2339 | 2357 | } |
2340 | 2358 | |
2341 | 2359 | static void |
2342 | -ftrace_set_regex(struct ftrace_hash *hash, unsigned char *buf, int len, int reset) | |
2360 | +ftrace_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 | 2365 | if (unlikely(ftrace_disabled)) |
2345 | 2366 | return; |
2346 | 2367 | |
2368 | + if (enable) | |
2369 | + hash = ops->filter_hash; | |
2370 | + else | |
2371 | + hash = ops->notrace_hash; | |
2372 | + | |
2347 | 2373 | mutex_lock(&ftrace_regex_lock); |
2348 | 2374 | if (reset) |
2349 | 2375 | ftrace_filter_reset(hash); |
... | ... | @@ -2363,7 +2389,7 @@ |
2363 | 2389 | */ |
2364 | 2390 | void 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 @@ |
2378 | 2404 | */ |
2379 | 2405 | void ftrace_set_notrace(unsigned char *buf, int len, int reset) |
2380 | 2406 | { |
2381 | - ftrace_set_regex(¬race_hash, buf, len, reset); | |
2407 | + ftrace_set_regex(&global_ops, buf, len, reset, 0); | |
2382 | 2408 | } |
2383 | 2409 | |
2384 | 2410 | /* |
2385 | 2411 | |
2386 | 2412 | |
2387 | 2413 | |
... | ... | @@ -2430,22 +2456,23 @@ |
2430 | 2456 | } |
2431 | 2457 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
2432 | 2458 | |
2433 | -static void __init set_ftrace_early_filter(struct ftrace_hash *hash, char *buf) | |
2459 | +static void __init | |
2460 | +set_ftrace_early_filter(struct ftrace_ops *ops, char *buf, int enable) | |
2434 | 2461 | { |
2435 | 2462 | char *func; |
2436 | 2463 | |
2437 | 2464 | while (buf) { |
2438 | 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 | |
2443 | 2470 | static void __init set_ftrace_early_filters(void) |
2444 | 2471 | { |
2445 | 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 | 2474 | if (ftrace_notrace_buf[0]) |
2448 | - set_ftrace_early_filter(¬race_hash, ftrace_notrace_buf); | |
2475 | + set_ftrace_early_filter(&global_ops, ftrace_notrace_buf, 0); | |
2449 | 2476 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
2450 | 2477 | if (ftrace_graph_buf[0]) |
2451 | 2478 | set_ftrace_early_graph(ftrace_graph_buf); |