@@ -1293,6 +1293,28 @@ static void ftrace_hash_clear(struct ftrace_hash *hash)
1293
1293
FTRACE_WARN_ON (hash -> count );
1294
1294
}
1295
1295
1296
+ static void free_ftrace_mod (struct ftrace_mod_load * ftrace_mod )
1297
+ {
1298
+ list_del (& ftrace_mod -> list );
1299
+ kfree (ftrace_mod -> module );
1300
+ kfree (ftrace_mod -> func );
1301
+ kfree (ftrace_mod );
1302
+ }
1303
+
1304
+ static void clear_ftrace_mod_list (struct list_head * head )
1305
+ {
1306
+ struct ftrace_mod_load * p , * n ;
1307
+
1308
+ /* stack tracer isn't supported yet */
1309
+ if (!head )
1310
+ return ;
1311
+
1312
+ mutex_lock (& ftrace_lock );
1313
+ list_for_each_entry_safe (p , n , head , list )
1314
+ free_ftrace_mod (p );
1315
+ mutex_unlock (& ftrace_lock );
1316
+ }
1317
+
1296
1318
static void free_ftrace_hash (struct ftrace_hash * hash )
1297
1319
{
1298
1320
if (!hash || hash == EMPTY_HASH )
@@ -1346,6 +1368,35 @@ static struct ftrace_hash *alloc_ftrace_hash(int size_bits)
1346
1368
return hash ;
1347
1369
}
1348
1370
1371
+
1372
+ static int ftrace_add_mod (struct trace_array * tr ,
1373
+ const char * func , const char * module ,
1374
+ int enable )
1375
+ {
1376
+ struct ftrace_mod_load * ftrace_mod ;
1377
+ struct list_head * mod_head = enable ? & tr -> mod_trace : & tr -> mod_notrace ;
1378
+
1379
+ ftrace_mod = kzalloc (sizeof (* ftrace_mod ), GFP_KERNEL );
1380
+ if (!ftrace_mod )
1381
+ return - ENOMEM ;
1382
+
1383
+ ftrace_mod -> func = kstrdup (func , GFP_KERNEL );
1384
+ ftrace_mod -> module = kstrdup (module , GFP_KERNEL );
1385
+ ftrace_mod -> enable = enable ;
1386
+
1387
+ if (!ftrace_mod -> func || !ftrace_mod -> module )
1388
+ goto out_free ;
1389
+
1390
+ list_add (& ftrace_mod -> list , mod_head );
1391
+
1392
+ return 0 ;
1393
+
1394
+ out_free :
1395
+ free_ftrace_mod (ftrace_mod );
1396
+
1397
+ return - ENOMEM ;
1398
+ }
1399
+
1349
1400
static struct ftrace_hash *
1350
1401
alloc_and_copy_ftrace_hash (int size_bits , struct ftrace_hash * hash )
1351
1402
{
@@ -3457,6 +3508,8 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag,
3457
3508
{
3458
3509
struct ftrace_iterator * iter ;
3459
3510
struct ftrace_hash * hash ;
3511
+ struct list_head * mod_head ;
3512
+ struct trace_array * tr = ops -> private ;
3460
3513
int ret = 0 ;
3461
3514
3462
3515
ftrace_ops_init (ops );
@@ -3478,18 +3531,23 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag,
3478
3531
3479
3532
mutex_lock (& ops -> func_hash -> regex_lock );
3480
3533
3481
- if (flag & FTRACE_ITER_NOTRACE )
3534
+ if (flag & FTRACE_ITER_NOTRACE ) {
3482
3535
hash = ops -> func_hash -> notrace_hash ;
3483
- else
3536
+ mod_head = tr ? & tr -> mod_trace : NULL ;
3537
+ } else {
3484
3538
hash = ops -> func_hash -> filter_hash ;
3539
+ mod_head = tr ? & tr -> mod_notrace : NULL ;
3540
+ }
3485
3541
3486
3542
if (file -> f_mode & FMODE_WRITE ) {
3487
3543
const int size_bits = FTRACE_HASH_DEFAULT_BITS ;
3488
3544
3489
- if (file -> f_flags & O_TRUNC )
3545
+ if (file -> f_flags & O_TRUNC ) {
3490
3546
iter -> hash = alloc_ftrace_hash (size_bits );
3491
- else
3547
+ clear_ftrace_mod_list (mod_head );
3548
+ } else {
3492
3549
iter -> hash = alloc_and_copy_ftrace_hash (size_bits , hash );
3550
+ }
3493
3551
3494
3552
if (!iter -> hash ) {
3495
3553
trace_parser_put (& iter -> parser );
@@ -3761,17 +3819,85 @@ static int ftrace_hash_move_and_update_ops(struct ftrace_ops *ops,
3761
3819
return ret ;
3762
3820
}
3763
3821
3822
+ static bool module_exists (const char * module )
3823
+ {
3824
+ /* All modules have the symbol __this_module */
3825
+ const char this_mod [] = "__this_module" ;
3826
+ const int modname_size = MAX_PARAM_PREFIX_LEN + sizeof (this_mod ) + 1 ;
3827
+ char modname [modname_size + 1 ];
3828
+ unsigned long val ;
3829
+ int n ;
3830
+
3831
+ n = snprintf (modname , modname_size + 1 , "%s:%s" , module , this_mod );
3832
+
3833
+ if (n > modname_size )
3834
+ return false;
3835
+
3836
+ val = module_kallsyms_lookup_name (modname );
3837
+ return val != 0 ;
3838
+ }
3839
+
3840
+ static int cache_mod (struct trace_array * tr ,
3841
+ const char * func , char * module , int enable )
3842
+ {
3843
+ struct ftrace_mod_load * ftrace_mod , * n ;
3844
+ struct list_head * head = enable ? & tr -> mod_trace : & tr -> mod_notrace ;
3845
+ int ret ;
3846
+
3847
+ mutex_lock (& ftrace_lock );
3848
+
3849
+ /* We do not cache inverse filters */
3850
+ if (func [0 ] == '!' ) {
3851
+ func ++ ;
3852
+ ret = - EINVAL ;
3853
+
3854
+ /* Look to remove this hash */
3855
+ list_for_each_entry_safe (ftrace_mod , n , head , list ) {
3856
+ if (strcmp (ftrace_mod -> module , module ) != 0 )
3857
+ continue ;
3858
+
3859
+ /* no func matches all */
3860
+ if (!func || strcmp (func , "*" ) == 0 ||
3861
+ (ftrace_mod -> func &&
3862
+ strcmp (ftrace_mod -> func , func ) == 0 )) {
3863
+ ret = 0 ;
3864
+ free_ftrace_mod (ftrace_mod );
3865
+ continue ;
3866
+ }
3867
+ }
3868
+ goto out ;
3869
+ }
3870
+
3871
+ ret = - EINVAL ;
3872
+ /* We only care about modules that have not been loaded yet */
3873
+ if (module_exists (module ))
3874
+ goto out ;
3875
+
3876
+ /* Save this string off, and execute it when the module is loaded */
3877
+ ret = ftrace_add_mod (tr , func , module , enable );
3878
+ out :
3879
+ mutex_unlock (& ftrace_lock );
3880
+
3881
+ return ret ;
3882
+ }
3883
+
3764
3884
/*
3765
3885
* We register the module command as a template to show others how
3766
3886
* to register the a command as well.
3767
3887
*/
3768
3888
3769
3889
static int
3770
3890
ftrace_mod_callback (struct trace_array * tr , struct ftrace_hash * hash ,
3771
- char * func , char * cmd , char * module , int enable )
3891
+ char * func_orig , char * cmd , char * module , int enable )
3772
3892
{
3893
+ char * func ;
3773
3894
int ret ;
3774
3895
3896
+ /* match_records() modifies func, and we need the original */
3897
+ func = kstrdup (func_orig , GFP_KERNEL );
3898
+ if (!func )
3899
+ return - ENOMEM ;
3900
+
3775
3901
/*
3776
3902
* cmd == 'mod' because we only registered this func
3777
3903
* for the 'mod' ftrace_func_command.
@@ -3780,8 +3906,10 @@ ftrace_mod_callback(struct trace_array *tr, struct ftrace_hash *hash,
3780
3906
* parameter.
3781
3907
*/
3782
3908
ret = match_records (hash , func , strlen (func ), module );
3909
+ kfree (func );
3910
+
3783
3911
if (!ret )
3784
- return - EINVAL ;
3912
+ return cache_mod ( tr , func_orig , module , enable ) ;
3785
3913
if (ret < 0 )
3786
3914
return ret ;
3787
3915
return 0 ;
@@ -5570,6 +5698,8 @@ static void ftrace_update_trampoline(struct ftrace_ops *ops)
5570
5698
void ftrace_init_trace_array (struct trace_array * tr )
5571
5699
{
5572
5700
INIT_LIST_HEAD (& tr -> func_probes );
5701
+ INIT_LIST_HEAD (& tr -> mod_trace );
5702
+ INIT_LIST_HEAD (& tr -> mod_notrace );
5573
5703
}
5574
5704
#else
5575
5705
0 commit comments