Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ftrace: Export ftrace_free_filter() to modules

Setting filters on an ftrace ops results in some memory being allocated
for the filter hashes, which must be freed before the ops can be freed.
This can be done by removing every individual element of the hash by
calling ftrace_set_filter_ip() or ftrace_set_filter_ips() with `remove`
set, but this is somewhat error prone as it's easy to forget to remove
an element.

Make it easier to clean this up by exporting ftrace_free_filter(), which
can be used to clean up all of the filter hashes after an ftrace_ops has
been unregistered.

Using this, fix the ftrace-direct* samples to free hashes prior to being
unloaded. All other code either removes individual filters explicitly or
is built-in and already calls ftrace_free_filter().

Link: https://lkml.kernel.org/r/20230103124912.2948963-3-mark.rutland@arm.com

Cc: stable@vger.kernel.org
Cc: Florent Revest <revest@chromium.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Fixes: e1067a07cfbc ("ftrace/samples: Add module to test multi direct modify interface")
Fixes: 5fae941b9a6f ("ftrace/samples: Add multi direct interface test module")
Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>

authored by

Mark Rutland and committed by
Steven Rostedt (Google)
8be9fbd5 2241ab53

+24 -1
+22 -1
kernel/trace/ftrace.c
··· 1248 1248 call_rcu(&hash->rcu, __free_ftrace_hash_rcu); 1249 1249 } 1250 1250 1251 + /** 1252 + * ftrace_free_filter - remove all filters for an ftrace_ops 1253 + * @ops - the ops to remove the filters from 1254 + */ 1251 1255 void ftrace_free_filter(struct ftrace_ops *ops) 1252 1256 { 1253 1257 ftrace_ops_init(ops); 1254 1258 free_ftrace_hash(ops->func_hash->filter_hash); 1255 1259 free_ftrace_hash(ops->func_hash->notrace_hash); 1256 1260 } 1261 + EXPORT_SYMBOL_GPL(ftrace_free_filter); 1257 1262 1258 1263 static struct ftrace_hash *alloc_ftrace_hash(int size_bits) 1259 1264 { ··· 5844 5839 * 5845 5840 * Filters denote which functions should be enabled when tracing is enabled 5846 5841 * If @ip is NULL, it fails to update filter. 5842 + * 5843 + * This can allocate memory which must be freed before @ops can be freed, 5844 + * either by removing each filtered addr or by using 5845 + * ftrace_free_filter(@ops). 5847 5846 */ 5848 5847 int ftrace_set_filter_ip(struct ftrace_ops *ops, unsigned long ip, 5849 5848 int remove, int reset) ··· 5867 5858 * 5868 5859 * Filters denote which functions should be enabled when tracing is enabled 5869 5860 * If @ips array or any ip specified within is NULL , it fails to update filter. 5870 - */ 5861 + * 5862 + * This can allocate memory which must be freed before @ops can be freed, 5863 + * either by removing each filtered addr or by using 5864 + * ftrace_free_filter(@ops). 5865 + */ 5871 5866 int ftrace_set_filter_ips(struct ftrace_ops *ops, unsigned long *ips, 5872 5867 unsigned int cnt, int remove, int reset) 5873 5868 { ··· 5913 5900 * 5914 5901 * Filters denote which functions should be enabled when tracing is enabled. 5915 5902 * If @buf is NULL and reset is set, all functions will be enabled for tracing. 5903 + * 5904 + * This can allocate memory which must be freed before @ops can be freed, 5905 + * either by removing each filtered addr or by using 5906 + * ftrace_free_filter(@ops). 5916 5907 */ 5917 5908 int ftrace_set_filter(struct ftrace_ops *ops, unsigned char *buf, 5918 5909 int len, int reset) ··· 5936 5919 * Notrace Filters denote which functions should not be enabled when tracing 5937 5920 * is enabled. If @buf is NULL and reset is set, all functions will be enabled 5938 5921 * for tracing. 5922 + * 5923 + * This can allocate memory which must be freed before @ops can be freed, 5924 + * either by removing each filtered addr or by using 5925 + * ftrace_free_filter(@ops). 5939 5926 */ 5940 5927 int ftrace_set_notrace(struct ftrace_ops *ops, unsigned char *buf, 5941 5928 int len, int reset)
+1
samples/ftrace/ftrace-direct-multi-modify.c
··· 152 152 { 153 153 kthread_stop(simple_tsk); 154 154 unregister_ftrace_direct_multi(&direct, my_tramp); 155 + ftrace_free_filter(&direct); 155 156 } 156 157 157 158 module_init(ftrace_direct_multi_init);
+1
samples/ftrace/ftrace-direct-multi.c
··· 79 79 static void __exit ftrace_direct_multi_exit(void) 80 80 { 81 81 unregister_ftrace_direct_multi(&direct, (unsigned long) my_tramp); 82 + ftrace_free_filter(&direct); 82 83 } 83 84 84 85 module_init(ftrace_direct_multi_init);