aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2011-02-03 23:25:46 -0500
committerSteven Rostedt <rostedt@goodmis.org>2011-02-07 20:56:20 -0500
commit75b8e98263fdb0bfbdeba60d4db463259f1fe8a2 (patch)
treefdd1e66316b049523c76e34c816a812598d07a3c /kernel/trace
parentbf93f9ed3a2cb89eb7e58851139d3be375b98027 (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.c251
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
510static void remove_filter_string(struct event_filter *filter) 515static 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
569void print_event_filter(struct ftrace_event_call *call, struct trace_seq *s) 577void 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)
581void print_subsystem_event_filter(struct event_subsystem *system, 590void 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
748static void reset_preds(struct event_filter *filter) 758static 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
762static 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
770static void __free_filter(struct event_filter *filter) 763static 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 */
780void destroy_preds(struct ftrace_event_call *call) 779void 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
787static struct event_filter *__alloc_filter(void) 785static 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
841static int init_filter(struct ftrace_event_call *call) 834static 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
854static 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
871static void filter_free_subsystem_preds(struct event_subsystem *system) 847static 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
1721struct filter_list {
1722 struct list_head list;
1723 struct event_filter *filter;
1724};
1725
1746static int replace_system_preds(struct event_subsystem *system, 1726static 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
1810int apply_event_filter(struct ftrace_event_call *call, char *filter_string) 1826int 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;
1858out: 1873out:
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:
1868int apply_subsystem_event_filter(struct event_subsystem *system, 1896int 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 }