Skip to content

Commit 4f554e9

Browse files
Jiri OlsaAlexei Starovoitov
authored andcommitted
ftrace: Add ftrace_set_filter_ips function
Adding ftrace_set_filter_ips function to be able to set filter on multiple ip addresses at once. With the kprobe multi attach interface we have cases where we need to initialize ftrace_ops object with thousands of functions, so having single function diving into ftrace_hash_move_and_update_ops with ftrace_lock is faster. The functions ips are passed as unsigned long array with count. Signed-off-by: Jiri Olsa <[email protected]> Signed-off-by: Steven Rostedt (Google) <[email protected]> Tested-by: Steven Rostedt (Google) <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Link: https://lore.kernel.org/bpf/164735282673.1084943.18310504594134769804.stgit@devnote2
1 parent e0999c8 commit 4f554e9

File tree

2 files changed

+52
-9
lines changed

2 files changed

+52
-9
lines changed

include/linux/ftrace.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,8 @@ struct dyn_ftrace {
512512

513513
int ftrace_set_filter_ip(struct ftrace_ops *ops, unsigned long ip,
514514
int remove, int reset);
515+
int ftrace_set_filter_ips(struct ftrace_ops *ops, unsigned long *ips,
516+
unsigned int cnt, int remove, int reset);
515517
int ftrace_set_filter(struct ftrace_ops *ops, unsigned char *buf,
516518
int len, int reset);
517519
int ftrace_set_notrace(struct ftrace_ops *ops, unsigned char *buf,
@@ -802,6 +804,7 @@ static inline unsigned long ftrace_location(unsigned long ip)
802804
#define ftrace_regex_open(ops, flag, inod, file) ({ -ENODEV; })
803805
#define ftrace_set_early_filter(ops, buf, enable) do { } while (0)
804806
#define ftrace_set_filter_ip(ops, ip, remove, reset) ({ -ENODEV; })
807+
#define ftrace_set_filter_ips(ops, ips, cnt, remove, reset) ({ -ENODEV; })
805808
#define ftrace_set_filter(ops, buf, len, reset) ({ -ENODEV; })
806809
#define ftrace_set_notrace(ops, buf, len, reset) ({ -ENODEV; })
807810
#define ftrace_free_filter(ops) do { } while (0)

kernel/trace/ftrace.c

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4958,7 +4958,7 @@ ftrace_notrace_write(struct file *file, const char __user *ubuf,
49584958
}
49594959

49604960
static int
4961-
ftrace_match_addr(struct ftrace_hash *hash, unsigned long ip, int remove)
4961+
__ftrace_match_addr(struct ftrace_hash *hash, unsigned long ip, int remove)
49624962
{
49634963
struct ftrace_func_entry *entry;
49644964

@@ -4976,9 +4976,30 @@ ftrace_match_addr(struct ftrace_hash *hash, unsigned long ip, int remove)
49764976
return add_hash_entry(hash, ip);
49774977
}
49784978

4979+
static int
4980+
ftrace_match_addr(struct ftrace_hash *hash, unsigned long *ips,
4981+
unsigned int cnt, int remove)
4982+
{
4983+
unsigned int i;
4984+
int err;
4985+
4986+
for (i = 0; i < cnt; i++) {
4987+
err = __ftrace_match_addr(hash, ips[i], remove);
4988+
if (err) {
4989+
/*
4990+
* This expects the @hash is a temporary hash and if this
4991+
* fails the caller must free the @hash.
4992+
*/
4993+
return err;
4994+
}
4995+
}
4996+
return 0;
4997+
}
4998+
49794999
static int
49805000
ftrace_set_hash(struct ftrace_ops *ops, unsigned char *buf, int len,
4981-
unsigned long ip, int remove, int reset, int enable)
5001+
unsigned long *ips, unsigned int cnt,
5002+
int remove, int reset, int enable)
49825003
{
49835004
struct ftrace_hash **orig_hash;
49845005
struct ftrace_hash *hash;
@@ -5008,8 +5029,8 @@ ftrace_set_hash(struct ftrace_ops *ops, unsigned char *buf, int len,
50085029
ret = -EINVAL;
50095030
goto out_regex_unlock;
50105031
}
5011-
if (ip) {
5012-
ret = ftrace_match_addr(hash, ip, remove);
5032+
if (ips) {
5033+
ret = ftrace_match_addr(hash, ips, cnt, remove);
50135034
if (ret < 0)
50145035
goto out_regex_unlock;
50155036
}
@@ -5026,10 +5047,10 @@ ftrace_set_hash(struct ftrace_ops *ops, unsigned char *buf, int len,
50265047
}
50275048

50285049
static int
5029-
ftrace_set_addr(struct ftrace_ops *ops, unsigned long ip, int remove,
5030-
int reset, int enable)
5050+
ftrace_set_addr(struct ftrace_ops *ops, unsigned long *ips, unsigned int cnt,
5051+
int remove, int reset, int enable)
50315052
{
5032-
return ftrace_set_hash(ops, NULL, 0, ip, remove, reset, enable);
5053+
return ftrace_set_hash(ops, NULL, 0, ips, cnt, remove, reset, enable);
50335054
}
50345055

50355056
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
@@ -5634,10 +5655,29 @@ int ftrace_set_filter_ip(struct ftrace_ops *ops, unsigned long ip,
56345655
int remove, int reset)
56355656
{
56365657
ftrace_ops_init(ops);
5637-
return ftrace_set_addr(ops, ip, remove, reset, 1);
5658+
return ftrace_set_addr(ops, &ip, 1, remove, reset, 1);
56385659
}
56395660
EXPORT_SYMBOL_GPL(ftrace_set_filter_ip);
56405661

5662+
/**
5663+
* ftrace_set_filter_ips - set functions to filter on in ftrace by addresses
5664+
* @ops - the ops to set the filter with
5665+
* @ips - the array of addresses to add to or remove from the filter.
5666+
* @cnt - the number of addresses in @ips
5667+
* @remove - non zero to remove ips from the filter
5668+
* @reset - non zero to reset all filters before applying this filter.
5669+
*
5670+
* Filters denote which functions should be enabled when tracing is enabled
5671+
* If @ips array or any ip specified within is NULL , it fails to update filter.
5672+
*/
5673+
int ftrace_set_filter_ips(struct ftrace_ops *ops, unsigned long *ips,
5674+
unsigned int cnt, int remove, int reset)
5675+
{
5676+
ftrace_ops_init(ops);
5677+
return ftrace_set_addr(ops, ips, cnt, remove, reset, 1);
5678+
}
5679+
EXPORT_SYMBOL_GPL(ftrace_set_filter_ips);
5680+
56415681
/**
56425682
* ftrace_ops_set_global_filter - setup ops to use global filters
56435683
* @ops - the ops which will use the global filters
@@ -5659,7 +5699,7 @@ static int
56595699
ftrace_set_regex(struct ftrace_ops *ops, unsigned char *buf, int len,
56605700
int reset, int enable)
56615701
{
5662-
return ftrace_set_hash(ops, buf, len, 0, 0, reset, enable);
5702+
return ftrace_set_hash(ops, buf, len, NULL, 0, 0, reset, enable);
56635703
}
56645704

56655705
/**

0 commit comments

Comments
 (0)