@@ -3677,23 +3677,24 @@ static void __enable_ftrace_function_probe(struct ftrace_ops_hash *old_hash)
3677
3677
ftrace_probe_registered = 1 ;
3678
3678
}
3679
3679
3680
- static void __disable_ftrace_function_probe (void )
3680
+ static bool __disable_ftrace_function_probe (void )
3681
3681
{
3682
3682
int i ;
3683
3683
3684
3684
if (!ftrace_probe_registered )
3685
- return ;
3685
+ return false ;
3686
3686
3687
3687
for (i = 0 ; i < FTRACE_FUNC_HASHSIZE ; i ++ ) {
3688
3688
struct hlist_head * hhd = & ftrace_func_hash [i ];
3689
3689
if (hhd -> first )
3690
- return ;
3690
+ return false ;
3691
3691
}
3692
3692
3693
3693
/* no more funcs left */
3694
3694
ftrace_shutdown (& trace_probe_ops , 0 );
3695
3695
3696
3696
ftrace_probe_registered = 0 ;
3697
+ return true;
3697
3698
}
3698
3699
3699
3700
@@ -3820,6 +3821,7 @@ static void
3820
3821
__unregister_ftrace_function_probe (char * glob , struct ftrace_probe_ops * ops ,
3821
3822
void * data , int flags )
3822
3823
{
3824
+ struct ftrace_ops_hash old_hash_ops ;
3823
3825
struct ftrace_func_entry * rec_entry ;
3824
3826
struct ftrace_func_probe * entry ;
3825
3827
struct ftrace_func_probe * p ;
@@ -3831,6 +3833,7 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
3831
3833
struct hlist_node * tmp ;
3832
3834
char str [KSYM_SYMBOL_LEN ];
3833
3835
int i , ret ;
3836
+ bool disabled ;
3834
3837
3835
3838
if (glob && (strcmp (glob , "*" ) == 0 || !strlen (glob )))
3836
3839
func_g .search = NULL ;
@@ -3849,6 +3852,10 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
3849
3852
3850
3853
mutex_lock (& trace_probe_ops .func_hash -> regex_lock );
3851
3854
3855
+ old_hash_ops .filter_hash = old_hash ;
3856
+ /* Probes only have filters */
3857
+ old_hash_ops .notrace_hash = NULL ;
3858
+
3852
3859
hash = alloc_and_copy_ftrace_hash (FTRACE_HASH_DEFAULT_BITS , * orig_hash );
3853
3860
if (!hash )
3854
3861
/* Hmm, should report this somehow */
@@ -3886,12 +3893,17 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
3886
3893
}
3887
3894
}
3888
3895
mutex_lock (& ftrace_lock );
3889
- __disable_ftrace_function_probe ();
3896
+ disabled = __disable_ftrace_function_probe ();
3890
3897
/*
3891
3898
* Remove after the disable is called. Otherwise, if the last
3892
3899
* probe is removed, a null hash means *all enabled*.
3893
3900
*/
3894
3901
ret = ftrace_hash_move (& trace_probe_ops , 1 , orig_hash , hash );
3902
+
3903
+ /* still need to update the function call sites */
3904
+ if (ftrace_enabled && !disabled )
3905
+ ftrace_run_modify_code (& trace_probe_ops , FTRACE_UPDATE_CALLS ,
3906
+ & old_hash_ops );
3895
3907
synchronize_sched ();
3896
3908
if (!ret )
3897
3909
free_ftrace_hash_rcu (old_hash );
0 commit comments