@@ -5691,22 +5691,8 @@ int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr)
5691
5691
}
5692
5692
EXPORT_SYMBOL_GPL (unregister_ftrace_direct_multi );
5693
5693
5694
- /**
5695
- * modify_ftrace_direct_multi - Modify an existing direct 'multi' call
5696
- * to call something else
5697
- * @ops: The address of the struct ftrace_ops object
5698
- * @addr: The address of the new trampoline to call at @ops functions
5699
- *
5700
- * This is used to unregister currently registered direct caller and
5701
- * register new one @addr on functions registered in @ops object.
5702
- *
5703
- * Note there's window between ftrace_shutdown and ftrace_startup calls
5704
- * where there will be no callbacks called.
5705
- *
5706
- * Returns: zero on success. Non zero on error, which includes:
5707
- * -EINVAL - The @ops object was not properly registered.
5708
- */
5709
- int modify_ftrace_direct_multi (struct ftrace_ops * ops , unsigned long addr )
5694
+ static int
5695
+ __modify_ftrace_direct_multi (struct ftrace_ops * ops , unsigned long addr )
5710
5696
{
5711
5697
struct ftrace_hash * hash ;
5712
5698
struct ftrace_func_entry * entry , * iter ;
@@ -5717,20 +5703,15 @@ int modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr)
5717
5703
int i , size ;
5718
5704
int err ;
5719
5705
5720
- if (check_direct_multi (ops ))
5721
- return - EINVAL ;
5722
- if (!(ops -> flags & FTRACE_OPS_FL_ENABLED ))
5723
- return - EINVAL ;
5724
-
5725
- mutex_lock (& direct_mutex );
5706
+ lockdep_assert_held_once (& direct_mutex );
5726
5707
5727
5708
/* Enable the tmp_ops to have the same functions as the direct ops */
5728
5709
ftrace_ops_init (& tmp_ops );
5729
5710
tmp_ops .func_hash = ops -> func_hash ;
5730
5711
5731
5712
err = register_ftrace_function (& tmp_ops );
5732
5713
if (err )
5733
- goto out_direct ;
5714
+ return err ;
5734
5715
5735
5716
/*
5736
5717
* Now the ftrace_ops_list_func() is called to do the direct callers.
@@ -5754,7 +5735,64 @@ int modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr)
5754
5735
/* Removing the tmp_ops will add the updated direct callers to the functions */
5755
5736
unregister_ftrace_function (& tmp_ops );
5756
5737
5757
- out_direct :
5738
+ return err ;
5739
+ }
5740
+
5741
+ /**
5742
+ * modify_ftrace_direct_multi_nolock - Modify an existing direct 'multi' call
5743
+ * to call something else
5744
+ * @ops: The address of the struct ftrace_ops object
5745
+ * @addr: The address of the new trampoline to call at @ops functions
5746
+ *
5747
+ * This is used to unregister currently registered direct caller and
5748
+ * register new one @addr on functions registered in @ops object.
5749
+ *
5750
+ * Note there's window between ftrace_shutdown and ftrace_startup calls
5751
+ * where there will be no callbacks called.
5752
+ *
5753
+ * Caller should already have direct_mutex locked, so we don't lock
5754
+ * direct_mutex here.
5755
+ *
5756
+ * Returns: zero on success. Non zero on error, which includes:
5757
+ * -EINVAL - The @ops object was not properly registered.
5758
+ */
5759
+ int modify_ftrace_direct_multi_nolock (struct ftrace_ops * ops , unsigned long addr )
5760
+ {
5761
+ if (check_direct_multi (ops ))
5762
+ return - EINVAL ;
5763
+ if (!(ops -> flags & FTRACE_OPS_FL_ENABLED ))
5764
+ return - EINVAL ;
5765
+
5766
+ return __modify_ftrace_direct_multi (ops , addr );
5767
+ }
5768
+ EXPORT_SYMBOL_GPL (modify_ftrace_direct_multi_nolock );
5769
+
5770
+ /**
5771
+ * modify_ftrace_direct_multi - Modify an existing direct 'multi' call
5772
+ * to call something else
5773
+ * @ops: The address of the struct ftrace_ops object
5774
+ * @addr: The address of the new trampoline to call at @ops functions
5775
+ *
5776
+ * This is used to unregister currently registered direct caller and
5777
+ * register new one @addr on functions registered in @ops object.
5778
+ *
5779
+ * Note there's window between ftrace_shutdown and ftrace_startup calls
5780
+ * where there will be no callbacks called.
5781
+ *
5782
+ * Returns: zero on success. Non zero on error, which includes:
5783
+ * -EINVAL - The @ops object was not properly registered.
5784
+ */
5785
+ int modify_ftrace_direct_multi (struct ftrace_ops * ops , unsigned long addr )
5786
+ {
5787
+ int err ;
5788
+
5789
+ if (check_direct_multi (ops ))
5790
+ return - EINVAL ;
5791
+ if (!(ops -> flags & FTRACE_OPS_FL_ENABLED ))
5792
+ return - EINVAL ;
5793
+
5794
+ mutex_lock (& direct_mutex );
5795
+ err = __modify_ftrace_direct_multi (ops , addr );
5758
5796
mutex_unlock (& direct_mutex );
5759
5797
return err ;
5760
5798
}
0 commit comments