@@ -3755,23 +3755,24 @@ static void __enable_ftrace_function_probe(struct ftrace_ops_hash *old_hash)
3755
3755
ftrace_probe_registered = 1 ;
3756
3756
}
3757
3757
3758
- static void __disable_ftrace_function_probe (void )
3758
+ static bool __disable_ftrace_function_probe (void )
3759
3759
{
3760
3760
int i ;
3761
3761
3762
3762
if (!ftrace_probe_registered )
3763
- return ;
3763
+ return false ;
3764
3764
3765
3765
for (i = 0 ; i < FTRACE_FUNC_HASHSIZE ; i ++ ) {
3766
3766
struct hlist_head * hhd = & ftrace_func_hash [i ];
3767
3767
if (hhd -> first )
3768
- return ;
3768
+ return false ;
3769
3769
}
3770
3770
3771
3771
/* no more funcs left */
3772
3772
ftrace_shutdown (& trace_probe_ops , 0 );
3773
3773
3774
3774
ftrace_probe_registered = 0 ;
3775
+ return true;
3775
3776
}
3776
3777
3777
3778
@@ -3901,6 +3902,7 @@ static void
3901
3902
__unregister_ftrace_function_probe (char * glob , struct ftrace_probe_ops * ops ,
3902
3903
void * data , int flags )
3903
3904
{
3905
+ struct ftrace_ops_hash old_hash_ops ;
3904
3906
struct ftrace_func_entry * rec_entry ;
3905
3907
struct ftrace_func_probe * entry ;
3906
3908
struct ftrace_func_probe * p ;
@@ -3912,6 +3914,7 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
3912
3914
struct hlist_node * tmp ;
3913
3915
char str [KSYM_SYMBOL_LEN ];
3914
3916
int i , ret ;
3917
+ bool disabled ;
3915
3918
3916
3919
if (glob && (strcmp (glob , "*" ) == 0 || !strlen (glob )))
3917
3920
func_g .search = NULL ;
@@ -3930,6 +3933,10 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
3930
3933
3931
3934
mutex_lock (& trace_probe_ops .func_hash -> regex_lock );
3932
3935
3936
+ old_hash_ops .filter_hash = old_hash ;
3937
+ /* Probes only have filters */
3938
+ old_hash_ops .notrace_hash = NULL ;
3939
+
3933
3940
hash = alloc_and_copy_ftrace_hash (FTRACE_HASH_DEFAULT_BITS , * orig_hash );
3934
3941
if (!hash )
3935
3942
/* Hmm, should report this somehow */
@@ -3967,12 +3974,17 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
3967
3974
}
3968
3975
}
3969
3976
mutex_lock (& ftrace_lock );
3970
- __disable_ftrace_function_probe ();
3977
+ disabled = __disable_ftrace_function_probe ();
3971
3978
/*
3972
3979
* Remove after the disable is called. Otherwise, if the last
3973
3980
* probe is removed, a null hash means *all enabled*.
3974
3981
*/
3975
3982
ret = ftrace_hash_move (& trace_probe_ops , 1 , orig_hash , hash );
3983
+
3984
+ /* still need to update the function call sites */
3985
+ if (ftrace_enabled && !disabled )
3986
+ ftrace_run_modify_code (& trace_probe_ops , FTRACE_UPDATE_CALLS ,
3987
+ & old_hash_ops );
3976
3988
synchronize_sched ();
3977
3989
if (!ret )
3978
3990
free_ftrace_hash_rcu (old_hash );
0 commit comments