diff options
| author | Steven Rostedt <srostedt@redhat.com> | 2011-02-03 23:25:46 -0500 |
|---|---|---|
| committer | Steven Rostedt <rostedt@goodmis.org> | 2011-02-07 20:56:20 -0500 |
| commit | 75b8e98263fdb0bfbdeba60d4db463259f1fe8a2 (patch) | |
| tree | fdd1e66316b049523c76e34c816a812598d07a3c /kernel/trace | |
| parent | bf93f9ed3a2cb89eb7e58851139d3be375b98027 (diff) | |
tracing/filter: Swap entire filter of events
When creating a new filter, instead of allocating the filter to the
event call first and then processing the filter, it is easier to
process a temporary filter and then just swap it with the call filter.
By doing this, it simplifies the code.
A filter is allocated and processed, when it is done, it is
swapped with the call filter, synchronize_sched() is called to make
sure all callers are done with the old filter (filters are called
with premption disabled), and then the old filter is freed.
Cc: Tom Zanussi <tzanussi@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace')
| -rw-r--r-- | kernel/trace/trace_events_filter.c | 251 |
1 files changed, 146 insertions, 105 deletions
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 2403ce5b6507..f5d335d28d0b 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c | |||
| @@ -425,10 +425,15 @@ int filter_match_preds(struct event_filter *filter, void *rec) | |||
| 425 | struct filter_pred *preds; | 425 | struct filter_pred *preds; |
| 426 | struct filter_pred *pred; | 426 | struct filter_pred *pred; |
| 427 | struct filter_pred *root; | 427 | struct filter_pred *root; |
| 428 | int n_preds = ACCESS_ONCE(filter->n_preds); | 428 | int n_preds; |
| 429 | int done = 0; | 429 | int done = 0; |
| 430 | 430 | ||
| 431 | /* no filter is considered a match */ | 431 | /* no filter is considered a match */ |
| 432 | if (!filter) | ||
| 433 | return 1; | ||
| 434 | |||
| 435 | n_preds = filter->n_preds; | ||
| 436 | |||
| 432 | if (!n_preds) | 437 | if (!n_preds) |
| 433 | return 1; | 438 | return 1; |
| 434 | 439 | ||
| @@ -509,6 +514,9 @@ static void parse_error(struct filter_parse_state *ps, int err, int pos) | |||
| 509 | 514 | ||
| 510 | static void remove_filter_string(struct event_filter *filter) | 515 | static void remove_filter_string(struct event_filter *filter) |
| 511 | { | 516 | { |
| 517 | if (!filter) | ||
| 518 | return; | ||
| 519 | |||
| 512 | kfree(filter->filter_string); | 520 | kfree(filter->filter_string); |
| 513 | filter->filter_string = NULL; | 521 | filter->filter_string = NULL; |
| 514 | } | 522 | } |
| @@ -568,9 +576,10 @@ static void append_filter_err(struct filter_parse_state *ps, | |||
| 568 | 576 | ||
| 569 | void print_event_filter(struct ftrace_event_call *call, struct trace_seq *s) | 577 | void print_event_filter(struct ftrace_event_call *call, struct trace_seq *s) |
| 570 | { | 578 | { |
| 571 | struct event_filter *filter = call->filter; | 579 | struct event_filter *filter; |
| 572 | 580 | ||
| 573 | mutex_lock(&event_mutex); | 581 | mutex_lock(&event_mutex); |
| 582 | filter = call->filter; | ||
| 574 | if (filter && filter->filter_string) | 583 | if (filter && filter->filter_string) |
| 575 | trace_seq_printf(s, "%s\n", filter->filter_string); | 584 | trace_seq_printf(s, "%s\n", filter->filter_string); |
| 576 | else | 585 | else |
| @@ -581,9 +590,10 @@ void print_event_filter(struct ftrace_event_call *call, struct trace_seq *s) | |||
| 581 | void print_subsystem_event_filter(struct event_subsystem *system, | 590 | void print_subsystem_event_filter(struct event_subsystem *system, |
| 582 | struct trace_seq *s) | 591 | struct trace_seq *s) |
| 583 | { | 592 | { |
| 584 | struct event_filter *filter = system->filter; | 593 | struct event_filter *filter; |
| 585 | 594 | ||
| 586 | mutex_lock(&event_mutex); | 595 | mutex_lock(&event_mutex); |
| 596 | filter = system->filter; | ||
| 587 | if (filter && filter->filter_string) | 597 | if (filter && filter->filter_string) |
| 588 | trace_seq_printf(s, "%s\n", filter->filter_string); | 598 | trace_seq_printf(s, "%s\n", filter->filter_string); |
| 589 | else | 599 | else |
| @@ -745,26 +755,9 @@ static void __free_preds(struct event_filter *filter) | |||
| 745 | filter->n_preds = 0; | 755 | filter->n_preds = 0; |
| 746 | } | 756 | } |
| 747 | 757 | ||
| 748 | static void reset_preds(struct event_filter *filter) | 758 | static void filter_disable(struct ftrace_event_call *call) |
| 749 | { | ||
| 750 | int n_preds = filter->n_preds; | ||
| 751 | int i; | ||
| 752 | |||
| 753 | filter->n_preds = 0; | ||
| 754 | filter->root = NULL; | ||
| 755 | if (!filter->preds) | ||
| 756 | return; | ||
| 757 | |||
| 758 | for (i = 0; i < n_preds; i++) | ||
| 759 | filter->preds[i].fn = filter_pred_none; | ||
| 760 | } | ||
| 761 | |||
| 762 | static void filter_disable_preds(struct ftrace_event_call *call) | ||
| 763 | { | 759 | { |
| 764 | struct event_filter *filter = call->filter; | ||
| 765 | |||
| 766 | call->flags &= ~TRACE_EVENT_FL_FILTERED; | 760 | call->flags &= ~TRACE_EVENT_FL_FILTERED; |
| 767 | reset_preds(filter); | ||
| 768 | } | 761 | } |
| 769 | 762 | ||
| 770 | static void __free_filter(struct event_filter *filter) | 763 | static void __free_filter(struct event_filter *filter) |
| @@ -777,11 +770,16 @@ static void __free_filter(struct event_filter *filter) | |||
| 777 | kfree(filter); | 770 | kfree(filter); |
| 778 | } | 771 | } |
| 779 | 772 | ||
| 773 | /* | ||
| 774 | * Called when destroying the ftrace_event_call. | ||
| 775 | * The call is being freed, so we do not need to worry about | ||
| 776 | * the call being currently used. This is for module code removing | ||
| 777 | * the tracepoints from within it. | ||
| 778 | */ | ||
| 780 | void destroy_preds(struct ftrace_event_call *call) | 779 | void destroy_preds(struct ftrace_event_call *call) |
| 781 | { | 780 | { |
| 782 | __free_filter(call->filter); | 781 | __free_filter(call->filter); |
| 783 | call->filter = NULL; | 782 | call->filter = NULL; |
| 784 | call->flags &= ~TRACE_EVENT_FL_FILTERED; | ||
| 785 | } | 783 | } |
| 786 | 784 | ||
| 787 | static struct event_filter *__alloc_filter(void) | 785 | static struct event_filter *__alloc_filter(void) |
| @@ -789,11 +787,6 @@ static struct event_filter *__alloc_filter(void) | |||
| 789 | struct event_filter *filter; | 787 | struct event_filter *filter; |
| 790 | 788 | ||
| 791 | filter = kzalloc(sizeof(*filter), GFP_KERNEL); | 789 | filter = kzalloc(sizeof(*filter), GFP_KERNEL); |
| 792 | if (!filter) | ||
| 793 | return ERR_PTR(-ENOMEM); | ||
| 794 | |||
| 795 | filter->n_preds = 0; | ||
| 796 | |||
| 797 | return filter; | 790 | return filter; |
| 798 | } | 791 | } |
| 799 | 792 | ||
| @@ -838,46 +831,28 @@ static int __alloc_preds(struct event_filter *filter, int n_preds) | |||
| 838 | return 0; | 831 | return 0; |
| 839 | } | 832 | } |
| 840 | 833 | ||
| 841 | static int init_filter(struct ftrace_event_call *call) | 834 | static void filter_free_subsystem_preds(struct event_subsystem *system) |
| 842 | { | ||
| 843 | if (call->filter) | ||
| 844 | return 0; | ||
| 845 | |||
| 846 | call->flags &= ~TRACE_EVENT_FL_FILTERED; | ||
| 847 | call->filter = __alloc_filter(); | ||
| 848 | if (IS_ERR(call->filter)) | ||
| 849 | return PTR_ERR(call->filter); | ||
| 850 | |||
| 851 | return 0; | ||
| 852 | } | ||
| 853 | |||
| 854 | static int init_subsystem_preds(struct event_subsystem *system) | ||
| 855 | { | 835 | { |
| 856 | struct ftrace_event_call *call; | 836 | struct ftrace_event_call *call; |
| 857 | int err; | ||
| 858 | 837 | ||
| 859 | list_for_each_entry(call, &ftrace_events, list) { | 838 | list_for_each_entry(call, &ftrace_events, list) { |
| 860 | if (strcmp(call->class->system, system->name) != 0) | 839 | if (strcmp(call->class->system, system->name) != 0) |
| 861 | continue; | 840 | continue; |
| 862 | 841 | ||
| 863 | err = init_filter(call); | 842 | filter_disable(call); |
| 864 | if (err) | 843 | remove_filter_string(call->filter); |
| 865 | return err; | ||
| 866 | } | 844 | } |
| 867 | |||
| 868 | return 0; | ||
| 869 | } | 845 | } |
| 870 | 846 | ||
| 871 | static void filter_free_subsystem_preds(struct event_subsystem *system) | 847 | static void filter_free_subsystem_filters(struct event_subsystem *system) |
| 872 | { | 848 | { |
| 873 | struct ftrace_event_call *call; | 849 | struct ftrace_event_call *call; |
| 874 | 850 | ||
| 875 | list_for_each_entry(call, &ftrace_events, list) { | 851 | list_for_each_entry(call, &ftrace_events, list) { |
| 876 | if (strcmp(call->class->system, system->name) != 0) | 852 | if (strcmp(call->class->system, system->name) != 0) |
| 877 | continue; | 853 | continue; |
| 878 | 854 | __free_filter(call->filter); | |
| 879 | filter_disable_preds(call); | 855 | call->filter = NULL; |
| 880 | remove_filter_string(call->filter); | ||
| 881 | } | 856 | } |
| 882 | } | 857 | } |
| 883 | 858 | ||
| @@ -1743,88 +1718,129 @@ fail: | |||
| 1743 | return err; | 1718 | return err; |
| 1744 | } | 1719 | } |
| 1745 | 1720 | ||
| 1721 | struct filter_list { | ||
| 1722 | struct list_head list; | ||
| 1723 | struct event_filter *filter; | ||
| 1724 | }; | ||
| 1725 | |||
| 1746 | static int replace_system_preds(struct event_subsystem *system, | 1726 | static int replace_system_preds(struct event_subsystem *system, |
| 1747 | struct filter_parse_state *ps, | 1727 | struct filter_parse_state *ps, |
| 1748 | char *filter_string) | 1728 | char *filter_string) |
| 1749 | { | 1729 | { |
| 1750 | struct ftrace_event_call *call; | 1730 | struct ftrace_event_call *call; |
| 1731 | struct filter_list *filter_item; | ||
| 1732 | struct filter_list *tmp; | ||
| 1733 | LIST_HEAD(filter_list); | ||
| 1751 | bool fail = true; | 1734 | bool fail = true; |
| 1752 | int err; | 1735 | int err; |
| 1753 | 1736 | ||
| 1754 | list_for_each_entry(call, &ftrace_events, list) { | 1737 | list_for_each_entry(call, &ftrace_events, list) { |
| 1755 | struct event_filter *filter = call->filter; | ||
| 1756 | 1738 | ||
| 1757 | if (strcmp(call->class->system, system->name) != 0) | 1739 | if (strcmp(call->class->system, system->name) != 0) |
| 1758 | continue; | 1740 | continue; |
| 1759 | 1741 | ||
| 1760 | /* try to see if the filter can be applied */ | 1742 | /* |
| 1761 | err = replace_preds(call, filter, ps, filter_string, true); | 1743 | * Try to see if the filter can be applied |
| 1744 | * (filter arg is ignored on dry_run) | ||
| 1745 | */ | ||
| 1746 | err = replace_preds(call, NULL, ps, filter_string, true); | ||
| 1762 | if (err) | 1747 | if (err) |
| 1763 | goto fail; | 1748 | goto fail; |
| 1764 | } | 1749 | } |
| 1765 | 1750 | ||
| 1766 | /* set all filter pred counts to zero */ | ||
| 1767 | list_for_each_entry(call, &ftrace_events, list) { | 1751 | list_for_each_entry(call, &ftrace_events, list) { |
| 1768 | struct event_filter *filter = call->filter; | 1752 | struct event_filter *filter; |
| 1769 | 1753 | ||
| 1770 | if (strcmp(call->class->system, system->name) != 0) | 1754 | if (strcmp(call->class->system, system->name) != 0) |
| 1771 | continue; | 1755 | continue; |
| 1772 | 1756 | ||
| 1773 | reset_preds(filter); | 1757 | filter_item = kzalloc(sizeof(*filter_item), GFP_KERNEL); |
| 1774 | } | 1758 | if (!filter_item) |
| 1759 | goto fail_mem; | ||
| 1775 | 1760 | ||
| 1776 | /* | 1761 | list_add_tail(&filter_item->list, &filter_list); |
| 1777 | * Since some of the preds may be used under preemption | ||
| 1778 | * we need to wait for them to finish before we may | ||
| 1779 | * reallocate them. | ||
| 1780 | */ | ||
| 1781 | synchronize_sched(); | ||
| 1782 | 1762 | ||
| 1783 | list_for_each_entry(call, &ftrace_events, list) { | 1763 | filter_item->filter = __alloc_filter(); |
| 1784 | struct event_filter *filter = call->filter; | 1764 | if (!filter_item->filter) |
| 1765 | goto fail_mem; | ||
| 1766 | filter = filter_item->filter; | ||
| 1785 | 1767 | ||
| 1786 | if (strcmp(call->class->system, system->name) != 0) | 1768 | /* Can only fail on no memory */ |
| 1787 | continue; | 1769 | err = replace_filter_string(filter, filter_string); |
| 1770 | if (err) | ||
| 1771 | goto fail_mem; | ||
| 1788 | 1772 | ||
| 1789 | /* really apply the filter */ | ||
| 1790 | filter_disable_preds(call); | ||
| 1791 | err = replace_preds(call, filter, ps, filter_string, false); | 1773 | err = replace_preds(call, filter, ps, filter_string, false); |
| 1792 | if (err) | 1774 | if (err) { |
| 1793 | filter_disable_preds(call); | 1775 | filter_disable(call); |
| 1794 | else { | 1776 | parse_error(ps, FILT_ERR_BAD_SUBSYS_FILTER, 0); |
| 1777 | append_filter_err(ps, filter); | ||
| 1778 | } else | ||
| 1795 | call->flags |= TRACE_EVENT_FL_FILTERED; | 1779 | call->flags |= TRACE_EVENT_FL_FILTERED; |
| 1796 | replace_filter_string(filter, filter_string); | 1780 | /* |
| 1797 | } | 1781 | * Regardless of if this returned an error, we still |
| 1782 | * replace the filter for the call. | ||
| 1783 | */ | ||
| 1784 | filter = call->filter; | ||
| 1785 | call->filter = filter_item->filter; | ||
| 1786 | filter_item->filter = filter; | ||
| 1787 | |||
| 1798 | fail = false; | 1788 | fail = false; |
| 1799 | } | 1789 | } |
| 1800 | 1790 | ||
| 1801 | if (fail) | 1791 | if (fail) |
| 1802 | goto fail; | 1792 | goto fail; |
| 1803 | 1793 | ||
| 1794 | /* | ||
| 1795 | * The calls can still be using the old filters. | ||
| 1796 | * Do a synchronize_sched() to ensure all calls are | ||
| 1797 | * done with them before we free them. | ||
| 1798 | */ | ||
| 1799 | synchronize_sched(); | ||
| 1800 | list_for_each_entry_safe(filter_item, tmp, &filter_list, list) { | ||
| 1801 | __free_filter(filter_item->filter); | ||
| 1802 | list_del(&filter_item->list); | ||
| 1803 | kfree(filter_item); | ||
| 1804 | } | ||
| 1804 | return 0; | 1805 | return 0; |
| 1805 | fail: | 1806 | fail: |
| 1807 | /* No call succeeded */ | ||
| 1808 | list_for_each_entry_safe(filter_item, tmp, &filter_list, list) { | ||
| 1809 | list_del(&filter_item->list); | ||
| 1810 | kfree(filter_item); | ||
| 1811 | } | ||
| 1806 | parse_error(ps, FILT_ERR_BAD_SUBSYS_FILTER, 0); | 1812 | parse_error(ps, FILT_ERR_BAD_SUBSYS_FILTER, 0); |
| 1807 | return -EINVAL; | 1813 | return -EINVAL; |
| 1814 | fail_mem: | ||
| 1815 | /* If any call succeeded, we still need to sync */ | ||
| 1816 | if (!fail) | ||
| 1817 | synchronize_sched(); | ||
| 1818 | list_for_each_entry_safe(filter_item, tmp, &filter_list, list) { | ||
| 1819 | __free_filter(filter_item->filter); | ||
| 1820 | list_del(&filter_item->list); | ||
| 1821 | kfree(filter_item); | ||
| 1822 | } | ||
| 1823 | return -ENOMEM; | ||
| 1808 | } | 1824 | } |
| 1809 | 1825 | ||
| 1810 | int apply_event_filter(struct ftrace_event_call *call, char *filter_string) | 1826 | int apply_event_filter(struct ftrace_event_call *call, char *filter_string) |
| 1811 | { | 1827 | { |
| 1812 | int err; | ||
| 1813 | struct filter_parse_state *ps; | 1828 | struct filter_parse_state *ps; |
| 1829 | struct event_filter *filter; | ||
| 1830 | struct event_filter *tmp; | ||
| 1831 | int err = 0; | ||
| 1814 | 1832 | ||
| 1815 | mutex_lock(&event_mutex); | 1833 | mutex_lock(&event_mutex); |
| 1816 | 1834 | ||
| 1817 | err = init_filter(call); | ||
| 1818 | if (err) | ||
| 1819 | goto out_unlock; | ||
| 1820 | |||
| 1821 | if (!strcmp(strstrip(filter_string), "0")) { | 1835 | if (!strcmp(strstrip(filter_string), "0")) { |
| 1822 | filter_disable_preds(call); | 1836 | filter_disable(call); |
| 1823 | reset_preds(call->filter); | 1837 | filter = call->filter; |
| 1838 | if (!filter) | ||
| 1839 | goto out_unlock; | ||
| 1840 | call->filter = NULL; | ||
| 1824 | /* Make sure the filter is not being used */ | 1841 | /* Make sure the filter is not being used */ |
| 1825 | synchronize_sched(); | 1842 | synchronize_sched(); |
| 1826 | __free_preds(call->filter); | 1843 | __free_filter(filter); |
| 1827 | remove_filter_string(call->filter); | ||
| 1828 | goto out_unlock; | 1844 | goto out_unlock; |
| 1829 | } | 1845 | } |
| 1830 | 1846 | ||
| @@ -1833,29 +1849,41 @@ int apply_event_filter(struct ftrace_event_call *call, char *filter_string) | |||
| 1833 | if (!ps) | 1849 | if (!ps) |
| 1834 | goto out_unlock; | 1850 | goto out_unlock; |
| 1835 | 1851 | ||
| 1836 | filter_disable_preds(call); | 1852 | filter = __alloc_filter(); |
| 1837 | replace_filter_string(call->filter, filter_string); | 1853 | if (!filter) { |
| 1854 | kfree(ps); | ||
| 1855 | goto out_unlock; | ||
| 1856 | } | ||
| 1857 | |||
| 1858 | replace_filter_string(filter, filter_string); | ||
| 1838 | 1859 | ||
| 1839 | parse_init(ps, filter_ops, filter_string); | 1860 | parse_init(ps, filter_ops, filter_string); |
| 1840 | err = filter_parse(ps); | 1861 | err = filter_parse(ps); |
| 1841 | if (err) { | 1862 | if (err) { |
| 1842 | append_filter_err(ps, call->filter); | 1863 | append_filter_err(ps, filter); |
| 1843 | goto out; | 1864 | goto out; |
| 1844 | } | 1865 | } |
| 1845 | 1866 | ||
| 1846 | /* | 1867 | err = replace_preds(call, filter, ps, filter_string, false); |
| 1847 | * Make sure all the pred counts are zero so that | 1868 | if (err) { |
| 1848 | * no task is using it when we reallocate the preds array. | 1869 | filter_disable(call); |
| 1849 | */ | 1870 | append_filter_err(ps, filter); |
| 1850 | reset_preds(call->filter); | 1871 | } else |
| 1851 | synchronize_sched(); | ||
| 1852 | |||
| 1853 | err = replace_preds(call, call->filter, ps, filter_string, false); | ||
| 1854 | if (err) | ||
| 1855 | append_filter_err(ps, call->filter); | ||
| 1856 | else | ||
| 1857 | call->flags |= TRACE_EVENT_FL_FILTERED; | 1872 | call->flags |= TRACE_EVENT_FL_FILTERED; |
| 1858 | out: | 1873 | out: |
| 1874 | /* | ||
| 1875 | * Always swap the call filter with the new filter | ||
| 1876 | * even if there was an error. If there was an error | ||
| 1877 | * in the filter, we disable the filter and show the error | ||
| 1878 | * string | ||
| 1879 | */ | ||
| 1880 | tmp = call->filter; | ||
| 1881 | call->filter = filter; | ||
| 1882 | if (tmp) { | ||
| 1883 | /* Make sure the call is done with the filter */ | ||
| 1884 | synchronize_sched(); | ||
| 1885 | __free_filter(tmp); | ||
| 1886 | } | ||
| 1859 | filter_opstack_clear(ps); | 1887 | filter_opstack_clear(ps); |
| 1860 | postfix_clear(ps); | 1888 | postfix_clear(ps); |
| 1861 | kfree(ps); | 1889 | kfree(ps); |
| @@ -1868,18 +1896,21 @@ out_unlock: | |||
| 1868 | int apply_subsystem_event_filter(struct event_subsystem *system, | 1896 | int apply_subsystem_event_filter(struct event_subsystem *system, |
| 1869 | char *filter_string) | 1897 | char *filter_string) |
| 1870 | { | 1898 | { |
| 1871 | int err; | ||
| 1872 | struct filter_parse_state *ps; | 1899 | struct filter_parse_state *ps; |
| 1900 | struct event_filter *filter; | ||
| 1901 | int err = 0; | ||
| 1873 | 1902 | ||
| 1874 | mutex_lock(&event_mutex); | 1903 | mutex_lock(&event_mutex); |
| 1875 | 1904 | ||
| 1876 | err = init_subsystem_preds(system); | ||
| 1877 | if (err) | ||
| 1878 | goto out_unlock; | ||
| 1879 | |||
| 1880 | if (!strcmp(strstrip(filter_string), "0")) { | 1905 | if (!strcmp(strstrip(filter_string), "0")) { |
| 1881 | filter_free_subsystem_preds(system); | 1906 | filter_free_subsystem_preds(system); |
| 1882 | remove_filter_string(system->filter); | 1907 | remove_filter_string(system->filter); |
| 1908 | filter = system->filter; | ||
| 1909 | system->filter = NULL; | ||
| 1910 | /* Ensure all filters are no longer used */ | ||
| 1911 | synchronize_sched(); | ||
| 1912 | filter_free_subsystem_filters(system); | ||
| 1913 | __free_filter(filter); | ||
| 1883 | goto out_unlock; | 1914 | goto out_unlock; |
| 1884 | } | 1915 | } |
| 1885 | 1916 | ||
| @@ -1888,7 +1919,17 @@ int apply_subsystem_event_filter(struct event_subsystem *system, | |||
| 1888 | if (!ps) | 1919 | if (!ps) |
| 1889 | goto out_unlock; | 1920 | goto out_unlock; |
| 1890 | 1921 | ||
| 1891 | replace_filter_string(system->filter, filter_string); | 1922 | filter = __alloc_filter(); |
| 1923 | if (!filter) | ||
| 1924 | goto out; | ||
| 1925 | |||
| 1926 | replace_filter_string(filter, filter_string); | ||
| 1927 | /* | ||
| 1928 | * No event actually uses the system filter | ||
| 1929 | * we can free it without synchronize_sched(). | ||
| 1930 | */ | ||
| 1931 | __free_filter(system->filter); | ||
| 1932 | system->filter = filter; | ||
| 1892 | 1933 | ||
| 1893 | parse_init(ps, filter_ops, filter_string); | 1934 | parse_init(ps, filter_ops, filter_string); |
| 1894 | err = filter_parse(ps); | 1935 | err = filter_parse(ps); |
| @@ -1945,7 +1986,7 @@ int ftrace_profile_set_filter(struct perf_event *event, int event_id, | |||
| 1945 | goto out_unlock; | 1986 | goto out_unlock; |
| 1946 | 1987 | ||
| 1947 | filter = __alloc_filter(); | 1988 | filter = __alloc_filter(); |
| 1948 | if (IS_ERR(filter)) { | 1989 | if (!filter) { |
| 1949 | err = PTR_ERR(filter); | 1990 | err = PTR_ERR(filter); |
| 1950 | goto out_unlock; | 1991 | goto out_unlock; |
| 1951 | } | 1992 | } |
