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