diff options
author | Oleg Nesterov <oleg@redhat.com> | 2013-07-31 13:31:32 -0400 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2013-08-21 22:31:23 -0400 |
commit | 779c5e379158de3e96112630c543d3c7b37efab9 (patch) | |
tree | 372c80fb9521ef4ac5d614d481a1a819cf57ba6c /kernel | |
parent | 3ddc77f6f4a58ee2e49e0e8c0216105c7f8ddd8c (diff) |
tracing: Kill trace_create_file_ops() and friends
trace_create_file_ops() allocates the copy of id/filter/format/enable
file_operations to set "f_op->owner = mod" for fops_get().
However after the recent changes there is no reason to prevent rmmod
even if one of these files is opened. A file operation can do nothing
but fail after remove_event_file_dir() clears ->i_private for every
file removed by trace_module_remove_events().
Kill "struct ftrace_module_file_ops" and fix the compilation errors.
Link: http://lkml.kernel.org/r/20130731173132.GA31033@redhat.com
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/trace/trace_events.c | 153 |
1 files changed, 9 insertions, 144 deletions
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 29a7ebcfb426..2ec82734b8a7 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
@@ -1683,8 +1683,7 @@ __trace_early_add_new_event(struct ftrace_event_call *call, | |||
1683 | } | 1683 | } |
1684 | 1684 | ||
1685 | struct ftrace_module_file_ops; | 1685 | struct ftrace_module_file_ops; |
1686 | static void __add_event_to_tracers(struct ftrace_event_call *call, | 1686 | static void __add_event_to_tracers(struct ftrace_event_call *call); |
1687 | struct ftrace_module_file_ops *file_ops); | ||
1688 | 1687 | ||
1689 | /* Add an additional event_call dynamically */ | 1688 | /* Add an additional event_call dynamically */ |
1690 | int trace_add_event_call(struct ftrace_event_call *call) | 1689 | int trace_add_event_call(struct ftrace_event_call *call) |
@@ -1695,7 +1694,7 @@ int trace_add_event_call(struct ftrace_event_call *call) | |||
1695 | 1694 | ||
1696 | ret = __register_event(call, NULL); | 1695 | ret = __register_event(call, NULL); |
1697 | if (ret >= 0) | 1696 | if (ret >= 0) |
1698 | __add_event_to_tracers(call, NULL); | 1697 | __add_event_to_tracers(call); |
1699 | 1698 | ||
1700 | mutex_unlock(&event_mutex); | 1699 | mutex_unlock(&event_mutex); |
1701 | mutex_unlock(&trace_types_lock); | 1700 | mutex_unlock(&trace_types_lock); |
@@ -1769,100 +1768,21 @@ int trace_remove_event_call(struct ftrace_event_call *call) | |||
1769 | 1768 | ||
1770 | #ifdef CONFIG_MODULES | 1769 | #ifdef CONFIG_MODULES |
1771 | 1770 | ||
1772 | static LIST_HEAD(ftrace_module_file_list); | ||
1773 | |||
1774 | /* | ||
1775 | * Modules must own their file_operations to keep up with | ||
1776 | * reference counting. | ||
1777 | */ | ||
1778 | struct ftrace_module_file_ops { | ||
1779 | struct list_head list; | ||
1780 | struct module *mod; | ||
1781 | struct file_operations id; | ||
1782 | struct file_operations enable; | ||
1783 | struct file_operations format; | ||
1784 | struct file_operations filter; | ||
1785 | }; | ||
1786 | |||
1787 | static struct ftrace_module_file_ops * | ||
1788 | find_ftrace_file_ops(struct ftrace_module_file_ops *file_ops, struct module *mod) | ||
1789 | { | ||
1790 | /* | ||
1791 | * As event_calls are added in groups by module, | ||
1792 | * when we find one file_ops, we don't need to search for | ||
1793 | * each call in that module, as the rest should be the | ||
1794 | * same. Only search for a new one if the last one did | ||
1795 | * not match. | ||
1796 | */ | ||
1797 | if (file_ops && mod == file_ops->mod) | ||
1798 | return file_ops; | ||
1799 | |||
1800 | list_for_each_entry(file_ops, &ftrace_module_file_list, list) { | ||
1801 | if (file_ops->mod == mod) | ||
1802 | return file_ops; | ||
1803 | } | ||
1804 | return NULL; | ||
1805 | } | ||
1806 | |||
1807 | static struct ftrace_module_file_ops * | ||
1808 | trace_create_file_ops(struct module *mod) | ||
1809 | { | ||
1810 | struct ftrace_module_file_ops *file_ops; | ||
1811 | |||
1812 | /* | ||
1813 | * This is a bit of a PITA. To allow for correct reference | ||
1814 | * counting, modules must "own" their file_operations. | ||
1815 | * To do this, we allocate the file operations that will be | ||
1816 | * used in the event directory. | ||
1817 | */ | ||
1818 | |||
1819 | file_ops = kmalloc(sizeof(*file_ops), GFP_KERNEL); | ||
1820 | if (!file_ops) | ||
1821 | return NULL; | ||
1822 | |||
1823 | file_ops->mod = mod; | ||
1824 | |||
1825 | file_ops->id = ftrace_event_id_fops; | ||
1826 | file_ops->id.owner = mod; | ||
1827 | |||
1828 | file_ops->enable = ftrace_enable_fops; | ||
1829 | file_ops->enable.owner = mod; | ||
1830 | |||
1831 | file_ops->filter = ftrace_event_filter_fops; | ||
1832 | file_ops->filter.owner = mod; | ||
1833 | |||
1834 | file_ops->format = ftrace_event_format_fops; | ||
1835 | file_ops->format.owner = mod; | ||
1836 | |||
1837 | list_add(&file_ops->list, &ftrace_module_file_list); | ||
1838 | |||
1839 | return file_ops; | ||
1840 | } | ||
1841 | |||
1842 | static void trace_module_add_events(struct module *mod) | 1771 | static void trace_module_add_events(struct module *mod) |
1843 | { | 1772 | { |
1844 | struct ftrace_module_file_ops *file_ops = NULL; | ||
1845 | struct ftrace_event_call **call, **start, **end; | 1773 | struct ftrace_event_call **call, **start, **end; |
1846 | 1774 | ||
1847 | start = mod->trace_events; | 1775 | start = mod->trace_events; |
1848 | end = mod->trace_events + mod->num_trace_events; | 1776 | end = mod->trace_events + mod->num_trace_events; |
1849 | 1777 | ||
1850 | if (start == end) | ||
1851 | return; | ||
1852 | |||
1853 | file_ops = trace_create_file_ops(mod); | ||
1854 | if (!file_ops) | ||
1855 | return; | ||
1856 | |||
1857 | for_each_event(call, start, end) { | 1778 | for_each_event(call, start, end) { |
1858 | __register_event(*call, mod); | 1779 | __register_event(*call, mod); |
1859 | __add_event_to_tracers(*call, file_ops); | 1780 | __add_event_to_tracers(*call); |
1860 | } | 1781 | } |
1861 | } | 1782 | } |
1862 | 1783 | ||
1863 | static void trace_module_remove_events(struct module *mod) | 1784 | static void trace_module_remove_events(struct module *mod) |
1864 | { | 1785 | { |
1865 | struct ftrace_module_file_ops *file_ops; | ||
1866 | struct ftrace_event_call *call, *p; | 1786 | struct ftrace_event_call *call, *p; |
1867 | bool clear_trace = false; | 1787 | bool clear_trace = false; |
1868 | 1788 | ||
@@ -1874,16 +1794,6 @@ static void trace_module_remove_events(struct module *mod) | |||
1874 | __trace_remove_event_call(call); | 1794 | __trace_remove_event_call(call); |
1875 | } | 1795 | } |
1876 | } | 1796 | } |
1877 | |||
1878 | /* Now free the file_operations */ | ||
1879 | list_for_each_entry(file_ops, &ftrace_module_file_list, list) { | ||
1880 | if (file_ops->mod == mod) | ||
1881 | break; | ||
1882 | } | ||
1883 | if (&file_ops->list != &ftrace_module_file_list) { | ||
1884 | list_del(&file_ops->list); | ||
1885 | kfree(file_ops); | ||
1886 | } | ||
1887 | up_write(&trace_event_sem); | 1797 | up_write(&trace_event_sem); |
1888 | 1798 | ||
1889 | /* | 1799 | /* |
@@ -1919,62 +1829,22 @@ static int trace_module_notify(struct notifier_block *self, | |||
1919 | return 0; | 1829 | return 0; |
1920 | } | 1830 | } |
1921 | 1831 | ||
1922 | static int | ||
1923 | __trace_add_new_mod_event(struct ftrace_event_call *call, | ||
1924 | struct trace_array *tr, | ||
1925 | struct ftrace_module_file_ops *file_ops) | ||
1926 | { | ||
1927 | return __trace_add_new_event(call, tr, | ||
1928 | &file_ops->id, &file_ops->enable, | ||
1929 | &file_ops->filter, &file_ops->format); | ||
1930 | } | ||
1931 | |||
1932 | #else | 1832 | #else |
1933 | static inline struct ftrace_module_file_ops * | ||
1934 | find_ftrace_file_ops(struct ftrace_module_file_ops *file_ops, struct module *mod) | ||
1935 | { | ||
1936 | return NULL; | ||
1937 | } | ||
1938 | static inline int trace_module_notify(struct notifier_block *self, | 1833 | static inline int trace_module_notify(struct notifier_block *self, |
1939 | unsigned long val, void *data) | 1834 | unsigned long val, void *data) |
1940 | { | 1835 | { |
1941 | return 0; | 1836 | return 0; |
1942 | } | 1837 | } |
1943 | static inline int | ||
1944 | __trace_add_new_mod_event(struct ftrace_event_call *call, | ||
1945 | struct trace_array *tr, | ||
1946 | struct ftrace_module_file_ops *file_ops) | ||
1947 | { | ||
1948 | return -ENODEV; | ||
1949 | } | ||
1950 | #endif /* CONFIG_MODULES */ | 1838 | #endif /* CONFIG_MODULES */ |
1951 | 1839 | ||
1952 | /* Create a new event directory structure for a trace directory. */ | 1840 | /* Create a new event directory structure for a trace directory. */ |
1953 | static void | 1841 | static void |
1954 | __trace_add_event_dirs(struct trace_array *tr) | 1842 | __trace_add_event_dirs(struct trace_array *tr) |
1955 | { | 1843 | { |
1956 | struct ftrace_module_file_ops *file_ops = NULL; | ||
1957 | struct ftrace_event_call *call; | 1844 | struct ftrace_event_call *call; |
1958 | int ret; | 1845 | int ret; |
1959 | 1846 | ||
1960 | list_for_each_entry(call, &ftrace_events, list) { | 1847 | list_for_each_entry(call, &ftrace_events, list) { |
1961 | if (call->mod) { | ||
1962 | /* | ||
1963 | * Directories for events by modules need to | ||
1964 | * keep module ref counts when opened (as we don't | ||
1965 | * want the module to disappear when reading one | ||
1966 | * of these files). The file_ops keep account of | ||
1967 | * the module ref count. | ||
1968 | */ | ||
1969 | file_ops = find_ftrace_file_ops(file_ops, call->mod); | ||
1970 | if (!file_ops) | ||
1971 | continue; /* Warn? */ | ||
1972 | ret = __trace_add_new_mod_event(call, tr, file_ops); | ||
1973 | if (ret < 0) | ||
1974 | pr_warning("Could not create directory for event %s\n", | ||
1975 | call->name); | ||
1976 | continue; | ||
1977 | } | ||
1978 | ret = __trace_add_new_event(call, tr, | 1848 | ret = __trace_add_new_event(call, tr, |
1979 | &ftrace_event_id_fops, | 1849 | &ftrace_event_id_fops, |
1980 | &ftrace_enable_fops, | 1850 | &ftrace_enable_fops, |
@@ -2332,21 +2202,16 @@ __trace_remove_event_dirs(struct trace_array *tr) | |||
2332 | remove_event_file_dir(file); | 2202 | remove_event_file_dir(file); |
2333 | } | 2203 | } |
2334 | 2204 | ||
2335 | static void | 2205 | static void __add_event_to_tracers(struct ftrace_event_call *call) |
2336 | __add_event_to_tracers(struct ftrace_event_call *call, | ||
2337 | struct ftrace_module_file_ops *file_ops) | ||
2338 | { | 2206 | { |
2339 | struct trace_array *tr; | 2207 | struct trace_array *tr; |
2340 | 2208 | ||
2341 | list_for_each_entry(tr, &ftrace_trace_arrays, list) { | 2209 | list_for_each_entry(tr, &ftrace_trace_arrays, list) { |
2342 | if (file_ops) | 2210 | __trace_add_new_event(call, tr, |
2343 | __trace_add_new_mod_event(call, tr, file_ops); | 2211 | &ftrace_event_id_fops, |
2344 | else | 2212 | &ftrace_enable_fops, |
2345 | __trace_add_new_event(call, tr, | 2213 | &ftrace_event_filter_fops, |
2346 | &ftrace_event_id_fops, | 2214 | &ftrace_event_format_fops); |
2347 | &ftrace_enable_fops, | ||
2348 | &ftrace_event_filter_fops, | ||
2349 | &ftrace_event_format_fops); | ||
2350 | } | 2215 | } |
2351 | } | 2216 | } |
2352 | 2217 | ||