Merge tag 'timers-urgent-2020-12-27' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / Documentation / trace / ftrace-uses.rst
index a4955f7..f7d98ae 100644 (file)
@@ -30,8 +30,8 @@ The ftrace context
   This requires extra care to what can be done inside a callback. A callback
   can be called outside the protective scope of RCU.
 
   This requires extra care to what can be done inside a callback. A callback
   can be called outside the protective scope of RCU.
 
-The ftrace infrastructure has some protections against recursions and RCU
-but one must still be very careful how they use the callbacks.
+There are helper functions to help against recursion, and making sure
+RCU is watching. These are explained below.
 
 
 The ftrace_ops structure
 
 
 The ftrace_ops structure
@@ -108,6 +108,58 @@ The prototype of the callback function is as follows (as of v4.14):
        at the start of the function where ftrace was tracing. Otherwise it
        either contains garbage, or NULL.
 
        at the start of the function where ftrace was tracing. Otherwise it
        either contains garbage, or NULL.
 
+Protect your callback
+=====================
+
+As functions can be called from anywhere, and it is possible that a function
+called by a callback may also be traced, and call that same callback,
+recursion protection must be used. There are two helper functions that
+can help in this regard. If you start your code with:
+
+.. code-block:: c
+
+       int bit;
+
+       bit = ftrace_test_recursion_trylock(ip, parent_ip);
+       if (bit < 0)
+               return;
+
+and end it with:
+
+.. code-block:: c
+
+       ftrace_test_recursion_unlock(bit);
+
+The code in between will be safe to use, even if it ends up calling a
+function that the callback is tracing. Note, on success,
+ftrace_test_recursion_trylock() will disable preemption, and the
+ftrace_test_recursion_unlock() will enable it again (if it was previously
+enabled). The instruction pointer (ip) and its parent (parent_ip) is passed to
+ftrace_test_recursion_trylock() to record where the recursion happened
+(if CONFIG_FTRACE_RECORD_RECURSION is set).
+
+Alternatively, if the FTRACE_OPS_FL_RECURSION flag is set on the ftrace_ops
+(as explained below), then a helper trampoline will be used to test
+for recursion for the callback and no recursion test needs to be done.
+But this is at the expense of a slightly more overhead from an extra
+function call.
+
+If your callback accesses any data or critical section that requires RCU
+protection, it is best to make sure that RCU is "watching", otherwise
+that data or critical section will not be protected as expected. In this
+case add:
+
+.. code-block:: c
+
+       if (!rcu_is_watching())
+               return;
+
+Alternatively, if the FTRACE_OPS_FL_RCU flag is set on the ftrace_ops
+(as explained below), then a helper trampoline will be used to test
+for rcu_is_watching for the callback and no other test needs to be done.
+But this is at the expense of a slightly more overhead from an extra
+function call.
+
 
 The ftrace FLAGS
 ================
 
 The ftrace FLAGS
 ================
@@ -128,26 +180,20 @@ FTRACE_OPS_FL_SAVE_REGS_IF_SUPPORTED
        will not fail with this flag set. But the callback must check if
        regs is NULL or not to determine if the architecture supports it.
 
        will not fail with this flag set. But the callback must check if
        regs is NULL or not to determine if the architecture supports it.
 
-FTRACE_OPS_FL_RECURSION_SAFE
-       By default, a wrapper is added around the callback to
-       make sure that recursion of the function does not occur. That is,
-       if a function that is called as a result of the callback's execution
-       is also traced, ftrace will prevent the callback from being called
-       again. But this wrapper adds some overhead, and if the callback is
-       safe from recursion, it can set this flag to disable the ftrace
-       protection.
-
-       Note, if this flag is set, and recursion does occur, it could cause
-       the system to crash, and possibly reboot via a triple fault.
-
-       It is OK if another callback traces a function that is called by a
-       callback that is marked recursion safe. Recursion safe callbacks
-       must never trace any function that are called by the callback
-       itself or any nested functions that those functions call.
-
-       If this flag is set, it is possible that the callback will also
-       be called with preemption enabled (when CONFIG_PREEMPTION is set),
-       but this is not guaranteed.
+FTRACE_OPS_FL_RECURSION
+       By default, it is expected that the callback can handle recursion.
+       But if the callback is not that worried about overehead, then
+       setting this bit will add the recursion protection around the
+       callback by calling a helper function that will do the recursion
+       protection and only call the callback if it did not recurse.
+
+       Note, if this flag is not set, and recursion does occur, it could
+       cause the system to crash, and possibly reboot via a triple fault.
+
+       Not, if this flag is set, then the callback will always be called
+       with preemption disabled. If it is not set, then it is possible
+       (but not guaranteed) that the callback will be called in
+       preemptable context.
 
 FTRACE_OPS_FL_IPMODIFY
        Requires FTRACE_OPS_FL_SAVE_REGS set. If the callback is to "hijack"
 
 FTRACE_OPS_FL_IPMODIFY
        Requires FTRACE_OPS_FL_SAVE_REGS set. If the callback is to "hijack"