@@ -3740,23 +3740,24 @@ static void __enable_ftrace_function_probe(struct ftrace_ops_hash *old_hash)
3740
3740
ftrace_probe_registered = 1 ;
3741
3741
}
3742
3742
3743
- static void __disable_ftrace_function_probe (void )
3743
+ static bool __disable_ftrace_function_probe (void )
3744
3744
{
3745
3745
int i ;
3746
3746
3747
3747
if (!ftrace_probe_registered )
3748
- return ;
3748
+ return false ;
3749
3749
3750
3750
for (i = 0 ; i < FTRACE_FUNC_HASHSIZE ; i ++ ) {
3751
3751
struct hlist_head * hhd = & ftrace_func_hash [i ];
3752
3752
if (hhd -> first )
3753
- return ;
3753
+ return false ;
3754
3754
}
3755
3755
3756
3756
/* no more funcs left */
3757
3757
ftrace_shutdown (& trace_probe_ops , 0 );
3758
3758
3759
3759
ftrace_probe_registered = 0 ;
3760
+ return true;
3760
3761
}
3761
3762
3762
3763
@@ -3886,6 +3887,7 @@ static void
3886
3887
__unregister_ftrace_function_probe (char * glob , struct ftrace_probe_ops * ops ,
3887
3888
void * data , int flags )
3888
3889
{
3890
+ struct ftrace_ops_hash old_hash_ops ;
3889
3891
struct ftrace_func_entry * rec_entry ;
3890
3892
struct ftrace_func_probe * entry ;
3891
3893
struct ftrace_func_probe * p ;
@@ -3897,6 +3899,7 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
3897
3899
struct hlist_node * tmp ;
3898
3900
char str [KSYM_SYMBOL_LEN ];
3899
3901
int i , ret ;
3902
+ bool disabled ;
3900
3903
3901
3904
if (glob && (strcmp (glob , "*" ) == 0 || !strlen (glob )))
3902
3905
func_g .search = NULL ;
@@ -3915,6 +3918,10 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
3915
3918
3916
3919
mutex_lock (& trace_probe_ops .func_hash -> regex_lock );
3917
3920
3921
+ old_hash_ops .filter_hash = old_hash ;
3922
+ /* Probes only have filters */
3923
+ old_hash_ops .notrace_hash = NULL ;
3924
+
3918
3925
hash = alloc_and_copy_ftrace_hash (FTRACE_HASH_DEFAULT_BITS , * orig_hash );
3919
3926
if (!hash )
3920
3927
/* Hmm, should report this somehow */
@@ -3952,12 +3959,17 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
3952
3959
}
3953
3960
}
3954
3961
mutex_lock (& ftrace_lock );
3955
- __disable_ftrace_function_probe ();
3962
+ disabled = __disable_ftrace_function_probe ();
3956
3963
/*
3957
3964
* Remove after the disable is called. Otherwise, if the last
3958
3965
* probe is removed, a null hash means *all enabled*.
3959
3966
*/
3960
3967
ret = ftrace_hash_move (& trace_probe_ops , 1 , orig_hash , hash );
3968
+
3969
+ /* still need to update the function call sites */
3970
+ if (ftrace_enabled && !disabled )
3971
+ ftrace_run_modify_code (& trace_probe_ops , FTRACE_UPDATE_CALLS ,
3972
+ & old_hash_ops );
3961
3973
synchronize_sched ();
3962
3974
if (!ret )
3963
3975
free_ftrace_hash_rcu (old_hash );
0 commit comments