aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/ftrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r--kernel/trace/ftrace.c98
1 files changed, 36 insertions, 62 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 33bcc71ca09..4f19dbba12f 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1726,34 +1726,52 @@ update_record(struct dyn_ftrace *rec, unsigned long flag, int not)
1726} 1726}
1727 1727
1728static int 1728static int
1729ftrace_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)
1730{ 1731{
1731 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 }
1732 1746
1733 kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
1734 return ftrace_match(str, regex, len, type); 1747 return ftrace_match(str, regex, len, type);
1735} 1748}
1736 1749
1737static int ftrace_match_records(char *buff, int len, int enable) 1750static int match_records(char *buff, int len, char *mod, int enable, int not)
1738{ 1751{
1739 unsigned int search_len; 1752 unsigned search_len = 0;
1740 struct ftrace_page *pg; 1753 struct ftrace_page *pg;
1741 struct dyn_ftrace *rec; 1754 struct dyn_ftrace *rec;
1755 int type = MATCH_FULL;
1756 char *search = buff;
1742 unsigned long flag; 1757 unsigned long flag;
1743 char *search;
1744 int type;
1745 int not;
1746 int found = 0; 1758 int found = 0;
1747 1759
1748 flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE; 1760 if (len) {
1749 type = filter_parse_regex(buff, len, &search, &not); 1761 type = filter_parse_regex(buff, len, &search, &not);
1762 search_len = strlen(search);
1763 }
1750 1764
1751 search_len = strlen(search); 1765 flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
1752 1766
1753 mutex_lock(&ftrace_lock); 1767 mutex_lock(&ftrace_lock);
1768
1769 if (unlikely(ftrace_disabled))
1770 goto out_unlock;
1771
1754 do_for_each_ftrace_rec(pg, rec) { 1772 do_for_each_ftrace_rec(pg, rec) {
1755 1773
1756 if (ftrace_match_record(rec, search, search_len, type)) { 1774 if (ftrace_match_record(rec, mod, search, search_len, type)) {
1757 update_record(rec, flag, not); 1775 update_record(rec, flag, not);
1758 found = 1; 1776 found = 1;
1759 } 1777 }
@@ -1763,43 +1781,23 @@ static int ftrace_match_records(char *buff, int len, int enable)
1763 */ 1781 */
1764 if (enable && (rec->flags & FTRACE_FL_FILTER)) 1782 if (enable && (rec->flags & FTRACE_FL_FILTER))
1765 ftrace_filtered = 1; 1783 ftrace_filtered = 1;
1784
1766 } while_for_each_ftrace_rec(); 1785 } while_for_each_ftrace_rec();
1786 out_unlock:
1767 mutex_unlock(&ftrace_lock); 1787 mutex_unlock(&ftrace_lock);
1768 1788
1769 return found; 1789 return found;
1770} 1790}
1771 1791
1772static int 1792static int
1773ftrace_match_module_record(struct dyn_ftrace *rec, char *mod, 1793ftrace_match_records(char *buff, int len, int enable)
1774 char *regex, int len, int type)
1775{ 1794{
1776 char str[KSYM_SYMBOL_LEN]; 1795 return match_records(buff, len, NULL, enable, 0);
1777 char *modname;
1778
1779 kallsyms_lookup(rec->ip, NULL, NULL, &modname, str);
1780
1781 if (!modname || strcmp(modname, mod))
1782 return 0;
1783
1784 /* blank search means to match all funcs in the mod */
1785 if (len)
1786 return ftrace_match(str, regex, len, type);
1787 else
1788 return 1;
1789} 1796}
1790 1797
1791static int ftrace_match_module_records(char *buff, char *mod, int enable) 1798static int ftrace_match_module_records(char *buff, char *mod, int enable)
1792{ 1799{
1793 unsigned search_len = 0;
1794 struct ftrace_page *pg;
1795 struct dyn_ftrace *rec;
1796 int type = MATCH_FULL;
1797 char *search = buff;
1798 unsigned long flag;
1799 int not = 0; 1800 int not = 0;
1800 int found = 0;
1801
1802 flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
1803 1801
1804 /* blank or '*' mean the same */ 1802 /* blank or '*' mean the same */
1805 if (strcmp(buff, "*") == 0) 1803 if (strcmp(buff, "*") == 0)
@@ -1811,31 +1809,7 @@ static int ftrace_match_module_records(char *buff, char *mod, int enable)
1811 not = 1; 1809 not = 1;
1812 } 1810 }
1813 1811
1814 if (strlen(buff)) { 1812 return match_records(buff, strlen(buff), mod, enable, not);
1815 type = filter_parse_regex(buff, strlen(buff), &search, &not);
1816 search_len = strlen(search);
1817 }
1818
1819 mutex_lock(&ftrace_lock);
1820
1821 if (unlikely(ftrace_disabled))
1822 goto out_unlock;
1823
1824 do_for_each_ftrace_rec(pg, rec) {
1825
1826 if (ftrace_match_module_record(rec, mod,
1827 search, search_len, type)) {
1828 update_record(rec, flag, not);
1829 found = 1;
1830 }
1831 if (enable && (rec->flags & FTRACE_FL_FILTER))
1832 ftrace_filtered = 1;
1833
1834 } while_for_each_ftrace_rec();
1835 out_unlock:
1836 mutex_unlock(&ftrace_lock);
1837
1838 return found;
1839} 1813}
1840 1814
1841/* 1815/*
@@ -1993,7 +1967,7 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
1993 1967
1994 do_for_each_ftrace_rec(pg, rec) { 1968 do_for_each_ftrace_rec(pg, rec) {
1995 1969
1996 if (!ftrace_match_record(rec, search, len, type)) 1970 if (!ftrace_match_record(rec, NULL, search, len, type))
1997 continue; 1971 continue;
1998 1972
1999 entry = kmalloc(sizeof(*entry), GFP_KERNEL); 1973 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
@@ -2548,7 +2522,7 @@ ftrace_set_func(unsigned long *array, int *idx, char *buffer)
2548 if (rec->flags & FTRACE_FL_FREE) 2522 if (rec->flags & FTRACE_FL_FREE)
2549 continue; 2523 continue;
2550 2524
2551 if (ftrace_match_record(rec, search, search_len, type)) { 2525 if (ftrace_match_record(rec, NULL, search, search_len, type)) {
2552 /* if it is in the array */ 2526 /* if it is in the array */
2553 exists = false; 2527 exists = false;
2554 for (i = 0; i < *idx; i++) { 2528 for (i = 0; i < *idx; i++) {