diff options
-rw-r--r-- | include/linux/ftrace_event.h | 3 | ||||
-rw-r--r-- | kernel/trace/trace_events.c | 4 | ||||
-rw-r--r-- | kernel/trace/trace_events_filter.c | 73 | ||||
-rw-r--r-- | kernel/trace/trace_uprobe.c | 3 |
4 files changed, 19 insertions, 64 deletions
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index cff3106ffe2c..06c6faa9e5cc 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h | |||
@@ -272,7 +272,6 @@ struct ftrace_event_call { | |||
272 | struct trace_event event; | 272 | struct trace_event event; |
273 | const char *print_fmt; | 273 | const char *print_fmt; |
274 | struct event_filter *filter; | 274 | struct event_filter *filter; |
275 | struct list_head *files; | ||
276 | void *mod; | 275 | void *mod; |
277 | void *data; | 276 | void *data; |
278 | /* | 277 | /* |
@@ -404,8 +403,6 @@ enum event_trigger_type { | |||
404 | ETT_EVENT_ENABLE = (1 << 3), | 403 | ETT_EVENT_ENABLE = (1 << 3), |
405 | }; | 404 | }; |
406 | 405 | ||
407 | extern void destroy_preds(struct ftrace_event_file *file); | ||
408 | extern void destroy_call_preds(struct ftrace_event_call *call); | ||
409 | extern int filter_match_preds(struct event_filter *filter, void *rec); | 406 | extern int filter_match_preds(struct event_filter *filter, void *rec); |
410 | 407 | ||
411 | extern int filter_check_discard(struct ftrace_event_file *file, void *rec, | 408 | extern int filter_check_discard(struct ftrace_event_file *file, void *rec, |
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 3154eb39241d..ef06ce7e9cf8 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
@@ -1621,7 +1621,6 @@ static void event_remove(struct ftrace_event_call *call) | |||
1621 | if (file->event_call != call) | 1621 | if (file->event_call != call) |
1622 | continue; | 1622 | continue; |
1623 | ftrace_event_enable_disable(file, 0); | 1623 | ftrace_event_enable_disable(file, 0); |
1624 | destroy_preds(file); | ||
1625 | /* | 1624 | /* |
1626 | * The do_for_each_event_file() is | 1625 | * The do_for_each_event_file() is |
1627 | * a double loop. After finding the call for this | 1626 | * a double loop. After finding the call for this |
@@ -1748,7 +1747,8 @@ static void __trace_remove_event_call(struct ftrace_event_call *call) | |||
1748 | { | 1747 | { |
1749 | event_remove(call); | 1748 | event_remove(call); |
1750 | trace_destroy_fields(call); | 1749 | trace_destroy_fields(call); |
1751 | destroy_call_preds(call); | 1750 | free_event_filter(call->filter); |
1751 | call->filter = NULL; | ||
1752 | } | 1752 | } |
1753 | 1753 | ||
1754 | static int probe_remove_event_call(struct ftrace_event_call *call) | 1754 | static int probe_remove_event_call(struct ftrace_event_call *call) |
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 8a8631926a07..7a8c1528e141 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c | |||
@@ -774,17 +774,12 @@ static void __free_preds(struct event_filter *filter) | |||
774 | filter->n_preds = 0; | 774 | filter->n_preds = 0; |
775 | } | 775 | } |
776 | 776 | ||
777 | static void call_filter_disable(struct ftrace_event_call *call) | ||
778 | { | ||
779 | call->flags &= ~TRACE_EVENT_FL_FILTERED; | ||
780 | } | ||
781 | |||
782 | static void filter_disable(struct ftrace_event_file *file) | 777 | static void filter_disable(struct ftrace_event_file *file) |
783 | { | 778 | { |
784 | struct ftrace_event_call *call = file->event_call; | 779 | struct ftrace_event_call *call = file->event_call; |
785 | 780 | ||
786 | if (call->flags & TRACE_EVENT_FL_USE_CALL_FILTER) | 781 | if (call->flags & TRACE_EVENT_FL_USE_CALL_FILTER) |
787 | call_filter_disable(call); | 782 | call->flags &= ~TRACE_EVENT_FL_FILTERED; |
788 | else | 783 | else |
789 | file->flags &= ~FTRACE_EVENT_FL_FILTERED; | 784 | file->flags &= ~FTRACE_EVENT_FL_FILTERED; |
790 | } | 785 | } |
@@ -804,32 +799,6 @@ void free_event_filter(struct event_filter *filter) | |||
804 | __free_filter(filter); | 799 | __free_filter(filter); |
805 | } | 800 | } |
806 | 801 | ||
807 | void destroy_call_preds(struct ftrace_event_call *call) | ||
808 | { | ||
809 | __free_filter(call->filter); | ||
810 | call->filter = NULL; | ||
811 | } | ||
812 | |||
813 | static void destroy_file_preds(struct ftrace_event_file *file) | ||
814 | { | ||
815 | __free_filter(file->filter); | ||
816 | file->filter = NULL; | ||
817 | } | ||
818 | |||
819 | /* | ||
820 | * Called when destroying the ftrace_event_file. | ||
821 | * The file is being freed, so we do not need to worry about | ||
822 | * the file being currently used. This is for module code removing | ||
823 | * the tracepoints from within it. | ||
824 | */ | ||
825 | void destroy_preds(struct ftrace_event_file *file) | ||
826 | { | ||
827 | if (file->event_call->flags & TRACE_EVENT_FL_USE_CALL_FILTER) | ||
828 | destroy_call_preds(file->event_call); | ||
829 | else | ||
830 | destroy_file_preds(file); | ||
831 | } | ||
832 | |||
833 | static struct event_filter *__alloc_filter(void) | 802 | static struct event_filter *__alloc_filter(void) |
834 | { | 803 | { |
835 | struct event_filter *filter; | 804 | struct event_filter *filter; |
@@ -873,17 +842,14 @@ static inline void __remove_filter(struct ftrace_event_file *file) | |||
873 | remove_filter_string(file->filter); | 842 | remove_filter_string(file->filter); |
874 | } | 843 | } |
875 | 844 | ||
876 | static void filter_free_subsystem_preds(struct event_subsystem *system, | 845 | static void filter_free_subsystem_preds(struct ftrace_subsystem_dir *dir, |
877 | struct trace_array *tr) | 846 | struct trace_array *tr) |
878 | { | 847 | { |
879 | struct ftrace_event_file *file; | 848 | struct ftrace_event_file *file; |
880 | struct ftrace_event_call *call; | ||
881 | 849 | ||
882 | list_for_each_entry(file, &tr->events, list) { | 850 | list_for_each_entry(file, &tr->events, list) { |
883 | call = file->event_call; | 851 | if (file->system != dir) |
884 | if (strcmp(call->class->system, system->name) != 0) | ||
885 | continue; | 852 | continue; |
886 | |||
887 | __remove_filter(file); | 853 | __remove_filter(file); |
888 | } | 854 | } |
889 | } | 855 | } |
@@ -901,15 +867,13 @@ static inline void __free_subsystem_filter(struct ftrace_event_file *file) | |||
901 | } | 867 | } |
902 | } | 868 | } |
903 | 869 | ||
904 | static void filter_free_subsystem_filters(struct event_subsystem *system, | 870 | static void filter_free_subsystem_filters(struct ftrace_subsystem_dir *dir, |
905 | struct trace_array *tr) | 871 | struct trace_array *tr) |
906 | { | 872 | { |
907 | struct ftrace_event_file *file; | 873 | struct ftrace_event_file *file; |
908 | struct ftrace_event_call *call; | ||
909 | 874 | ||
910 | list_for_each_entry(file, &tr->events, list) { | 875 | list_for_each_entry(file, &tr->events, list) { |
911 | call = file->event_call; | 876 | if (file->system != dir) |
912 | if (strcmp(call->class->system, system->name) != 0) | ||
913 | continue; | 877 | continue; |
914 | __free_subsystem_filter(file); | 878 | __free_subsystem_filter(file); |
915 | } | 879 | } |
@@ -1582,7 +1546,6 @@ static int fold_pred_tree(struct event_filter *filter, | |||
1582 | static int replace_preds(struct ftrace_event_call *call, | 1546 | static int replace_preds(struct ftrace_event_call *call, |
1583 | struct event_filter *filter, | 1547 | struct event_filter *filter, |
1584 | struct filter_parse_state *ps, | 1548 | struct filter_parse_state *ps, |
1585 | char *filter_string, | ||
1586 | bool dry_run) | 1549 | bool dry_run) |
1587 | { | 1550 | { |
1588 | char *operand1 = NULL, *operand2 = NULL; | 1551 | char *operand1 = NULL, *operand2 = NULL; |
@@ -1755,13 +1718,12 @@ struct filter_list { | |||
1755 | struct event_filter *filter; | 1718 | struct event_filter *filter; |
1756 | }; | 1719 | }; |
1757 | 1720 | ||
1758 | static int replace_system_preds(struct event_subsystem *system, | 1721 | static int replace_system_preds(struct ftrace_subsystem_dir *dir, |
1759 | struct trace_array *tr, | 1722 | struct trace_array *tr, |
1760 | struct filter_parse_state *ps, | 1723 | struct filter_parse_state *ps, |
1761 | char *filter_string) | 1724 | char *filter_string) |
1762 | { | 1725 | { |
1763 | struct ftrace_event_file *file; | 1726 | struct ftrace_event_file *file; |
1764 | struct ftrace_event_call *call; | ||
1765 | struct filter_list *filter_item; | 1727 | struct filter_list *filter_item; |
1766 | struct filter_list *tmp; | 1728 | struct filter_list *tmp; |
1767 | LIST_HEAD(filter_list); | 1729 | LIST_HEAD(filter_list); |
@@ -1769,15 +1731,14 @@ static int replace_system_preds(struct event_subsystem *system, | |||
1769 | int err; | 1731 | int err; |
1770 | 1732 | ||
1771 | list_for_each_entry(file, &tr->events, list) { | 1733 | list_for_each_entry(file, &tr->events, list) { |
1772 | call = file->event_call; | 1734 | if (file->system != dir) |
1773 | if (strcmp(call->class->system, system->name) != 0) | ||
1774 | continue; | 1735 | continue; |
1775 | 1736 | ||
1776 | /* | 1737 | /* |
1777 | * Try to see if the filter can be applied | 1738 | * Try to see if the filter can be applied |
1778 | * (filter arg is ignored on dry_run) | 1739 | * (filter arg is ignored on dry_run) |
1779 | */ | 1740 | */ |
1780 | err = replace_preds(call, NULL, ps, filter_string, true); | 1741 | err = replace_preds(file->event_call, NULL, ps, true); |
1781 | if (err) | 1742 | if (err) |
1782 | event_set_no_set_filter_flag(file); | 1743 | event_set_no_set_filter_flag(file); |
1783 | else | 1744 | else |
@@ -1787,9 +1748,7 @@ static int replace_system_preds(struct event_subsystem *system, | |||
1787 | list_for_each_entry(file, &tr->events, list) { | 1748 | list_for_each_entry(file, &tr->events, list) { |
1788 | struct event_filter *filter; | 1749 | struct event_filter *filter; |
1789 | 1750 | ||
1790 | call = file->event_call; | 1751 | if (file->system != dir) |
1791 | |||
1792 | if (strcmp(call->class->system, system->name) != 0) | ||
1793 | continue; | 1752 | continue; |
1794 | 1753 | ||
1795 | if (event_no_set_filter_flag(file)) | 1754 | if (event_no_set_filter_flag(file)) |
@@ -1811,7 +1770,7 @@ static int replace_system_preds(struct event_subsystem *system, | |||
1811 | if (err) | 1770 | if (err) |
1812 | goto fail_mem; | 1771 | goto fail_mem; |
1813 | 1772 | ||
1814 | err = replace_preds(call, filter, ps, filter_string, false); | 1773 | err = replace_preds(file->event_call, filter, ps, false); |
1815 | if (err) { | 1774 | if (err) { |
1816 | filter_disable(file); | 1775 | filter_disable(file); |
1817 | parse_error(ps, FILT_ERR_BAD_SUBSYS_FILTER, 0); | 1776 | parse_error(ps, FILT_ERR_BAD_SUBSYS_FILTER, 0); |
@@ -1933,7 +1892,7 @@ static int create_filter(struct ftrace_event_call *call, | |||
1933 | 1892 | ||
1934 | err = create_filter_start(filter_str, set_str, &ps, &filter); | 1893 | err = create_filter_start(filter_str, set_str, &ps, &filter); |
1935 | if (!err) { | 1894 | if (!err) { |
1936 | err = replace_preds(call, filter, ps, filter_str, false); | 1895 | err = replace_preds(call, filter, ps, false); |
1937 | if (err && set_str) | 1896 | if (err && set_str) |
1938 | append_filter_err(ps, filter); | 1897 | append_filter_err(ps, filter); |
1939 | } | 1898 | } |
@@ -1959,7 +1918,7 @@ int create_event_filter(struct ftrace_event_call *call, | |||
1959 | * Identical to create_filter() except that it creates a subsystem filter | 1918 | * Identical to create_filter() except that it creates a subsystem filter |
1960 | * and always remembers @filter_str. | 1919 | * and always remembers @filter_str. |
1961 | */ | 1920 | */ |
1962 | static int create_system_filter(struct event_subsystem *system, | 1921 | static int create_system_filter(struct ftrace_subsystem_dir *dir, |
1963 | struct trace_array *tr, | 1922 | struct trace_array *tr, |
1964 | char *filter_str, struct event_filter **filterp) | 1923 | char *filter_str, struct event_filter **filterp) |
1965 | { | 1924 | { |
@@ -1969,7 +1928,7 @@ static int create_system_filter(struct event_subsystem *system, | |||
1969 | 1928 | ||
1970 | err = create_filter_start(filter_str, true, &ps, &filter); | 1929 | err = create_filter_start(filter_str, true, &ps, &filter); |
1971 | if (!err) { | 1930 | if (!err) { |
1972 | err = replace_system_preds(system, tr, ps, filter_str); | 1931 | err = replace_system_preds(dir, tr, ps, filter_str); |
1973 | if (!err) { | 1932 | if (!err) { |
1974 | /* System filters just show a default message */ | 1933 | /* System filters just show a default message */ |
1975 | kfree(filter->filter_string); | 1934 | kfree(filter->filter_string); |
@@ -2053,18 +2012,18 @@ int apply_subsystem_event_filter(struct ftrace_subsystem_dir *dir, | |||
2053 | } | 2012 | } |
2054 | 2013 | ||
2055 | if (!strcmp(strstrip(filter_string), "0")) { | 2014 | if (!strcmp(strstrip(filter_string), "0")) { |
2056 | filter_free_subsystem_preds(system, tr); | 2015 | filter_free_subsystem_preds(dir, tr); |
2057 | remove_filter_string(system->filter); | 2016 | remove_filter_string(system->filter); |
2058 | filter = system->filter; | 2017 | filter = system->filter; |
2059 | system->filter = NULL; | 2018 | system->filter = NULL; |
2060 | /* Ensure all filters are no longer used */ | 2019 | /* Ensure all filters are no longer used */ |
2061 | synchronize_sched(); | 2020 | synchronize_sched(); |
2062 | filter_free_subsystem_filters(system, tr); | 2021 | filter_free_subsystem_filters(dir, tr); |
2063 | __free_filter(filter); | 2022 | __free_filter(filter); |
2064 | goto out_unlock; | 2023 | goto out_unlock; |
2065 | } | 2024 | } |
2066 | 2025 | ||
2067 | err = create_system_filter(system, tr, filter_string, &filter); | 2026 | err = create_system_filter(dir, tr, filter_string, &filter); |
2068 | if (filter) { | 2027 | if (filter) { |
2069 | /* | 2028 | /* |
2070 | * No event actually uses the system filter | 2029 | * No event actually uses the system filter |
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index 3c9b97e6b1f4..33ff6a24b802 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c | |||
@@ -265,7 +265,6 @@ alloc_trace_uprobe(const char *group, const char *event, int nargs, bool is_ret) | |||
265 | if (is_ret) | 265 | if (is_ret) |
266 | tu->consumer.ret_handler = uretprobe_dispatcher; | 266 | tu->consumer.ret_handler = uretprobe_dispatcher; |
267 | init_trace_uprobe_filter(&tu->filter); | 267 | init_trace_uprobe_filter(&tu->filter); |
268 | tu->tp.call.flags |= TRACE_EVENT_FL_USE_CALL_FILTER; | ||
269 | return tu; | 268 | return tu; |
270 | 269 | ||
271 | error: | 270 | error: |
@@ -1292,7 +1291,7 @@ static int register_uprobe_event(struct trace_uprobe *tu) | |||
1292 | kfree(call->print_fmt); | 1291 | kfree(call->print_fmt); |
1293 | return -ENODEV; | 1292 | return -ENODEV; |
1294 | } | 1293 | } |
1295 | call->flags = 0; | 1294 | |
1296 | call->class->reg = trace_uprobe_register; | 1295 | call->class->reg = trace_uprobe_register; |
1297 | call->data = tu; | 1296 | call->data = tu; |
1298 | ret = trace_add_event_call(call); | 1297 | ret = trace_add_event_call(call); |