Skip to content

Commit 8c08f0d

Browse files
committed
ftrace: Have cached module filters be an active filter
When a module filter is added to set_ftrace_filter, if the module is not loaded, it is cached. This should be considered an active filter, and function tracing should be filtered by this. That is, if a cached module filter is the only filter set, then no function tracing should be happening, as all the functions available will be filtered out. This makes sense, as the reason to add a cached module filter, is to trace the module when you load it. There shouldn't be any other tracing happening until then. Signed-off-by: Steven Rostedt (VMware) <[email protected]>
1 parent d7fbf8d commit 8c08f0d

File tree

3 files changed

+23
-6
lines changed

3 files changed

+23
-6
lines changed

include/linux/ftrace.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ ftrace_func_t ftrace_ops_get_func(struct ftrace_ops *ops);
120120
* this ops will fail to register or set_filter_ip.
121121
* PID - Is affected by set_ftrace_pid (allows filtering on those pids)
122122
* RCU - Set when the ops can only be called when RCU is watching.
123+
* TRACE_ARRAY - The ops->private points to a trace_array descriptor.
123124
*/
124125
enum {
125126
FTRACE_OPS_FL_ENABLED = 1 << 0,
@@ -138,6 +139,7 @@ enum {
138139
FTRACE_OPS_FL_IPMODIFY = 1 << 13,
139140
FTRACE_OPS_FL_PID = 1 << 14,
140141
FTRACE_OPS_FL_RCU = 1 << 15,
142+
FTRACE_OPS_FL_TRACE_ARRAY = 1 << 16,
141143
};
142144

143145
#ifdef CONFIG_DYNAMIC_FTRACE

kernel/trace/ftrace.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,6 +1410,9 @@ alloc_and_copy_ftrace_hash(int size_bits, struct ftrace_hash *hash)
14101410
if (!new_hash)
14111411
return NULL;
14121412

1413+
if (hash)
1414+
new_hash->flags = hash->flags;
1415+
14131416
/* Empty hash? */
14141417
if (ftrace_hash_empty(hash))
14151418
return new_hash;
@@ -1454,7 +1457,7 @@ __ftrace_hash_move(struct ftrace_hash *src)
14541457
/*
14551458
* If the new source is empty, just return the empty_hash.
14561459
*/
1457-
if (!src->count)
1460+
if (ftrace_hash_empty(src))
14581461
return EMPTY_HASH;
14591462

14601463
/*
@@ -1471,6 +1474,8 @@ __ftrace_hash_move(struct ftrace_hash *src)
14711474
if (!new_hash)
14721475
return NULL;
14731476

1477+
new_hash->flags = src->flags;
1478+
14741479
size = 1 << src->size_bits;
14751480
for (i = 0; i < size; i++) {
14761481
hhd = &src->buckets[i];
@@ -1701,7 +1706,7 @@ static bool __ftrace_hash_rec_update(struct ftrace_ops *ops,
17011706
struct dyn_ftrace *rec;
17021707
bool update = false;
17031708
int count = 0;
1704-
int all = 0;
1709+
int all = false;
17051710

17061711
/* Only update if the ops has been registered */
17071712
if (!(ops->flags & FTRACE_OPS_FL_ENABLED))
@@ -1722,7 +1727,7 @@ static bool __ftrace_hash_rec_update(struct ftrace_ops *ops,
17221727
hash = ops->func_hash->filter_hash;
17231728
other_hash = ops->func_hash->notrace_hash;
17241729
if (ftrace_hash_empty(hash))
1725-
all = 1;
1730+
all = true;
17261731
} else {
17271732
inc = !inc;
17281733
hash = ops->func_hash->notrace_hash;
@@ -4028,6 +4033,9 @@ static void process_mod_list(struct list_head *head, struct ftrace_ops *ops,
40284033
free_ftrace_mod(ftrace_mod);
40294034
}
40304035

4036+
if (enable && list_empty(head))
4037+
new_hash->flags &= ~FTRACE_HASH_FL_MOD;
4038+
40314039
mutex_lock(&ftrace_lock);
40324040

40334041
ret = ftrace_hash_move_and_update_ops(ops, orig_hash,
@@ -5035,9 +5043,11 @@ int ftrace_regex_release(struct inode *inode, struct file *file)
50355043
if (file->f_mode & FMODE_WRITE) {
50365044
filter_hash = !!(iter->flags & FTRACE_ITER_FILTER);
50375045

5038-
if (filter_hash)
5046+
if (filter_hash) {
50395047
orig_hash = &iter->ops->func_hash->filter_hash;
5040-
else
5048+
if (!list_empty(&iter->tr->mod_trace))
5049+
iter->hash->flags |= FTRACE_HASH_FL_MOD;
5050+
} else
50415051
orig_hash = &iter->ops->func_hash->notrace_hash;
50425052

50435053
mutex_lock(&ftrace_lock);

kernel/trace/trace.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,10 +773,15 @@ struct ftrace_mod_load {
773773
int enable;
774774
};
775775

776+
enum {
777+
FTRACE_HASH_FL_MOD = (1 << 0),
778+
};
779+
776780
struct ftrace_hash {
777781
unsigned long size_bits;
778782
struct hlist_head *buckets;
779783
unsigned long count;
784+
unsigned long flags;
780785
struct rcu_head rcu;
781786
};
782787

@@ -785,7 +790,7 @@ ftrace_lookup_ip(struct ftrace_hash *hash, unsigned long ip);
785790

786791
static __always_inline bool ftrace_hash_empty(struct ftrace_hash *hash)
787792
{
788-
return !hash || !hash->count;
793+
return !hash || !(hash->count || (hash->flags & FTRACE_HASH_FL_MOD));
789794
}
790795

791796
/* Standard output formatting function used for function return traces */

0 commit comments

Comments
 (0)