aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/ftrace.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2011-05-01 13:11:42 -0400
committerIngo Molnar <mingo@elte.hu>2011-05-01 13:11:42 -0400
commitac0a3260f37b8616da8d33488ec94b94e6ae5b31 (patch)
tree0db61f7492d45f1d548b0bcef06a0df9c904442c /kernel/trace/ftrace.c
parent809435ff4f43a5c0cb0201b3b89176253d5ade18 (diff)
parentb9df92d2a94eef8811061aecb1396290df440e2e (diff)
Merge branch 'tip/perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace into perf/core
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r--kernel/trace/ftrace.c347
1 files changed, 138 insertions, 209 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 666880d051ef..d3406346ced6 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -39,16 +39,20 @@
39#include "trace_stat.h" 39#include "trace_stat.h"
40 40
41#define FTRACE_WARN_ON(cond) \ 41#define FTRACE_WARN_ON(cond) \
42 do { \ 42 ({ \
43 if (WARN_ON(cond)) \ 43 int ___r = cond; \
44 if (WARN_ON(___r)) \
44 ftrace_kill(); \ 45 ftrace_kill(); \
45 } while (0) 46 ___r; \
47 })
46 48
47#define FTRACE_WARN_ON_ONCE(cond) \ 49#define FTRACE_WARN_ON_ONCE(cond) \
48 do { \ 50 ({ \
49 if (WARN_ON_ONCE(cond)) \ 51 int ___r = cond; \
52 if (WARN_ON_ONCE(___r)) \
50 ftrace_kill(); \ 53 ftrace_kill(); \
51 } while (0) 54 ___r; \
55 })
52 56
53/* hash bits for specific function selection */ 57/* hash bits for specific function selection */
54#define FTRACE_HASH_BITS 7 58#define FTRACE_HASH_BITS 7
@@ -147,6 +151,34 @@ static void ftrace_test_stop_func(unsigned long ip, unsigned long parent_ip)
147} 151}
148#endif 152#endif
149 153
154static void update_ftrace_function(void)
155{
156 ftrace_func_t func;
157
158 /*
159 * If there's only one function registered, then call that
160 * function directly. Otherwise, we need to iterate over the
161 * registered callers.
162 */
163 if (ftrace_list == &ftrace_list_end ||
164 ftrace_list->next == &ftrace_list_end)
165 func = ftrace_list->func;
166 else
167 func = ftrace_list_func;
168
169 /* If we filter on pids, update to use the pid function */
170 if (!list_empty(&ftrace_pids)) {
171 set_ftrace_pid_function(func);
172 func = ftrace_pid_func;
173 }
174#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
175 ftrace_trace_function = func;
176#else
177 __ftrace_trace_function = func;
178 ftrace_trace_function = ftrace_test_stop_func;
179#endif
180}
181
150static int __register_ftrace_function(struct ftrace_ops *ops) 182static int __register_ftrace_function(struct ftrace_ops *ops)
151{ 183{
152 ops->next = ftrace_list; 184 ops->next = ftrace_list;
@@ -158,30 +190,8 @@ static int __register_ftrace_function(struct ftrace_ops *ops)
158 */ 190 */
159 rcu_assign_pointer(ftrace_list, ops); 191 rcu_assign_pointer(ftrace_list, ops);
160 192
161 if (ftrace_enabled) { 193 if (ftrace_enabled)
162 ftrace_func_t func; 194 update_ftrace_function();
163
164 if (ops->next == &ftrace_list_end)
165 func = ops->func;
166 else
167 func = ftrace_list_func;
168
169 if (!list_empty(&ftrace_pids)) {
170 set_ftrace_pid_function(func);
171 func = ftrace_pid_func;
172 }
173
174 /*
175 * For one func, simply call it directly.
176 * For more than one func, call the chain.
177 */
178#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
179 ftrace_trace_function = func;
180#else
181 __ftrace_trace_function = func;
182 ftrace_trace_function = ftrace_test_stop_func;
183#endif
184 }
185 195
186 return 0; 196 return 0;
187} 197}
@@ -209,52 +219,19 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops)
209 219
210 *p = (*p)->next; 220 *p = (*p)->next;
211 221
212 if (ftrace_enabled) { 222 if (ftrace_enabled)
213 /* If we only have one func left, then call that directly */ 223 update_ftrace_function();
214 if (ftrace_list->next == &ftrace_list_end) {
215 ftrace_func_t func = ftrace_list->func;
216
217 if (!list_empty(&ftrace_pids)) {
218 set_ftrace_pid_function(func);
219 func = ftrace_pid_func;
220 }
221#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
222 ftrace_trace_function = func;
223#else
224 __ftrace_trace_function = func;
225#endif
226 }
227 }
228 224
229 return 0; 225 return 0;
230} 226}
231 227
232static void ftrace_update_pid_func(void) 228static void ftrace_update_pid_func(void)
233{ 229{
234 ftrace_func_t func; 230 /* Only do something if we are tracing something */
235
236 if (ftrace_trace_function == ftrace_stub) 231 if (ftrace_trace_function == ftrace_stub)
237 return; 232 return;
238 233
239#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST 234 update_ftrace_function();
240 func = ftrace_trace_function;
241#else
242 func = __ftrace_trace_function;
243#endif
244
245 if (!list_empty(&ftrace_pids)) {
246 set_ftrace_pid_function(func);
247 func = ftrace_pid_func;
248 } else {
249 if (func == ftrace_pid_func)
250 func = ftrace_pid_function;
251 }
252
253#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
254 ftrace_trace_function = func;
255#else
256 __ftrace_trace_function = func;
257#endif
258} 235}
259 236
260#ifdef CONFIG_FUNCTION_PROFILER 237#ifdef CONFIG_FUNCTION_PROFILER
@@ -1079,19 +1056,16 @@ static void ftrace_replace_code(int enable)
1079 struct ftrace_page *pg; 1056 struct ftrace_page *pg;
1080 int failed; 1057 int failed;
1081 1058
1059 if (unlikely(ftrace_disabled))
1060 return;
1061
1082 do_for_each_ftrace_rec(pg, rec) { 1062 do_for_each_ftrace_rec(pg, rec) {
1083 /* 1063 /* Skip over free records */
1084 * Skip over free records, records that have 1064 if (rec->flags & FTRACE_FL_FREE)
1085 * failed and not converted.
1086 */
1087 if (rec->flags & FTRACE_FL_FREE ||
1088 rec->flags & FTRACE_FL_FAILED ||
1089 !(rec->flags & FTRACE_FL_CONVERTED))
1090 continue; 1065 continue;
1091 1066
1092 failed = __ftrace_replace_code(rec, enable); 1067 failed = __ftrace_replace_code(rec, enable);
1093 if (failed) { 1068 if (failed) {
1094 rec->flags |= FTRACE_FL_FAILED;
1095 ftrace_bug(failed, rec->ip); 1069 ftrace_bug(failed, rec->ip);
1096 /* Stop processing */ 1070 /* Stop processing */
1097 return; 1071 return;
@@ -1107,10 +1081,12 @@ ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec)
1107 1081
1108 ip = rec->ip; 1082 ip = rec->ip;
1109 1083
1084 if (unlikely(ftrace_disabled))
1085 return 0;
1086
1110 ret = ftrace_make_nop(mod, rec, MCOUNT_ADDR); 1087 ret = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
1111 if (ret) { 1088 if (ret) {
1112 ftrace_bug(ret, ip); 1089 ftrace_bug(ret, ip);
1113 rec->flags |= FTRACE_FL_FAILED;
1114 return 0; 1090 return 0;
1115 } 1091 }
1116 return 1; 1092 return 1;
@@ -1273,10 +1249,10 @@ static int ftrace_update_code(struct module *mod)
1273 */ 1249 */
1274 if (!ftrace_code_disable(mod, p)) { 1250 if (!ftrace_code_disable(mod, p)) {
1275 ftrace_free_rec(p); 1251 ftrace_free_rec(p);
1276 continue; 1252 /* Game over */
1253 break;
1277 } 1254 }
1278 1255
1279 p->flags |= FTRACE_FL_CONVERTED;
1280 ftrace_update_cnt++; 1256 ftrace_update_cnt++;
1281 1257
1282 /* 1258 /*
@@ -1351,9 +1327,8 @@ static int __init ftrace_dyn_table_alloc(unsigned long num_to_init)
1351enum { 1327enum {
1352 FTRACE_ITER_FILTER = (1 << 0), 1328 FTRACE_ITER_FILTER = (1 << 0),
1353 FTRACE_ITER_NOTRACE = (1 << 1), 1329 FTRACE_ITER_NOTRACE = (1 << 1),
1354 FTRACE_ITER_FAILURES = (1 << 2), 1330 FTRACE_ITER_PRINTALL = (1 << 2),
1355 FTRACE_ITER_PRINTALL = (1 << 3), 1331 FTRACE_ITER_HASH = (1 << 3),
1356 FTRACE_ITER_HASH = (1 << 4),
1357}; 1332};
1358 1333
1359#define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */ 1334#define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */
@@ -1463,6 +1438,9 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
1463 struct ftrace_iterator *iter = m->private; 1438 struct ftrace_iterator *iter = m->private;
1464 struct dyn_ftrace *rec = NULL; 1439 struct dyn_ftrace *rec = NULL;
1465 1440
1441 if (unlikely(ftrace_disabled))
1442 return NULL;
1443
1466 if (iter->flags & FTRACE_ITER_HASH) 1444 if (iter->flags & FTRACE_ITER_HASH)
1467 return t_hash_next(m, pos); 1445 return t_hash_next(m, pos);
1468 1446
@@ -1483,12 +1461,6 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
1483 rec = &iter->pg->records[iter->idx++]; 1461 rec = &iter->pg->records[iter->idx++];
1484 if ((rec->flags & FTRACE_FL_FREE) || 1462 if ((rec->flags & FTRACE_FL_FREE) ||
1485 1463
1486 (!(iter->flags & FTRACE_ITER_FAILURES) &&
1487 (rec->flags & FTRACE_FL_FAILED)) ||
1488
1489 ((iter->flags & FTRACE_ITER_FAILURES) &&
1490 !(rec->flags & FTRACE_FL_FAILED)) ||
1491
1492 ((iter->flags & FTRACE_ITER_FILTER) && 1464 ((iter->flags & FTRACE_ITER_FILTER) &&
1493 !(rec->flags & FTRACE_FL_FILTER)) || 1465 !(rec->flags & FTRACE_FL_FILTER)) ||
1494 1466
@@ -1521,6 +1493,10 @@ static void *t_start(struct seq_file *m, loff_t *pos)
1521 loff_t l; 1493 loff_t l;
1522 1494
1523 mutex_lock(&ftrace_lock); 1495 mutex_lock(&ftrace_lock);
1496
1497 if (unlikely(ftrace_disabled))
1498 return NULL;
1499
1524 /* 1500 /*
1525 * If an lseek was done, then reset and start from beginning. 1501 * If an lseek was done, then reset and start from beginning.
1526 */ 1502 */
@@ -1629,24 +1605,6 @@ ftrace_avail_open(struct inode *inode, struct file *file)
1629 return ret; 1605 return ret;
1630} 1606}
1631 1607
1632static int
1633ftrace_failures_open(struct inode *inode, struct file *file)
1634{
1635 int ret;
1636 struct seq_file *m;
1637 struct ftrace_iterator *iter;
1638
1639 ret = ftrace_avail_open(inode, file);
1640 if (!ret) {
1641 m = file->private_data;
1642 iter = m->private;
1643 iter->flags = FTRACE_ITER_FAILURES;
1644 }
1645
1646 return ret;
1647}
1648
1649
1650static void ftrace_filter_reset(int enable) 1608static void ftrace_filter_reset(int enable)
1651{ 1609{
1652 struct ftrace_page *pg; 1610 struct ftrace_page *pg;
@@ -1657,8 +1615,6 @@ static void ftrace_filter_reset(int enable)
1657 if (enable) 1615 if (enable)
1658 ftrace_filtered = 0; 1616 ftrace_filtered = 0;
1659 do_for_each_ftrace_rec(pg, rec) { 1617 do_for_each_ftrace_rec(pg, rec) {
1660 if (rec->flags & FTRACE_FL_FAILED)
1661 continue;
1662 rec->flags &= ~type; 1618 rec->flags &= ~type;
1663 } while_for_each_ftrace_rec(); 1619 } while_for_each_ftrace_rec();
1664 mutex_unlock(&ftrace_lock); 1620 mutex_unlock(&ftrace_lock);
@@ -1760,42 +1716,63 @@ static int ftrace_match(char *str, char *regex, int len, int type)
1760 return matched; 1716 return matched;
1761} 1717}
1762 1718
1719static void
1720update_record(struct dyn_ftrace *rec, unsigned long flag, int not)
1721{
1722 if (not)
1723 rec->flags &= ~flag;
1724 else
1725 rec->flags |= flag;
1726}
1727
1763static int 1728static int
1764ftrace_match_record(struct dyn_ftrace *rec, char *regex, int len, int type) 1729ftrace_match_record(struct dyn_ftrace *rec, char *mod,
1730 char *regex, int len, int type)
1765{ 1731{
1766 char str[KSYM_SYMBOL_LEN]; 1732 char str[KSYM_SYMBOL_LEN];
1733 char *modname;
1734
1735 kallsyms_lookup(rec->ip, NULL, NULL, &modname, str);
1736
1737 if (mod) {
1738 /* module lookup requires matching the module */
1739 if (!modname || strcmp(modname, mod))
1740 return 0;
1741
1742 /* blank search means to match all funcs in the mod */
1743 if (!len)
1744 return 1;
1745 }
1767 1746
1768 kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
1769 return ftrace_match(str, regex, len, type); 1747 return ftrace_match(str, regex, len, type);
1770} 1748}
1771 1749
1772static int ftrace_match_records(char *buff, int len, int enable) 1750static int match_records(char *buff, int len, char *mod, int enable, int not)
1773{ 1751{
1774 unsigned int search_len; 1752 unsigned search_len = 0;
1775 struct ftrace_page *pg; 1753 struct ftrace_page *pg;
1776 struct dyn_ftrace *rec; 1754 struct dyn_ftrace *rec;
1755 int type = MATCH_FULL;
1756 char *search = buff;
1777 unsigned long flag; 1757 unsigned long flag;
1778 char *search;
1779 int type;
1780 int not;
1781 int found = 0; 1758 int found = 0;
1782 1759
1783 flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE; 1760 if (len) {
1784 type = filter_parse_regex(buff, len, &search, &not); 1761 type = filter_parse_regex(buff, len, &search, &not);
1762 search_len = strlen(search);
1763 }
1785 1764
1786 search_len = strlen(search); 1765 flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
1787 1766
1788 mutex_lock(&ftrace_lock); 1767 mutex_lock(&ftrace_lock);
1789 do_for_each_ftrace_rec(pg, rec) {
1790 1768
1791 if (rec->flags & FTRACE_FL_FAILED) 1769 if (unlikely(ftrace_disabled))
1792 continue; 1770 goto out_unlock;
1793 1771
1794 if (ftrace_match_record(rec, search, search_len, type)) { 1772 do_for_each_ftrace_rec(pg, rec) {
1795 if (not) 1773
1796 rec->flags &= ~flag; 1774 if (ftrace_match_record(rec, mod, search, search_len, type)) {
1797 else 1775 update_record(rec, flag, not);
1798 rec->flags |= flag;
1799 found = 1; 1776 found = 1;
1800 } 1777 }
1801 /* 1778 /*
@@ -1804,43 +1781,23 @@ static int ftrace_match_records(char *buff, int len, int enable)
1804 */ 1781 */
1805 if (enable && (rec->flags & FTRACE_FL_FILTER)) 1782 if (enable && (rec->flags & FTRACE_FL_FILTER))
1806 ftrace_filtered = 1; 1783 ftrace_filtered = 1;
1784
1807 } while_for_each_ftrace_rec(); 1785 } while_for_each_ftrace_rec();
1786 out_unlock:
1808 mutex_unlock(&ftrace_lock); 1787 mutex_unlock(&ftrace_lock);
1809 1788
1810 return found; 1789 return found;
1811} 1790}
1812 1791
1813static int 1792static int
1814ftrace_match_module_record(struct dyn_ftrace *rec, char *mod, 1793ftrace_match_records(char *buff, int len, int enable)
1815 char *regex, int len, int type)
1816{ 1794{
1817 char str[KSYM_SYMBOL_LEN]; 1795 return match_records(buff, len, NULL, enable, 0);
1818 char *modname;
1819
1820 kallsyms_lookup(rec->ip, NULL, NULL, &modname, str);
1821
1822 if (!modname || strcmp(modname, mod))
1823 return 0;
1824
1825 /* blank search means to match all funcs in the mod */
1826 if (len)
1827 return ftrace_match(str, regex, len, type);
1828 else
1829 return 1;
1830} 1796}
1831 1797
1832static int ftrace_match_module_records(char *buff, char *mod, int enable) 1798static int ftrace_match_module_records(char *buff, char *mod, int enable)
1833{ 1799{
1834 unsigned search_len = 0;
1835 struct ftrace_page *pg;
1836 struct dyn_ftrace *rec;
1837 int type = MATCH_FULL;
1838 char *search = buff;
1839 unsigned long flag;
1840 int not = 0; 1800 int not = 0;
1841 int found = 0;
1842
1843 flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
1844 1801
1845 /* blank or '*' mean the same */ 1802 /* blank or '*' mean the same */
1846 if (strcmp(buff, "*") == 0) 1803 if (strcmp(buff, "*") == 0)
@@ -1852,32 +1809,7 @@ static int ftrace_match_module_records(char *buff, char *mod, int enable)
1852 not = 1; 1809 not = 1;
1853 } 1810 }
1854 1811
1855 if (strlen(buff)) { 1812 return match_records(buff, strlen(buff), mod, enable, not);
1856 type = filter_parse_regex(buff, strlen(buff), &search, &not);
1857 search_len = strlen(search);
1858 }
1859
1860 mutex_lock(&ftrace_lock);
1861 do_for_each_ftrace_rec(pg, rec) {
1862
1863 if (rec->flags & FTRACE_FL_FAILED)
1864 continue;
1865
1866 if (ftrace_match_module_record(rec, mod,
1867 search, search_len, type)) {
1868 if (not)
1869 rec->flags &= ~flag;
1870 else
1871 rec->flags |= flag;
1872 found = 1;
1873 }
1874 if (enable && (rec->flags & FTRACE_FL_FILTER))
1875 ftrace_filtered = 1;
1876
1877 } while_for_each_ftrace_rec();
1878 mutex_unlock(&ftrace_lock);
1879
1880 return found;
1881} 1813}
1882 1814
1883/* 1815/*
@@ -2029,12 +1961,13 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
2029 return -EINVAL; 1961 return -EINVAL;
2030 1962
2031 mutex_lock(&ftrace_lock); 1963 mutex_lock(&ftrace_lock);
2032 do_for_each_ftrace_rec(pg, rec) {
2033 1964
2034 if (rec->flags & FTRACE_FL_FAILED) 1965 if (unlikely(ftrace_disabled))
2035 continue; 1966 goto out_unlock;
2036 1967
2037 if (!ftrace_match_record(rec, search, len, type)) 1968 do_for_each_ftrace_rec(pg, rec) {
1969
1970 if (!ftrace_match_record(rec, NULL, search, len, type))
2038 continue; 1971 continue;
2039 1972
2040 entry = kmalloc(sizeof(*entry), GFP_KERNEL); 1973 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
@@ -2239,6 +2172,10 @@ ftrace_regex_write(struct file *file, const char __user *ubuf,
2239 2172
2240 mutex_lock(&ftrace_regex_lock); 2173 mutex_lock(&ftrace_regex_lock);
2241 2174
2175 ret = -ENODEV;
2176 if (unlikely(ftrace_disabled))
2177 goto out_unlock;
2178
2242 if (file->f_mode & FMODE_READ) { 2179 if (file->f_mode & FMODE_READ) {
2243 struct seq_file *m = file->private_data; 2180 struct seq_file *m = file->private_data;
2244 iter = m->private; 2181 iter = m->private;
@@ -2446,13 +2383,6 @@ static const struct file_operations ftrace_avail_fops = {
2446 .release = seq_release_private, 2383 .release = seq_release_private,
2447}; 2384};
2448 2385
2449static const struct file_operations ftrace_failures_fops = {
2450 .open = ftrace_failures_open,
2451 .read = seq_read,
2452 .llseek = seq_lseek,
2453 .release = seq_release_private,
2454};
2455
2456static const struct file_operations ftrace_filter_fops = { 2386static const struct file_operations ftrace_filter_fops = {
2457 .open = ftrace_filter_open, 2387 .open = ftrace_filter_open,
2458 .read = seq_read, 2388 .read = seq_read,
@@ -2575,9 +2505,6 @@ ftrace_set_func(unsigned long *array, int *idx, char *buffer)
2575 bool exists; 2505 bool exists;
2576 int i; 2506 int i;
2577 2507
2578 if (ftrace_disabled)
2579 return -ENODEV;
2580
2581 /* decode regex */ 2508 /* decode regex */
2582 type = filter_parse_regex(buffer, strlen(buffer), &search, &not); 2509 type = filter_parse_regex(buffer, strlen(buffer), &search, &not);
2583 if (!not && *idx >= FTRACE_GRAPH_MAX_FUNCS) 2510 if (!not && *idx >= FTRACE_GRAPH_MAX_FUNCS)
@@ -2586,12 +2513,18 @@ ftrace_set_func(unsigned long *array, int *idx, char *buffer)
2586 search_len = strlen(search); 2513 search_len = strlen(search);
2587 2514
2588 mutex_lock(&ftrace_lock); 2515 mutex_lock(&ftrace_lock);
2516
2517 if (unlikely(ftrace_disabled)) {
2518 mutex_unlock(&ftrace_lock);
2519 return -ENODEV;
2520 }
2521
2589 do_for_each_ftrace_rec(pg, rec) { 2522 do_for_each_ftrace_rec(pg, rec) {
2590 2523
2591 if (rec->flags & (FTRACE_FL_FAILED | FTRACE_FL_FREE)) 2524 if (rec->flags & FTRACE_FL_FREE)
2592 continue; 2525 continue;
2593 2526
2594 if (ftrace_match_record(rec, search, search_len, type)) { 2527 if (ftrace_match_record(rec, NULL, search, search_len, type)) {
2595 /* if it is in the array */ 2528 /* if it is in the array */
2596 exists = false; 2529 exists = false;
2597 for (i = 0; i < *idx; i++) { 2530 for (i = 0; i < *idx; i++) {
@@ -2681,9 +2614,6 @@ static __init int ftrace_init_dyn_debugfs(struct dentry *d_tracer)
2681 trace_create_file("available_filter_functions", 0444, 2614 trace_create_file("available_filter_functions", 0444,
2682 d_tracer, NULL, &ftrace_avail_fops); 2615 d_tracer, NULL, &ftrace_avail_fops);
2683 2616
2684 trace_create_file("failures", 0444,
2685 d_tracer, NULL, &ftrace_failures_fops);
2686
2687 trace_create_file("set_ftrace_filter", 0644, d_tracer, 2617 trace_create_file("set_ftrace_filter", 0644, d_tracer,
2688 NULL, &ftrace_filter_fops); 2618 NULL, &ftrace_filter_fops);
2689 2619
@@ -2705,7 +2635,6 @@ static int ftrace_process_locs(struct module *mod,
2705{ 2635{
2706 unsigned long *p; 2636 unsigned long *p;
2707 unsigned long addr; 2637 unsigned long addr;
2708 unsigned long flags;
2709 2638
2710 mutex_lock(&ftrace_lock); 2639 mutex_lock(&ftrace_lock);
2711 p = start; 2640 p = start;
@@ -2722,10 +2651,7 @@ static int ftrace_process_locs(struct module *mod,
2722 ftrace_record_ip(addr); 2651 ftrace_record_ip(addr);
2723 } 2652 }
2724 2653
2725 /* disable interrupts to prevent kstop machine */
2726 local_irq_save(flags);
2727 ftrace_update_code(mod); 2654 ftrace_update_code(mod);
2728 local_irq_restore(flags);
2729 mutex_unlock(&ftrace_lock); 2655 mutex_unlock(&ftrace_lock);
2730 2656
2731 return 0; 2657 return 0;
@@ -2737,10 +2663,11 @@ void ftrace_release_mod(struct module *mod)
2737 struct dyn_ftrace *rec; 2663 struct dyn_ftrace *rec;
2738 struct ftrace_page *pg; 2664 struct ftrace_page *pg;
2739 2665
2666 mutex_lock(&ftrace_lock);
2667
2740 if (ftrace_disabled) 2668 if (ftrace_disabled)
2741 return; 2669 goto out_unlock;
2742 2670
2743 mutex_lock(&ftrace_lock);
2744 do_for_each_ftrace_rec(pg, rec) { 2671 do_for_each_ftrace_rec(pg, rec) {
2745 if (within_module_core(rec->ip, mod)) { 2672 if (within_module_core(rec->ip, mod)) {
2746 /* 2673 /*
@@ -2751,6 +2678,7 @@ void ftrace_release_mod(struct module *mod)
2751 ftrace_free_rec(rec); 2678 ftrace_free_rec(rec);
2752 } 2679 }
2753 } while_for_each_ftrace_rec(); 2680 } while_for_each_ftrace_rec();
2681 out_unlock:
2754 mutex_unlock(&ftrace_lock); 2682 mutex_unlock(&ftrace_lock);
2755} 2683}
2756 2684
@@ -3145,16 +3073,17 @@ void ftrace_kill(void)
3145 */ 3073 */
3146int register_ftrace_function(struct ftrace_ops *ops) 3074int register_ftrace_function(struct ftrace_ops *ops)
3147{ 3075{
3148 int ret; 3076 int ret = -1;
3149
3150 if (unlikely(ftrace_disabled))
3151 return -1;
3152 3077
3153 mutex_lock(&ftrace_lock); 3078 mutex_lock(&ftrace_lock);
3154 3079
3080 if (unlikely(ftrace_disabled))
3081 goto out_unlock;
3082
3155 ret = __register_ftrace_function(ops); 3083 ret = __register_ftrace_function(ops);
3156 ftrace_startup(0); 3084 ftrace_startup(0);
3157 3085
3086 out_unlock:
3158 mutex_unlock(&ftrace_lock); 3087 mutex_unlock(&ftrace_lock);
3159 return ret; 3088 return ret;
3160} 3089}
@@ -3182,14 +3111,14 @@ ftrace_enable_sysctl(struct ctl_table *table, int write,
3182 void __user *buffer, size_t *lenp, 3111 void __user *buffer, size_t *lenp,
3183 loff_t *ppos) 3112 loff_t *ppos)
3184{ 3113{
3185 int ret; 3114 int ret = -ENODEV;
3186
3187 if (unlikely(ftrace_disabled))
3188 return -ENODEV;
3189 3115
3190 mutex_lock(&ftrace_lock); 3116 mutex_lock(&ftrace_lock);
3191 3117
3192 ret = proc_dointvec(table, write, buffer, lenp, ppos); 3118 if (unlikely(ftrace_disabled))
3119 goto out;
3120
3121 ret = proc_dointvec(table, write, buffer, lenp, ppos);
3193 3122
3194 if (ret || !write || (last_ftrace_enabled == !!ftrace_enabled)) 3123 if (ret || !write || (last_ftrace_enabled == !!ftrace_enabled))
3195 goto out; 3124 goto out;