Merge tag 'drm-next-2020-12-24' of git://anongit.freedesktop.org/drm/drm
[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.
 
-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
@@ -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.
 
+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
 ================
@@ -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.
 
-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"