packaging: Add spec file for VisionFive2
[platform/kernel/linux-starfive.git] / include / linux / trace_recursion.h
index a9f9c57..fe95f09 100644 (file)
  *  When function tracing occurs, the following steps are made:
  *   If arch does not support a ftrace feature:
  *    call internal function (uses INTERNAL bits) which calls...
- *   If callback is registered to the "global" list, the list
- *    function is called and recursion checks the GLOBAL bits.
- *    then this function calls...
  *   The function callback, which can use the FTRACE bits to
  *    check for recursion.
- *
- * Now if the arch does not support a feature, and it calls
- * the global list function which calls the ftrace callback
- * all three of these steps will do a recursion protection.
- * There's no reason to do one if the previous caller already
- * did. The recursion that we are protecting against will
- * go through the same steps again.
- *
- * To prevent the multiple recursion checks, if a recursion
- * bit is set that is higher than the MAX bit of the current
- * check, then we know that the check was made by the previous
- * caller, and we can skip the current check.
  */
 enum {
        /* Function recursion bits */
@@ -40,12 +25,14 @@ enum {
        TRACE_FTRACE_NMI_BIT,
        TRACE_FTRACE_IRQ_BIT,
        TRACE_FTRACE_SIRQ_BIT,
+       TRACE_FTRACE_TRANSITION_BIT,
 
-       /* INTERNAL_BITs must be greater than FTRACE_BITs */
+       /* Internal use recursion bits */
        TRACE_INTERNAL_BIT,
        TRACE_INTERNAL_NMI_BIT,
        TRACE_INTERNAL_IRQ_BIT,
        TRACE_INTERNAL_SIRQ_BIT,
+       TRACE_INTERNAL_TRANSITION_BIT,
 
        TRACE_BRANCH_BIT,
 /*
@@ -86,12 +73,6 @@ enum {
         */
        TRACE_GRAPH_NOTRACE_BIT,
 
-       /*
-        * When transitioning between context, the preempt_count() may
-        * not be correct. Allow for a single recursion to cover this case.
-        */
-       TRACE_TRANSITION_BIT,
-
        /* Used to prevent recursion recording from recursing. */
        TRACE_RECORD_RECURSION_BIT,
 };
@@ -113,12 +94,10 @@ enum {
 #define TRACE_CONTEXT_BITS     4
 
 #define TRACE_FTRACE_START     TRACE_FTRACE_BIT
-#define TRACE_FTRACE_MAX       ((1 << (TRACE_FTRACE_START + TRACE_CONTEXT_BITS)) - 1)
 
 #define TRACE_LIST_START       TRACE_INTERNAL_BIT
-#define TRACE_LIST_MAX         ((1 << (TRACE_LIST_START + TRACE_CONTEXT_BITS)) - 1)
 
-#define TRACE_CONTEXT_MASK     TRACE_LIST_MAX
+#define TRACE_CONTEXT_MASK     ((1 << (TRACE_LIST_START + TRACE_CONTEXT_BITS)) - 1)
 
 /*
  * Used for setting context
@@ -132,6 +111,7 @@ enum {
        TRACE_CTX_IRQ,
        TRACE_CTX_SOFTIRQ,
        TRACE_CTX_NORMAL,
+       TRACE_CTX_TRANSITION,
 };
 
 static __always_inline int trace_get_context_bit(void)
@@ -160,45 +140,34 @@ extern void ftrace_record_recursion(unsigned long ip, unsigned long parent_ip);
 #endif
 
 static __always_inline int trace_test_and_set_recursion(unsigned long ip, unsigned long pip,
-                                                       int start, int max)
+                                                       int start)
 {
        unsigned int val = READ_ONCE(current->trace_recursion);
        int bit;
 
-       /* A previous recursion check was made */
-       if ((val & TRACE_CONTEXT_MASK) > max)
-               return 0;
-
        bit = trace_get_context_bit() + start;
        if (unlikely(val & (1 << bit))) {
                /*
                 * It could be that preempt_count has not been updated during
                 * a switch between contexts. Allow for a single recursion.
                 */
-               bit = TRACE_TRANSITION_BIT;
+               bit = TRACE_CTX_TRANSITION + start;
                if (val & (1 << bit)) {
                        do_ftrace_record_recursion(ip, pip);
                        return -1;
                }
-       } else {
-               /* Normal check passed, clear the transition to allow it again */
-               val &= ~(1 << TRACE_TRANSITION_BIT);
        }
 
        val |= 1 << bit;
        current->trace_recursion = val;
        barrier();
 
-       return bit + 1;
+       return bit;
 }
 
 static __always_inline void trace_clear_recursion(int bit)
 {
-       if (!bit)
-               return;
-
        barrier();
-       bit--;
        trace_recursion_clear(bit);
 }
 
@@ -214,7 +183,7 @@ static __always_inline void trace_clear_recursion(int bit)
 static __always_inline int ftrace_test_recursion_trylock(unsigned long ip,
                                                         unsigned long parent_ip)
 {
-       return trace_test_and_set_recursion(ip, parent_ip, TRACE_FTRACE_START, TRACE_FTRACE_MAX);
+       return trace_test_and_set_recursion(ip, parent_ip, TRACE_FTRACE_START);
 }
 
 /**