Skip to content

Commit 5985ea8

Browse files
committed
ftrace: Have the cached module list show in set_ftrace_filter
When writing in a module filter into set_ftrace_filter for a module that is not yet loaded, it it cached, and will be executed when the module is loaded (although that is not implemented yet at this commit). Display the list of cached modules to be traced. Signed-off-by: Steven Rostedt (VMware) <[email protected]>
1 parent 673feb9 commit 5985ea8

File tree

2 files changed

+102
-13
lines changed

2 files changed

+102
-13
lines changed

include/linux/ftrace.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,8 @@ enum {
446446
FTRACE_ITER_PRINTALL = (1 << 2),
447447
FTRACE_ITER_DO_PROBES = (1 << 3),
448448
FTRACE_ITER_PROBE = (1 << 4),
449-
FTRACE_ITER_ENABLED = (1 << 5),
449+
FTRACE_ITER_MOD = (1 << 5),
450+
FTRACE_ITER_ENABLED = (1 << 6),
450451
};
451452

452453
void arch_ftrace_update_code(int command);

kernel/trace/ftrace.c

Lines changed: 100 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3112,13 +3112,16 @@ ftrace_allocate_pages(unsigned long num_to_init)
31123112
struct ftrace_iterator {
31133113
loff_t pos;
31143114
loff_t func_pos;
3115+
loff_t mod_pos;
31153116
struct ftrace_page *pg;
31163117
struct dyn_ftrace *func;
31173118
struct ftrace_func_probe *probe;
31183119
struct ftrace_func_entry *probe_entry;
31193120
struct trace_parser parser;
31203121
struct ftrace_hash *hash;
31213122
struct ftrace_ops *ops;
3123+
struct trace_array *tr;
3124+
struct list_head *mod_list;
31223125
int pidx;
31233126
int idx;
31243127
unsigned flags;
@@ -3203,13 +3206,13 @@ static void *t_probe_start(struct seq_file *m, loff_t *pos)
32033206
if (!(iter->flags & FTRACE_ITER_DO_PROBES))
32043207
return NULL;
32053208

3206-
if (iter->func_pos > *pos)
3209+
if (iter->mod_pos > *pos)
32073210
return NULL;
32083211

32093212
iter->probe = NULL;
32103213
iter->probe_entry = NULL;
32113214
iter->pidx = 0;
3212-
for (l = 0; l <= (*pos - iter->func_pos); ) {
3215+
for (l = 0; l <= (*pos - iter->mod_pos); ) {
32133216
p = t_probe_next(m, &l);
32143217
if (!p)
32153218
break;
@@ -3247,6 +3250,82 @@ t_probe_show(struct seq_file *m, struct ftrace_iterator *iter)
32473250
return 0;
32483251
}
32493252

3253+
static void *
3254+
t_mod_next(struct seq_file *m, loff_t *pos)
3255+
{
3256+
struct ftrace_iterator *iter = m->private;
3257+
struct trace_array *tr = iter->tr;
3258+
3259+
(*pos)++;
3260+
iter->pos = *pos;
3261+
3262+
iter->mod_list = iter->mod_list->next;
3263+
3264+
if (iter->mod_list == &tr->mod_trace ||
3265+
iter->mod_list == &tr->mod_notrace) {
3266+
iter->flags &= ~FTRACE_ITER_MOD;
3267+
return NULL;
3268+
}
3269+
3270+
iter->mod_pos = *pos;
3271+
3272+
return iter;
3273+
}
3274+
3275+
static void *t_mod_start(struct seq_file *m, loff_t *pos)
3276+
{
3277+
struct ftrace_iterator *iter = m->private;
3278+
void *p = NULL;
3279+
loff_t l;
3280+
3281+
if (iter->func_pos > *pos)
3282+
return NULL;
3283+
3284+
iter->mod_pos = iter->func_pos;
3285+
3286+
/* probes are only available if tr is set */
3287+
if (!iter->tr)
3288+
return NULL;
3289+
3290+
for (l = 0; l <= (*pos - iter->func_pos); ) {
3291+
p = t_mod_next(m, &l);
3292+
if (!p)
3293+
break;
3294+
}
3295+
if (!p) {
3296+
iter->flags &= ~FTRACE_ITER_MOD;
3297+
return t_probe_start(m, pos);
3298+
}
3299+
3300+
/* Only set this if we have an item */
3301+
iter->flags |= FTRACE_ITER_MOD;
3302+
3303+
return iter;
3304+
}
3305+
3306+
static int
3307+
t_mod_show(struct seq_file *m, struct ftrace_iterator *iter)
3308+
{
3309+
struct ftrace_mod_load *ftrace_mod;
3310+
struct trace_array *tr = iter->tr;
3311+
3312+
if (WARN_ON_ONCE(!iter->mod_list) ||
3313+
iter->mod_list == &tr->mod_trace ||
3314+
iter->mod_list == &tr->mod_notrace)
3315+
return -EIO;
3316+
3317+
ftrace_mod = list_entry(iter->mod_list, struct ftrace_mod_load, list);
3318+
3319+
if (ftrace_mod->func)
3320+
seq_printf(m, "%s", ftrace_mod->func);
3321+
else
3322+
seq_putc(m, '*');
3323+
3324+
seq_printf(m, ":mod:%s\n", ftrace_mod->module);
3325+
3326+
return 0;
3327+
}
3328+
32503329
static void *
32513330
t_func_next(struct seq_file *m, loff_t *pos)
32523331
{
@@ -3288,7 +3367,7 @@ static void *
32883367
t_next(struct seq_file *m, void *v, loff_t *pos)
32893368
{
32903369
struct ftrace_iterator *iter = m->private;
3291-
loff_t l = *pos; /* t_hash_start() must use original pos */
3370+
loff_t l = *pos; /* t_probe_start() must use original pos */
32923371
void *ret;
32933372

32943373
if (unlikely(ftrace_disabled))
@@ -3297,16 +3376,19 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
32973376
if (iter->flags & FTRACE_ITER_PROBE)
32983377
return t_probe_next(m, pos);
32993378

3379+
if (iter->flags & FTRACE_ITER_MOD)
3380+
return t_mod_next(m, pos);
3381+
33003382
if (iter->flags & FTRACE_ITER_PRINTALL) {
33013383
/* next must increment pos, and t_probe_start does not */
33023384
(*pos)++;
3303-
return t_probe_start(m, &l);
3385+
return t_mod_start(m, &l);
33043386
}
33053387

33063388
ret = t_func_next(m, pos);
33073389

33083390
if (!ret)
3309-
return t_probe_start(m, &l);
3391+
return t_mod_start(m, &l);
33103392

33113393
return ret;
33123394
}
@@ -3315,7 +3397,7 @@ static void reset_iter_read(struct ftrace_iterator *iter)
33153397
{
33163398
iter->pos = 0;
33173399
iter->func_pos = 0;
3318-
iter->flags &= ~(FTRACE_ITER_PRINTALL | FTRACE_ITER_PROBE);
3400+
iter->flags &= ~(FTRACE_ITER_PRINTALL | FTRACE_ITER_PROBE | FTRACE_ITER_MOD);
33193401
}
33203402

33213403
static void *t_start(struct seq_file *m, loff_t *pos)
@@ -3344,15 +3426,15 @@ static void *t_start(struct seq_file *m, loff_t *pos)
33443426
ftrace_hash_empty(iter->hash)) {
33453427
iter->func_pos = 1; /* Account for the message */
33463428
if (*pos > 0)
3347-
return t_probe_start(m, pos);
3429+
return t_mod_start(m, pos);
33483430
iter->flags |= FTRACE_ITER_PRINTALL;
33493431
/* reset in case of seek/pread */
33503432
iter->flags &= ~FTRACE_ITER_PROBE;
33513433
return iter;
33523434
}
33533435

3354-
if (iter->flags & FTRACE_ITER_PROBE)
3355-
return t_probe_start(m, pos);
3436+
if (iter->flags & FTRACE_ITER_MOD)
3437+
return t_mod_start(m, pos);
33563438

33573439
/*
33583440
* Unfortunately, we need to restart at ftrace_pages_start
@@ -3368,7 +3450,7 @@ static void *t_start(struct seq_file *m, loff_t *pos)
33683450
}
33693451

33703452
if (!p)
3371-
return t_probe_start(m, pos);
3453+
return t_mod_start(m, pos);
33723454

33733455
return iter;
33743456
}
@@ -3402,6 +3484,9 @@ static int t_show(struct seq_file *m, void *v)
34023484
if (iter->flags & FTRACE_ITER_PROBE)
34033485
return t_probe_show(m, iter);
34043486

3487+
if (iter->flags & FTRACE_ITER_MOD)
3488+
return t_mod_show(m, iter);
3489+
34053490
if (iter->flags & FTRACE_ITER_PRINTALL) {
34063491
if (iter->flags & FTRACE_ITER_NOTRACE)
34073492
seq_puts(m, "#### no functions disabled ####\n");
@@ -3528,17 +3613,20 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag,
35283613

35293614
iter->ops = ops;
35303615
iter->flags = flag;
3616+
iter->tr = tr;
35313617

35323618
mutex_lock(&ops->func_hash->regex_lock);
35333619

35343620
if (flag & FTRACE_ITER_NOTRACE) {
35353621
hash = ops->func_hash->notrace_hash;
3536-
mod_head = tr ? &tr->mod_trace : NULL;
3622+
mod_head = tr ? &tr->mod_notrace : NULL;
35373623
} else {
35383624
hash = ops->func_hash->filter_hash;
3539-
mod_head = tr ? &tr->mod_notrace : NULL;
3625+
mod_head = tr ? &tr->mod_trace : NULL;
35403626
}
35413627

3628+
iter->mod_list = mod_head;
3629+
35423630
if (file->f_mode & FMODE_WRITE) {
35433631
const int size_bits = FTRACE_HASH_DEFAULT_BITS;
35443632

0 commit comments

Comments
 (0)