[PATCH bpf-next v2 0/4] Add ftrace direct call for arm64

Xu Kuohai xukuohai at huawei.com
Fri Oct 7 03:13:36 PDT 2022


On 10/7/2022 12:29 AM, Steven Rostedt wrote:
> On Thu, 6 Oct 2022 18:19:12 +0200
> Florent Revest <revest at chromium.org> wrote:
> 
>> Sure, we can give this a try, I'll work on a macro that generates the
>> 7 callbacks and we can check how much that helps. My belief right now
>> is that ftrace's iteration over all ops on arm64 is where we lose most
>> time but now that we have numbers it's pretty easy to check hypothesis
>> :)
> 
> Ah, I forgot that's what Mark's code is doing. But yes, that needs to be
> fixed first. I forget that arm64 doesn't have the dedicated trampolines yet.
> 
> So, let's hold off until that is complete.
> 
> -- Steve
> 
> .


Here is the perf data I captured.

1. perf report

     99.94%     0.00%  ld-linux-aarch6  bench                                           [.] trigger_producer
             |
             ---trigger_producer
                |
                |--98.04%--syscall
                |          |
                |           --81.35%--el0t_64_sync
                |                     el0t_64_sync_handler
                |                     el0_svc
                |                     do_el0_svc
                |                     |
                |                     |--80.75%--el0_svc_common.constprop.0
                |                     |          |
                |                     |          |--49.70%--invoke_syscall
                |                     |          |          |
                |                     |          |           --46.66%--__arm64_sys_getpgid
                |                     |          |                     |
                |                     |          |                     |--40.73%--ftrace_call
                |                     |          |                     |          |
                |                     |          |                     |          |--38.71%--ftrace_ops_list_func
                |                     |          |                     |          |          |
                |                     |          |                     |          |          |--25.06%--fprobe_handler
                |                     |          |                     |          |          |          |
                |                     |          |                     |          |          |          |--13.20%--bpf_fprobe_entry
                |                     |          |                     |          |          |          |          |
                |                     |          |                     |          |          |          |           --11.47%--call_bpf_prog.isra.0
                |                     |          |                     |          |          |          |                     |
                |                     |          |                     |          |          |          |                     |--4.08%--__bpf_prog_exit
                |                     |          |                     |          |          |          |                     |          |
                |                     |          |                     |          |          |          |                     |           --0.87%--migrate_enable
                |                     |          |                     |          |          |          |                     |
                |                     |          |                     |          |          |          |                     |--2.46%--__bpf_prog_enter
                |                     |          |                     |          |          |          |                     |
                |                     |          |                     |          |          |          |                      --2.18%--bpf_prog_21856463590f61f1_bench_trigger_fentry
                |                     |          |                     |          |          |          |
                |                     |          |                     |          |          |          |--8.68%--rethook_trampoline_handler
                |                     |          |                     |          |          |          |
                |                     |          |                     |          |          |           --1.59%--rethook_try_get
                |                     |          |                     |          |          |                     |
                |                     |          |                     |          |          |                      --0.58%--rcu_is_watching
                |                     |          |                     |          |          |
                |                     |          |                     |          |          |--6.65%--rethook_trampoline_handler
                |                     |          |                     |          |          |
                |                     |          |                     |          |           --0.77%--rethook_recycle
                |                     |          |                     |          |
                |                     |          |                     |           --1.74%--hash_contains_ip.isra.0
                |                     |          |                     |
                |                     |          |                      --3.62%--find_task_by_vpid
                |                     |          |                                |
                |                     |          |                                 --2.75%--idr_find
                |                     |          |                                           |
                |                     |          |                                            --2.17%--__radix_tree_lookup
                |                     |          |
                |                     |           --1.30%--ftrace_caller
                |                     |
                |                      --0.60%--invoke_syscall
                |
                |--0.88%--0xffffb2807594
                |
                 --0.87%--syscall at plt


2. perf annotate

2.1 ftrace_caller

          : 39               SYM_CODE_START(ftrace_caller)
          : 40               bti     c
     0.00 :   ffff80000802e0c4:       bti     c
          :
          : 39               /* Save original SP */
          : 40               mov     x10, sp
     0.00 :   ffff80000802e0c8:       mov     x10, sp
          :
          : 42               /* Make room for pt_regs, plus two frame records */
          : 43               sub     sp, sp, #(FREGS_SIZE + 32)
     0.00 :   ffff80000802e0cc:       sub     sp, sp, #0x90
          :
          : 45               /* Save function arguments */
          : 46               stp     x0, x1, [sp, #FREGS_X0]
     0.00 :   ffff80000802e0d0:       stp     x0, x1, [sp]
          : 45               stp     x2, x3, [sp, #FREGS_X2]
     0.00 :   ffff80000802e0d4:       stp     x2, x3, [sp, #16]
          : 46               stp     x4, x5, [sp, #FREGS_X4]
    16.67 :   ffff80000802e0d8:       stp     x4, x5, [sp, #32] // entry-ftrace.S:46
          : 47               stp     x6, x7, [sp, #FREGS_X6]
     8.33 :   ffff80000802e0dc:       stp     x6, x7, [sp, #48] // entry-ftrace.S:47
          : 48               str     x8,     [sp, #FREGS_X8]
     0.00 :   ffff80000802e0e0:       str     x8, [sp, #64]
          :
          : 52               /* Save the callsite's FP, LR, SP */
          : 53               str     x29, [sp, #FREGS_FP]
     8.33 :   ffff80000802e0e4:       str     x29, [sp, #80] // entry-ftrace.S:51
          : 52               str     x9,  [sp, #FREGS_LR]
     8.33 :   ffff80000802e0e8:       str     x9, [sp, #88] // entry-ftrace.S:52
          : 53               str     x10, [sp, #FREGS_SP]
     0.00 :   ffff80000802e0ec:       str     x10, [sp, #96]
          :
          : 57               /* Save the PC after the ftrace callsite */
          : 58               str     x30, [sp, #FREGS_PC]
    16.67 :   ffff80000802e0f0:       str     x30, [sp, #104] // entry-ftrace.S:56
          :
          : 60               /* Create a frame record for the callsite above the ftrace regs */
          : 61               stp     x29, x9, [sp, #FREGS_SIZE + 16]
    16.67 :   ffff80000802e0f4:       stp     x29, x9, [sp, #128] // entry-ftrace.S:59
          : 60               add     x29, sp, #FREGS_SIZE + 16
     0.00 :   ffff80000802e0f8:       add     x29, sp, #0x80
          :
          : 64               /* Create our frame record above the ftrace regs */
          : 65               stp     x29, x30, [sp, #FREGS_SIZE]
    16.67 :   ffff80000802e0fc:       stp     x29, x30, [sp, #112] // entry-ftrace.S:63
          : 64               add     x29, sp, #FREGS_SIZE
     0.00 :   ffff80000802e100:       add     x29, sp, #0x70
          :
          : 67               sub     x0, x30, #AARCH64_INSN_SIZE     // ip (callsite's BL insn)
     0.00 :   ffff80000802e104:       sub     x0, x30, #0x4
          : 67               mov     x1, x9                          // parent_ip (callsite's LR)
     0.00 :   ffff80000802e108:       mov     x1, x9
          : 68               ldr_l   x2, function_trace_op           // op
     0.00 :   ffff80000802e10c:       adrp    x2, ffff800009638000 <folio_wait_table+0x14c0>
     0.00 :   ffff80000802e110:       ldr     x2, [x2, #3320]
          : 69               mov     x3, sp                          // regs
     0.00 :   ffff80000802e114:       mov     x3, sp
          :
          : 72               ffff80000802e118 <ftrace_call>:
          :
          : 73               SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL)
          : 74               bl      ftrace_stub
     0.00 :   ffff80000802e118:       bl      ffff80000802e144 <ftrace_stub>
          : 80               * At the callsite x0-x8 and x19-x30 were live. Any C code will have preserved
          : 81               * x19-x29 per the AAPCS, and we created frame records upon entry, so we need
          : 82               * to restore x0-x8, x29, and x30.
          : 83               */
          : 84               /* Restore function arguments */
          : 85               ldp     x0, x1, [sp, #FREGS_X0]
     8.33 :   ffff80000802e11c:       ldp     x0, x1, [sp] // entry-ftrace.S:80
          : 81               ldp     x2, x3, [sp, #FREGS_X2]
     0.00 :   ffff80000802e120:       ldp     x2, x3, [sp, #16]
          : 82               ldp     x4, x5, [sp, #FREGS_X4]
     0.00 :   ffff80000802e124:       ldp     x4, x5, [sp, #32]
          : 83               ldp     x6, x7, [sp, #FREGS_X6]
     0.00 :   ffff80000802e128:       ldp     x6, x7, [sp, #48]
          : 84               ldr     x8,     [sp, #FREGS_X8]
     0.00 :   ffff80000802e12c:       ldr     x8, [sp, #64]
          :
          : 88               /* Restore the callsite's FP, LR, PC */
          : 89               ldr     x29, [sp, #FREGS_FP]
     0.00 :   ffff80000802e130:       ldr     x29, [sp, #80]
          : 88               ldr     x30, [sp, #FREGS_LR]
     0.00 :   ffff80000802e134:       ldr     x30, [sp, #88]
          : 89               ldr     x9,  [sp, #FREGS_PC]
     0.00 :   ffff80000802e138:       ldr     x9, [sp, #104]
          :
          : 93               /* Restore the callsite's SP */
          : 94               add     sp, sp, #FREGS_SIZE + 32
     0.00 :   ffff80000802e13c:       add     sp, sp, #0x90
          :
          : 95               ret     x9
     0.00 :   ffff80000802e140:       ret     x9


2.2 arch_ftrace_ops_list_func

          : 7554             void arch_ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip,
          : 7555             struct ftrace_ops *op, struct ftrace_regs *fregs)
          : 7556             {
     0.00 :   ffff80000815bdf0:       paciasp
     4.65 :   ffff80000815bdf4:       stp     x29, x30, [sp, #-144]! // ftrace.c:7551
     0.00 :   ffff80000815bdf8:       mrs     x2, sp_el0
     0.00 :   ffff80000815bdfc:       mov     x29, sp
     2.32 :   ffff80000815be00:       stp     x19, x20, [sp, #16]
     0.00 :   ffff80000815be04:       mov     x20, x1
          : 7563             trace_test_and_set_recursion():
          : 147              int start)
          : 148              {
          : 149              unsigned int val = READ_ONCE(current->trace_recursion);
          : 150              int bit;
          :
          : 152              bit = trace_get_context_bit() + start;
     0.00 :   ffff80000815be08:       mov     w5, #0x8                        // #8
          : 154              arch_ftrace_ops_list_func():
     0.00 :   ffff80000815be0c:       stp     x21, x22, [sp, #32]
     0.00 :   ffff80000815be10:       mov     x21, x3
     2.32 :   ffff80000815be14:       stp     x23, x24, [sp, #48]
     0.00 :   ffff80000815be18:       mov     x23, x0
     0.00 :   ffff80000815be1c:       ldr     x4, [x2, #1168]
     2.32 :   ffff80000815be20:       str     x4, [sp, #136]
     0.00 :   ffff80000815be24:       mov     x4, #0x0                        // #0
          : 7558             trace_test_and_set_recursion():
          : 148              if (unlikely(val & (1 << bit))) {
     0.00 :   ffff80000815be28:       mov     w2, #0x1                        // #1
          : 150              get_current():
          : 19               */
          : 20               static __always_inline struct task_struct *get_current(void)
          : 21               {
          : 22               unsigned long sp_el0;
          :
          : 24               asm ("mrs %0, sp_el0" : "=r" (sp_el0));
     0.00 :   ffff80000815be2c:       mrs     x4, sp_el0
          : 26               trace_test_and_set_recursion():
          : 144              unsigned int val = READ_ONCE(current->trace_recursion);
     0.00 :   ffff80000815be30:       ldr     x7, [x4, #2520]
          : 146              preempt_count():
          : 13               #define PREEMPT_NEED_RESCHED    BIT(32)
          : 14               #define PREEMPT_ENABLED (PREEMPT_NEED_RESCHED)
          :
          : 16               static inline int preempt_count(void)
          : 17               {
          : 18               return READ_ONCE(current_thread_info()->preempt.count);
     0.00 :   ffff80000815be34:       ldr     w6, [x4, #8]
          : 20               interrupt_context_level():
          : 94               static __always_inline unsigned char interrupt_context_level(void)
          : 95               {
          : 96               unsigned long pc = preempt_count();
          : 97               unsigned char level = 0;
          :
          : 99               level += !!(pc & (NMI_MASK));
     0.00 :   ffff80000815be38:       tst     w6, #0xf00000
          : 96               level += !!(pc & (NMI_MASK | HARDIRQ_MASK));
          : 97               level += !!(pc & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET));
     0.00 :   ffff80000815be3c:       and     w1, w6, #0xffff00
          : 94               level += !!(pc & (NMI_MASK));
     0.00 :   ffff80000815be40:       cset    w4, ne  // ne = any
          : 96               level += !!(pc & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET));
     0.00 :   ffff80000815be44:       and     w1, w1, #0xffff01ff
          : 95               level += !!(pc & (NMI_MASK | HARDIRQ_MASK));
     0.00 :   ffff80000815be48:       tst     w6, #0xff0000
     0.00 :   ffff80000815be4c:       cinc    w4, w4, ne      // ne = any
          : 96               level += !!(pc & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET));
     0.00 :   ffff80000815be50:       cmp     w1, #0x0
          : 98               trace_get_context_bit():
          : 121              return TRACE_CTX_NORMAL - bit;
     0.00 :   ffff80000815be54:       cinc    w4, w4, ne      // ne = any
          : 123              trace_test_and_set_recursion():
          : 147              bit = trace_get_context_bit() + start;
     0.00 :   ffff80000815be58:       sub     w5, w5, w4
          : 148              if (unlikely(val & (1 << bit))) {
     0.00 :   ffff80000815be5c:       lsl     w2, w2, w5
     0.00 :   ffff80000815be60:       tst     w2, w7
     0.00 :   ffff80000815be64:       b.ne    ffff80000815bf84 <arch_ftrace_ops_list_func+0x194>  // b.any
          : 152              trace_clear_recursion():
          : 180              */
          : 181              static __always_inline void trace_clear_recursion(int bit)
          : 182              {
          : 183              preempt_enable_notrace();
          : 184              barrier();
          : 185              trace_recursion_clear(bit);
     4.65 :   ffff80000815be68:       mvn     w22, w2 // trace_recursion.h:180
     0.00 :   ffff80000815be6c:       str     x25, [sp, #64]
     0.00 :   ffff80000815be70:       sxtw    x22, w22
          : 189              trace_test_and_set_recursion():
          : 165              current->trace_recursion = val;
     0.00 :   ffff80000815be74:       orr     w2, w2, w7
          : 167              get_current():
     0.00 :   ffff80000815be78:       mrs     x4, sp_el0
          : 20               trace_test_and_set_recursion():
     2.32 :   ffff80000815be7c:       str     x2, [x4, #2520] // trace_recursion.h:165
          : 166              __preempt_count_add():
          : 47               return !current_thread_info()->preempt.need_resched;
          : 48               }
          :
          : 50               static inline void __preempt_count_add(int val)
          : 51               {
          : 52               u32 pc = READ_ONCE(current_thread_info()->preempt.count);
     0.00 :   ffff80000815be80:       ldr     w1, [x4, #8]
          : 48               pc += val;
     0.00 :   ffff80000815be84:       add     w1, w1, #0x1
          : 49               WRITE_ONCE(current_thread_info()->preempt.count, pc);
     2.32 :   ffff80000815be88:       str     w1, [x4, #8] // preempt.h:49
          : 51               __ftrace_ops_list_func():
          : 7506             do_for_each_ftrace_op(op, ftrace_ops_list) {
     0.00 :   ffff80000815be8c:       adrp    x0, ffff800009638000 <folio_wait_table+0x14c0>
     0.00 :   ffff80000815be90:       add     x25, x0, #0xc28
          : 7527             } while_for_each_ftrace_op(op);
     0.00 :   ffff80000815be94:       add     x24, x25, #0x8
          : 7506             do_for_each_ftrace_op(op, ftrace_ops_list) {
     0.00 :   ffff80000815be98:       ldr     x19, [x0, #3112]
          : 7508             if (op->flags & FTRACE_OPS_FL_STUB)
     4.72 :   ffff80000815be9c:       ldr     x0, [x19, #16] // ftrace.c:7508
     0.00 :   ffff80000815bea0:       tbnz    w0, #5, ffff80000815bef8 <arch_ftrace_ops_list_func+0x108>
          : 7519             if ((!(op->flags & FTRACE_OPS_FL_RCU) || rcu_is_watching()) &&
     2.32 :   ffff80000815bea4:       tbnz    w0, #14, ffff80000815bf74 <arch_ftrace_ops_list_func+0x184> // ftrace.c:7519
          : 7521             ftrace_ops_test():
          : 1486             rcu_assign_pointer(hash.filter_hash, ops->func_hash->filter_hash);
     2.32 :   ffff80000815bea8:       ldr     x0, [x19, #88] // ftrace.c:1486
     0.00 :   ffff80000815beac:       add     x1, sp, #0x60
     0.00 :   ffff80000815beb0:       ldr     x0, [x0, #8]
     0.00 :   ffff80000815beb4:       stlr    x0, [x1]
          : 1487             rcu_assign_pointer(hash.notrace_hash, ops->func_hash->notrace_hash);
     0.00 :   ffff80000815beb8:       ldr     x0, [x19, #88]
     0.00 :   ffff80000815bebc:       add     x1, sp, #0x58
     0.00 :   ffff80000815bec0:       ldr     x0, [x0]
     2.32 :   ffff80000815bec4:       stlr    x0, [x1] // ftrace.c:1487
          : 1489             if (hash_contains_ip(ip, &hash))
    44.15 :   ffff80000815bec8:       ldp     x1, x2, [sp, #88] // ftrace.c:1489
     0.00 :   ffff80000815becc:       mov     x0, x23
     0.00 :   ffff80000815bed0:       bl      ffff80000815b530 <hash_contains_ip.isra.0>
     0.00 :   ffff80000815bed4:       tst     w0, #0xff
     0.00 :   ffff80000815bed8:       b.eq    ffff80000815bef8 <arch_ftrace_ops_list_func+0x108>  // b.none
          : 1495             __ftrace_ops_list_func():
          : 7521             if (FTRACE_WARN_ON(!op->func)) {
     0.00 :   ffff80000815bedc:       ldr     x4, [x19]
     0.00 :   ffff80000815bee0:       cbz     x4, ffff80000815bfa0 <arch_ftrace_ops_list_func+0x1b0>
          : 7525             op->func(ip, parent_ip, op, fregs);
     0.00 :   ffff80000815bee4:       mov     x3, x21
     0.00 :   ffff80000815bee8:       mov     x2, x19
     0.00 :   ffff80000815beec:       mov     x1, x20
     0.00 :   ffff80000815bef0:       mov     x0, x23
     0.00 :   ffff80000815bef4:       blr     x4
          : 7527             } while_for_each_ftrace_op(op);
     0.00 :   ffff80000815bef8:       ldr     x19, [x19, #8]
     0.00 :   ffff80000815befc:       cmp     x19, #0x0
     0.00 :   ffff80000815bf00:       ccmp    x19, x24, #0x4, ne      // ne = any
     0.00 :   ffff80000815bf04:       b.ne    ffff80000815be9c <arch_ftrace_ops_list_func+0xac>  // b.any
          : 7532             get_current():
     0.00 :   ffff80000815bf08:       mrs     x1, sp_el0
          : 20               __preempt_count_dec_and_test():
          : 62               }
          :
          : 64               static inline bool __preempt_count_dec_and_test(void)
          : 65               {
          : 66               struct thread_info *ti = current_thread_info();
          : 67               u64 pc = READ_ONCE(ti->preempt_count);
     0.00 :   ffff80000815bf0c:       ldr     x0, [x1, #8]
          :
          : 66               /* Update only the count field, leaving need_resched unchanged */
          : 67               WRITE_ONCE(ti->preempt.count, --pc);
     0.00 :   ffff80000815bf10:       sub     x0, x0, #0x1
     0.00 :   ffff80000815bf14:       str     w0, [x1, #8]
          : 74               * need of a reschedule. Otherwise, we need to reload the
          : 75               * preempt_count in case the need_resched flag was cleared by an
          : 76               * interrupt occurring between the non-atomic READ_ONCE/WRITE_ONCE
          : 77               * pair.
          : 78               */
          : 79               return !pc || !READ_ONCE(ti->preempt_count);
     0.00 :   ffff80000815bf18:       cbnz    x0, ffff80000815bf64 <arch_ftrace_ops_list_func+0x174>
          : 81               trace_clear_recursion():
          : 178              preempt_enable_notrace();
     0.00 :   ffff80000815bf1c:       bl      ffff800008ae88d0 <preempt_schedule_notrace>
          : 180              get_current():
     2.32 :   ffff80000815bf20:       mrs     x1, sp_el0 // current.h:19
          : 20               trace_clear_recursion():
          : 180              trace_recursion_clear(bit);
     0.00 :   ffff80000815bf24:       ldr     x0, [x1, #2520]
     0.00 :   ffff80000815bf28:       and     x0, x0, x22
     2.32 :   ffff80000815bf2c:       str     x0, [x1, #2520] // trace_recursion.h:180
          : 184              arch_ftrace_ops_list_func():
          : 7553             __ftrace_ops_list_func(ip, parent_ip, NULL, fregs);
          : 7554             }
     0.00 :   ffff80000815bf30:       ldr     x25, [sp, #64]
     0.00 :   ffff80000815bf34:       mrs     x0, sp_el0
     2.32 :   ffff80000815bf38:       ldr     x2, [sp, #136] // ftrace.c:7553
     0.00 :   ffff80000815bf3c:       ldr     x1, [x0, #1168]
     0.00 :   ffff80000815bf40:       subs    x2, x2, x1
     0.00 :   ffff80000815bf44:       mov     x1, #0x0                        // #0
     0.00 :   ffff80000815bf48:       b.ne    ffff80000815bf98 <arch_ftrace_ops_list_func+0x1a8>  // b.any
     2.32 :   ffff80000815bf4c:       ldp     x19, x20, [sp, #16]
     0.00 :   ffff80000815bf50:       ldp     x21, x22, [sp, #32]
     2.32 :   ffff80000815bf54:       ldp     x23, x24, [sp, #48]
     0.00 :   ffff80000815bf58:       ldp     x29, x30, [sp], #144
     0.00 :   ffff80000815bf5c:       autiasp
     0.00 :   ffff80000815bf60:       ret
          : 7568             __preempt_count_dec_and_test():
    11.62 :   ffff80000815bf64:       ldr     x0, [x1, #8] // preempt.h:74
     0.00 :   ffff80000815bf68:       cbnz    x0, ffff80000815bf20 <arch_ftrace_ops_list_func+0x130>
          : 76               trace_clear_recursion():
          : 178              preempt_enable_notrace();
     0.00 :   ffff80000815bf6c:       bl      ffff800008ae88d0 <preempt_schedule_notrace>
     0.00 :   ffff80000815bf70:       b       ffff80000815bf20 <arch_ftrace_ops_list_func+0x130>
          : 181              __ftrace_ops_list_func():
          : 7519             if ((!(op->flags & FTRACE_OPS_FL_RCU) || rcu_is_watching()) &&
     0.00 :   ffff80000815bf74:       bl      ffff8000080e5770 <rcu_is_watching>
     0.00 :   ffff80000815bf78:       tst     w0, #0xff
     0.00 :   ffff80000815bf7c:       b.ne    ffff80000815bea8 <arch_ftrace_ops_list_func+0xb8>  // b.any
     0.00 :   ffff80000815bf80:       b       ffff80000815bef8 <arch_ftrace_ops_list_func+0x108>
          : 7524             trace_test_and_set_recursion():
          : 158              if (val & (1 << bit)) {
     0.00 :   ffff80000815bf84:       tbnz    w7, #9, ffff80000815bf34 <arch_ftrace_ops_list_func+0x144>
     0.00 :   ffff80000815bf88:       mov     x22, #0xfffffffffffffdff        // #-513
     0.00 :   ffff80000815bf8c:       mov     w2, #0x200                      // #512
     0.00 :   ffff80000815bf90:       str     x25, [sp, #64]
     0.00 :   ffff80000815bf94:       b       ffff80000815be74 <arch_ftrace_ops_list_func+0x84>
     0.00 :   ffff80000815bf98:       str     x25, [sp, #64]
          : 165              arch_ftrace_ops_list_func():
          : 7553             }
     0.00 :   ffff80000815bf9c:       bl      ffff800008ae5de0 <__stack_chk_fail>
          : 7555             __ftrace_ops_list_func():
          : 7521             if (FTRACE_WARN_ON(!op->func)) {
     0.00 :   ffff80000815bfa0:       brk     #0x800
          : 7523             ftrace_kill():
          : 8040             */
          : 8041             void ftrace_kill(void)
          : 8042             {
          : 8043             ftrace_disabled = 1;
          : 8044             ftrace_enabled = 0;
          : 8045             ftrace_trace_function = ftrace_stub;
     0.00 :   ffff80000815bfa4:       adrp    x3, ffff80000802e000 <arch_ftrace_update_code+0x10>
     0.00 :   ffff80000815bfa8:       add     x3, x3, #0x144
          : 8038             ftrace_disabled = 1;
     0.00 :   ffff80000815bfac:       mov     w4, #0x1                        // #1
          : 8040             __ftrace_ops_list_func():
          : 7522             pr_warn("op=%p %pS\n", op, op);
     0.00 :   ffff80000815bfb0:       mov     x2, x19
     0.00 :   ffff80000815bfb4:       mov     x1, x19
     0.00 :   ffff80000815bfb8:       adrp    x0, ffff800008d80000 <kallsyms_token_index+0x17f60>
     0.00 :   ffff80000815bfbc:       add     x0, x0, #0x678
          : 7527             ftrace_kill():
          : 8040             ftrace_trace_function = ftrace_stub;
     0.00 :   ffff80000815bfc0:       str     x3, [x25, #192]
          : 8039             ftrace_enabled = 0;
     0.00 :   ffff80000815bfc4:       stp     w4, wzr, [x25, #200]
          : 8041             __ftrace_ops_list_func():
          : 7522             pr_warn("op=%p %pS\n", op, op);
     0.00 :   ffff80000815bfc8:       bl      ffff800008ad5220 <_printk>
          : 7523             goto out;
     0.00 :   ffff80000815bfcc:       b       ffff80000815bf08 <arch_ftrace_ops_list_func+0x118>


2.3 fprobe_handler

          : 28               static void fprobe_handler(unsigned long ip, unsigned long parent_ip,
          : 29               struct ftrace_ops *ops, struct ftrace_regs *fregs)
          : 30               {
     0.00 :   ffff8000081a2020:       paciasp
     0.00 :   ffff8000081a2024:       stp     x29, x30, [sp, #-64]!
     0.00 :   ffff8000081a2028:       mov     x29, sp
     0.00 :   ffff8000081a202c:       stp     x19, x20, [sp, #16]
     0.00 :   ffff8000081a2030:       mov     x19, x2
     0.00 :   ffff8000081a2034:       stp     x21, x22, [sp, #32]
     0.00 :   ffff8000081a2038:       mov     x22, x3
     0.00 :   ffff8000081a203c:       str     x23, [sp, #48]
     0.00 :   ffff8000081a2040:       mov     x23, x0
          : 40               fprobe_disabled():
          : 49               */
          : 50               #define FPROBE_FL_KPROBE_SHARED 2
          :
          : 52               static inline bool fprobe_disabled(struct fprobe *fp)
          : 53               {
          : 54               return (fp) ? fp->flags & FPROBE_FL_DISABLED : false;
     0.00 :   ffff8000081a2044:       cbz     x2, ffff8000081a2050 <fprobe_handler+0x30>
    20.00 :   ffff8000081a2048:       ldr     w0, [x2, #192] // fprobe.h:49
     0.00 :   ffff8000081a204c:       tbnz    w0, #0, ffff8000081a2128 <fprobe_handler+0x108>
          : 58               get_current():
          : 19               */
          : 20               static __always_inline struct task_struct *get_current(void)
          : 21               {
          : 22               unsigned long sp_el0;
          :
          : 24               asm ("mrs %0, sp_el0" : "=r" (sp_el0));
     0.00 :   ffff8000081a2050:       mrs     x0, sp_el0
          : 26               trace_test_and_set_recursion():
          : 144              * Preemption is promised to be disabled when return bit >= 0.
          : 145              */
          : 146              static __always_inline int trace_test_and_set_recursion(unsigned long ip, unsigned long pip,
          : 147              int start)
          : 148              {
          : 149              unsigned int val = READ_ONCE(current->trace_recursion);
    10.00 :   ffff8000081a2054:       ldr     x9, [x0, #2520] // trace_recursion.h:144
          : 151              trace_get_context_bit():
          : 121              return TRACE_CTX_NORMAL - bit;
     0.00 :   ffff8000081a2058:       mov     w6, #0x3                        // #3
          : 123              preempt_count():
          : 13               #define PREEMPT_NEED_RESCHED    BIT(32)
          : 14               #define PREEMPT_ENABLED (PREEMPT_NEED_RESCHED)
          :
          : 16               static inline int preempt_count(void)
          : 17               {
          : 18               return READ_ONCE(current_thread_info()->preempt.count);
     0.00 :   ffff8000081a205c:       ldr     w8, [x0, #8]
          : 20               trace_test_and_set_recursion():
          : 148              int bit;
          :
          : 150              bit = trace_get_context_bit() + start;
          : 151              if (unlikely(val & (1 << bit))) {
     0.00 :   ffff8000081a2060:       mov     w4, #0x1                        // #1
          : 153              interrupt_context_level():
          : 94               static __always_inline unsigned char interrupt_context_level(void)
          : 95               {
          : 96               unsigned long pc = preempt_count();
          : 97               unsigned char level = 0;
          :
          : 99               level += !!(pc & (NMI_MASK));
     0.00 :   ffff8000081a2064:       tst     w8, #0xf00000
          : 96               level += !!(pc & (NMI_MASK | HARDIRQ_MASK));
          : 97               level += !!(pc & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET));
     0.00 :   ffff8000081a2068:       and     w7, w8, #0xffff00
          : 94               level += !!(pc & (NMI_MASK));
     0.00 :   ffff8000081a206c:       cset    w5, ne  // ne = any
          : 96               level += !!(pc & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET));
     0.00 :   ffff8000081a2070:       and     w7, w7, #0xffff01ff
          : 95               level += !!(pc & (NMI_MASK | HARDIRQ_MASK));
     0.00 :   ffff8000081a2074:       tst     w8, #0xff0000
     0.00 :   ffff8000081a2078:       cinc    w5, w5, ne      // ne = any
          : 96               level += !!(pc & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET));
     0.00 :   ffff8000081a207c:       cmp     w7, #0x0
          : 98               trace_get_context_bit():
          : 121              return TRACE_CTX_NORMAL - bit;
     0.00 :   ffff8000081a2080:       cinc    w5, w5, ne      // ne = any
     0.00 :   ffff8000081a2084:       sub     w5, w6, w5
          : 124              trace_test_and_set_recursion():
          : 148              if (unlikely(val & (1 << bit))) {
     0.00 :   ffff8000081a2088:       lsl     w4, w4, w5
          : 150              trace_clear_recursion():
          : 180              */
          : 181              static __always_inline void trace_clear_recursion(int bit)
          : 182              {
          : 183              preempt_enable_notrace();
          : 184              barrier();
          : 185              trace_recursion_clear(bit);
    10.00 :   ffff8000081a208c:       mvn     w20, w4 // trace_recursion.h:180
     0.00 :   ffff8000081a2090:       sxtw    x20, w20
          : 188              trace_test_and_set_recursion():
          : 148              if (unlikely(val & (1 << bit))) {
     0.00 :   ffff8000081a2094:       tst     w4, w9
     0.00 :   ffff8000081a2098:       b.ne    ffff8000081a2194 <fprobe_handler+0x174>  // b.any
          : 165              current->trace_recursion = val;
     0.00 :   ffff8000081a209c:       orr     w4, w4, w9
          : 167              get_current():
     0.00 :   ffff8000081a20a0:       mrs     x5, sp_el0
          : 20               trace_test_and_set_recursion():
     0.00 :   ffff8000081a20a4:       str     x4, [x5, #2520]
          : 166              __preempt_count_add():
          : 47               return !current_thread_info()->preempt.need_resched;
          : 48               }
          :
          : 50               static inline void __preempt_count_add(int val)
          : 51               {
          : 52               u32 pc = READ_ONCE(current_thread_info()->preempt.count);
     0.00 :   ffff8000081a20a8:       ldr     w4, [x5, #8]
          : 48               pc += val;
     0.00 :   ffff8000081a20ac:       add     w4, w4, #0x1
          : 49               WRITE_ONCE(current_thread_info()->preempt.count, pc);
     0.00 :   ffff8000081a20b0:       str     w4, [x5, #8]
          : 51               fprobe_handler():
          : 43               if (bit < 0) {
          : 44               fp->nmissed++;
          : 45               return;
          : 46               }
          :
          : 48               if (fp->exit_handler) {
     0.00 :   ffff8000081a20b4:       ldr     x0, [x19, #224]
     0.00 :   ffff8000081a20b8:       cbz     x0, ffff8000081a2140 <fprobe_handler+0x120>
          : 44               rh = rethook_try_get(fp->rethook);
    10.00 :   ffff8000081a20bc:       ldr     x0, [x19, #200] // fprobe.c:44
     0.00 :   ffff8000081a20c0:       bl      ffff8000081a2a54 <rethook_try_get>
     0.00 :   ffff8000081a20c4:       mov     x21, x0
          : 45               if (!rh) {
     0.00 :   ffff8000081a20c8:       cbz     x0, ffff8000081a21a4 <fprobe_handler+0x184>
          : 50               fp->nmissed++;
          : 51               goto out;
          : 52               }
          : 53               fpr = container_of(rh, struct fprobe_rethook_node, node);
          : 54               fpr->entry_ip = ip;
     0.00 :   ffff8000081a20cc:       str     x23, [x0, #48]
          : 54               private = fpr->private;
          : 55               }
          :
          : 57               if (fp->entry_handler)
     0.00 :   ffff8000081a20d0:       ldr     x4, [x19, #216]
     0.00 :   ffff8000081a20d4:       cbz     x4, ffff8000081a2180 <fprobe_handler+0x160>
          : 55               should_rethook = fp->entry_handler(fp, ip, fregs, fpr->private);
     0.00 :   ffff8000081a20d8:       mov     x1, x23
     0.00 :   ffff8000081a20dc:       mov     x0, x19
     0.00 :   ffff8000081a20e0:       add     x3, x21, #0x38
     0.00 :   ffff8000081a20e4:       mov     x2, x22
     0.00 :   ffff8000081a20e8:       blr     x4
          :
          : 59               if (rh) {
          : 60               if (should_rethook)
     0.00 :   ffff8000081a20ec:       tst     w0, #0xff
     0.00 :   ffff8000081a20f0:       b.ne    ffff8000081a2180 <fprobe_handler+0x160>  // b.any
          : 61               rethook_hook(rh, fregs, true);
          : 62               else
          : 63               rethook_recycle(rh);
     0.00 :   ffff8000081a20f4:       mov     x0, x21
     0.00 :   ffff8000081a20f8:       bl      ffff8000081a2bf0 <rethook_recycle>
          : 66               get_current():
     0.00 :   ffff8000081a20fc:       mrs     x1, sp_el0
          : 20               __preempt_count_dec_and_test():
          : 62               }
          :
          : 64               static inline bool __preempt_count_dec_and_test(void)
          : 65               {
          : 66               struct thread_info *ti = current_thread_info();
          : 67               u64 pc = READ_ONCE(ti->preempt_count);
     0.00 :   ffff8000081a2100:       ldr     x0, [x1, #8]
          :
          : 66               /* Update only the count field, leaving need_resched unchanged */
          : 67               WRITE_ONCE(ti->preempt.count, --pc);
     0.00 :   ffff8000081a2104:       sub     x0, x0, #0x1
     0.00 :   ffff8000081a2108:       str     w0, [x1, #8]
          : 74               * need of a reschedule. Otherwise, we need to reload the
          : 75               * preempt_count in case the need_resched flag was cleared by an
          : 76               * interrupt occurring between the non-atomic READ_ONCE/WRITE_ONCE
          : 77               * pair.
          : 78               */
          : 79               return !pc || !READ_ONCE(ti->preempt_count);
     0.00 :   ffff8000081a210c:       cbnz    x0, ffff8000081a2170 <fprobe_handler+0x150>
          : 81               trace_clear_recursion():
          : 178              preempt_enable_notrace();
     0.00 :   ffff8000081a2110:       bl      ffff800008ae88d0 <preempt_schedule_notrace>
     0.00 :   ffff8000081a2114:       nop
          : 181              get_current():
    10.00 :   ffff8000081a2118:       mrs     x1, sp_el0 // current.h:19
          : 20               trace_clear_recursion():
          : 180              trace_recursion_clear(bit);
     0.00 :   ffff8000081a211c:       ldr     x0, [x1, #2520]
     0.00 :   ffff8000081a2120:       and     x0, x0, x20
    10.00 :   ffff8000081a2124:       str     x0, [x1, #2520] // trace_recursion.h:180
          : 184              fprobe_handler():
          : 66               }
          :
          : 68               out:
          : 69               ftrace_test_recursion_unlock(bit);
          : 70               }
     0.00 :   ffff8000081a2128:       ldp     x19, x20, [sp, #16]
     0.00 :   ffff8000081a212c:       ldp     x21, x22, [sp, #32]
     0.00 :   ffff8000081a2130:       ldr     x23, [sp, #48]
    20.00 :   ffff8000081a2134:       ldp     x29, x30, [sp], #64 // fprobe.c:66
     0.00 :   ffff8000081a2138:       autiasp
    10.00 :   ffff8000081a213c:       ret
          : 54               if (fp->entry_handler)
     0.00 :   ffff8000081a2140:       ldr     x4, [x19, #216]
     0.00 :   ffff8000081a2144:       cbz     x4, ffff8000081a215c <fprobe_handler+0x13c>
          : 55               should_rethook = fp->entry_handler(fp, ip, fregs, fpr->private);
     0.00 :   ffff8000081a2148:       mov     x2, x22
     0.00 :   ffff8000081a214c:       mov     x1, x23
     0.00 :   ffff8000081a2150:       mov     x0, x19
     0.00 :   ffff8000081a2154:       mov     x3, #0x38                       // #56
     0.00 :   ffff8000081a2158:       blr     x4
          : 61               get_current():
     0.00 :   ffff8000081a215c:       mrs     x1, sp_el0
          : 20               __preempt_count_dec_and_test():
          : 62               u64 pc = READ_ONCE(ti->preempt_count);
     0.00 :   ffff8000081a2160:       ldr     x0, [x1, #8]
          : 65               WRITE_ONCE(ti->preempt.count, --pc);
     0.00 :   ffff8000081a2164:       sub     x0, x0, #0x1
     0.00 :   ffff8000081a2168:       str     w0, [x1, #8]
          : 74               return !pc || !READ_ONCE(ti->preempt_count);
     0.00 :   ffff8000081a216c:       cbz     x0, ffff8000081a2110 <fprobe_handler+0xf0>
     0.00 :   ffff8000081a2170:       ldr     x0, [x1, #8]
     0.00 :   ffff8000081a2174:       cbnz    x0, ffff8000081a2118 <fprobe_handler+0xf8>
          : 78               trace_clear_recursion():
          : 178              preempt_enable_notrace();
     0.00 :   ffff8000081a2178:       bl      ffff800008ae88d0 <preempt_schedule_notrace>
     0.00 :   ffff8000081a217c:       b       ffff8000081a2118 <fprobe_handler+0xf8>
          : 181              fprobe_handler():
          : 59               rethook_hook(rh, fregs, true);
     0.00 :   ffff8000081a2180:       mov     x1, x22
     0.00 :   ffff8000081a2184:       mov     x0, x21
     0.00 :   ffff8000081a2188:       mov     w2, #0x1                        // #1
     0.00 :   ffff8000081a218c:       bl      ffff8000081a27d0 <rethook_hook>
     0.00 :   ffff8000081a2190:       b       ffff8000081a215c <fprobe_handler+0x13c>
          : 65               trace_test_and_set_recursion():
          : 158              if (val & (1 << bit)) {
     0.00 :   ffff8000081a2194:       tbnz    w9, #4, ffff8000081a21b4 <fprobe_handler+0x194>
     0.00 :   ffff8000081a2198:       mov     x20, #0xffffffffffffffef        // #-17
     0.00 :   ffff8000081a219c:       mov     w4, #0x10                       // #16
     0.00 :   ffff8000081a21a0:       b       ffff8000081a209c <fprobe_handler+0x7c>
          : 163              fprobe_handler():
          : 46               fp->nmissed++;
     0.00 :   ffff8000081a21a4:       ldr     x0, [x19, #184]
     0.00 :   ffff8000081a21a8:       add     x0, x0, #0x1
     0.00 :   ffff8000081a21ac:       str     x0, [x19, #184]
          : 47               goto out;
     0.00 :   ffff8000081a21b0:       b       ffff8000081a215c <fprobe_handler+0x13c>
          : 39               fp->nmissed++;
     0.00 :   ffff8000081a21b4:       ldr     x0, [x19, #184]
     0.00 :   ffff8000081a21b8:       add     x0, x0, #0x1
     0.00 :   ffff8000081a21bc:       str     x0, [x19, #184]
          : 40               return;
     0.00 :   ffff8000081a21c0:       b       ffff8000081a2128 <fprobe_handler+0x108>


2.4 bpf_fprobe_entry

          : 5                ffff8000081e19f0 <bpf_fprobe_entry>:
          : 6                bpf_fprobe_entry():
          : 1057             flags = u64_stats_update_begin_irqsave(&stats->syncp);
          : 1058             u64_stats_inc(&stats->cnt);
          : 1059             u64_stats_add(&stats->nsecs, sched_clock() - start);
          : 1060             u64_stats_update_end_irqrestore(&stats->syncp, flags);
          : 1061             }
          : 1062             }
     0.00 :   ffff8000081e19f0:       bti     c
     0.00 :   ffff8000081e19f4:       nop
     0.00 :   ffff8000081e19f8:       nop
          : 165              {
     0.00 :   ffff8000081e19fc:       paciasp
     0.00 :   ffff8000081e1a00:       stp     x29, x30, [sp, #-80]!
     0.00 :   ffff8000081e1a04:       mov     w4, #0x0                        // #0
     0.00 :   ffff8000081e1a08:       mov     x29, sp
     0.00 :   ffff8000081e1a0c:       stp     x19, x20, [sp, #16]
     0.00 :   ffff8000081e1a10:       mov     x19, x3
     0.00 :   ffff8000081e1a14:       stp     x21, x22, [sp, #32]
     0.00 :   ffff8000081e1a18:       mov     x22, x0
     0.00 :   ffff8000081e1a1c:       mov     x21, x2
     0.00 :   ffff8000081e1a20:       stp     x23, x24, [sp, #48]
     0.00 :   ffff8000081e1a24:       str     x25, [sp, #64]
          : 167              struct bpf_fprobe_context *fprobe_ctx = fp->ops.private;
     0.00 :   ffff8000081e1a28:       ldr     x24, [x0, #24]
          : 168              struct bpf_tramp_links *links = fprobe_ctx->links;
     0.00 :   ffff8000081e1a2c:       ldr     x23, [x24]
          : 174              memset(&call_ctx->ctx, 0, sizeof(call_ctx->ctx));
     0.00 :   ffff8000081e1a30:       stp     xzr, xzr, [x3]
          : 175              call_ctx->ip = ip;
     0.00 :   ffff8000081e1a34:       str     x1, [x3, #16]
          : 176              for (i = 0; i < fprobe_ctx->nr_args; i++)
     0.00 :   ffff8000081e1a38:       ldr     w0, [x24, #8]
     0.00 :   ffff8000081e1a3c:       cmp     w0, #0x0
     0.00 :   ffff8000081e1a40:       b.gt    ffff8000081e1a64 <bpf_fprobe_entry+0x74>
     0.00 :   ffff8000081e1a44:       b       ffff8000081e1a90 <bpf_fprobe_entry+0xa0>
          : 177              call_ctx->args[i] = ftrace_regs_get_argument(regs, i);
     0.00 :   ffff8000081e1a48:       ldr     x0, [x21, x1, lsl #3]
     0.00 :   ffff8000081e1a4c:       add     x1, x19, x1, lsl #3
          : 176              for (i = 0; i < fprobe_ctx->nr_args; i++)
     0.00 :   ffff8000081e1a50:       add     w4, w4, #0x1
          : 177              call_ctx->args[i] = ftrace_regs_get_argument(regs, i);
    16.67 :   ffff8000081e1a54:       str     x0, [x1, #24] // trampoline.c:177
          : 176              for (i = 0; i < fprobe_ctx->nr_args; i++)
     0.00 :   ffff8000081e1a58:       ldr     w0, [x24, #8]
     0.00 :   ffff8000081e1a5c:       cmp     w0, w4
     0.00 :   ffff8000081e1a60:       b.le    ffff8000081e1a90 <bpf_fprobe_entry+0xa0>
          : 177              call_ctx->args[i] = ftrace_regs_get_argument(regs, i);
     8.33 :   ffff8000081e1a64:       sxtw    x1, w4
     0.00 :   ffff8000081e1a68:       mov     x0, #0x0                        // #0
     0.00 :   ffff8000081e1a6c:       cmp     w4, #0x7
     0.00 :   ffff8000081e1a70:       b.le    ffff8000081e1a48 <bpf_fprobe_entry+0x58>
     0.00 :   ffff8000081e1a74:       sxtw    x1, w4
          : 176              for (i = 0; i < fprobe_ctx->nr_args; i++)
     0.00 :   ffff8000081e1a78:       add     w4, w4, #0x1
          : 177              call_ctx->args[i] = ftrace_regs_get_argument(regs, i);
     0.00 :   ffff8000081e1a7c:       add     x1, x19, x1, lsl #3
     0.00 :   ffff8000081e1a80:       str     x0, [x1, #24]
          : 176              for (i = 0; i < fprobe_ctx->nr_args; i++)
     0.00 :   ffff8000081e1a84:       ldr     w0, [x24, #8]
     0.00 :   ffff8000081e1a88:       cmp     w0, w4
     0.00 :   ffff8000081e1a8c:       b.gt    ffff8000081e1a64 <bpf_fprobe_entry+0x74>
          : 179              for (i = 0; i < fentry->nr_links; i++)
     0.00 :   ffff8000081e1a90:       ldr     w1, [x23, #304]
          : 185              call_ctx->args);
     0.00 :   ffff8000081e1a94:       add     x25, x19, #0x18
     0.00 :   ffff8000081e1a98:       mov     x20, #0x0                       // #0
          : 179              for (i = 0; i < fentry->nr_links; i++)
     0.00 :   ffff8000081e1a9c:       cmp     w1, #0x0
     0.00 :   ffff8000081e1aa0:       b.le    ffff8000081e1ad4 <bpf_fprobe_entry+0xe4>
     0.00 :   ffff8000081e1aa4:       nop
          : 180              call_bpf_prog(fentry->links[i], &call_ctx->ctx, call_ctx->args);
     0.00 :   ffff8000081e1aa8:       ldr     x1, [x23, x20, lsl #3]
     0.00 :   ffff8000081e1aac:       mov     x3, x25
     0.00 :   ffff8000081e1ab0:       mov     x2, x19
          : 179              for (i = 0; i < fentry->nr_links; i++)
     0.00 :   ffff8000081e1ab4:       add     x20, x20, #0x1
          : 180              call_bpf_prog(fentry->links[i], &call_ctx->ctx, call_ctx->args);
    16.67 :   ffff8000081e1ab8:       ldr     x0, [x1, #24] // trampoline.c:180
     0.00 :   ffff8000081e1abc:       ldr     x1, [x1, #80]
     0.00 :   ffff8000081e1ac0:       bl      ffff8000081e1800 <call_bpf_prog.isra.0>
          : 179              for (i = 0; i < fentry->nr_links; i++)
     0.00 :   ffff8000081e1ac4:       ldr     w0, [x23, #304]
     0.00 :   ffff8000081e1ac8:       cmp     w0, w20
     0.00 :   ffff8000081e1acc:       b.gt    ffff8000081e1aa8 <bpf_fprobe_entry+0xb8>
     0.00 :   ffff8000081e1ad0:       ldr     w0, [x24, #8]
          : 182              call_ctx->args[fprobe_ctx->nr_args] = 0;
     0.00 :   ffff8000081e1ad4:       add     x0, x19, w0, sxtw #3
          : 183              for (i = 0; i < fmod_ret->nr_links; i++) {
     0.00 :   ffff8000081e1ad8:       add     x25, x23, #0x270
          : 185              call_ctx->args);
     0.00 :   ffff8000081e1adc:       add     x24, x19, #0x18
     0.00 :   ffff8000081e1ae0:       mov     x20, #0x0                       // #0
          : 182              call_ctx->args[fprobe_ctx->nr_args] = 0;
    25.00 :   ffff8000081e1ae4:       str     xzr, [x0, #24] // trampoline.c:182
          : 183              for (i = 0; i < fmod_ret->nr_links; i++) {
     0.00 :   ffff8000081e1ae8:       ldr     w0, [x25, #304]
     0.00 :   ffff8000081e1aec:       cmp     w0, #0x0
     0.00 :   ffff8000081e1af0:       b.gt    ffff8000081e1b04 <bpf_fprobe_entry+0x114>
    16.67 :   ffff8000081e1af4:       b       ffff8000081e1ba8 <bpf_fprobe_entry+0x1b8> // trampoline.c:183
     0.00 :   ffff8000081e1af8:       ldr     w0, [x25, #304]
     0.00 :   ffff8000081e1afc:       cmp     w0, w20
     0.00 :   ffff8000081e1b00:       b.le    ffff8000081e1ba8 <bpf_fprobe_entry+0x1b8>
          : 184              ret = call_bpf_prog(fmod_ret->links[i], &call_ctx->ctx,
     0.00 :   ffff8000081e1b04:       ldr     x1, [x25, x20, lsl #3]
     0.00 :   ffff8000081e1b08:       mov     x3, x24
     0.00 :   ffff8000081e1b0c:       mov     x2, x19
          : 183              for (i = 0; i < fmod_ret->nr_links; i++) {
     0.00 :   ffff8000081e1b10:       add     x20, x20, #0x1
          : 184              ret = call_bpf_prog(fmod_ret->links[i], &call_ctx->ctx,
     0.00 :   ffff8000081e1b14:       ldr     x0, [x1, #24]
     0.00 :   ffff8000081e1b18:       ldr     x1, [x1, #80]
     0.00 :   ffff8000081e1b1c:       bl      ffff8000081e1800 <call_bpf_prog.isra.0>
          : 187              if (ret) {
     0.00 :   ffff8000081e1b20:       cbz     w0, ffff8000081e1af8 <bpf_fprobe_entry+0x108>
          : 189              ftrace_override_function_with_return(regs);
     0.00 :   ffff8000081e1b24:       ldr     x2, [x21, #88]
          : 188              ftrace_regs_set_return_value(regs, ret);
     0.00 :   ffff8000081e1b28:       sxtw    x1, w0
     0.00 :   ffff8000081e1b2c:       str     x1, [x21]
          : 191              bpf_fprobe_exit():
          : 160              for (i = 0; i < fexit->nr_links; i++)
     0.00 :   ffff8000081e1b30:       mov     x20, #0x0                       // #0
          : 162              bpf_fprobe_entry():
          : 189              ftrace_override_function_with_return(regs);
     0.00 :   ffff8000081e1b34:       str     x2, [x21, #104]
          : 191              bpf_fprobe_exit():
          : 153              struct bpf_fprobe_context *fprobe_ctx = fp->ops.private;
     0.00 :   ffff8000081e1b38:       ldr     x2, [x22, #24]
          : 158              call_ctx->args[fprobe_ctx->nr_args] = ftrace_regs_return_value(regs);
     0.00 :   ffff8000081e1b3c:       ldrsw   x0, [x2, #8]
          : 154              struct bpf_tramp_links *links = fprobe_ctx->links;
     0.00 :   ffff8000081e1b40:       ldr     x21, [x2]
          : 158              call_ctx->args[fprobe_ctx->nr_args] = ftrace_regs_return_value(regs);
     0.00 :   ffff8000081e1b44:       add     x0, x19, x0, lsl #3
          : 160              for (i = 0; i < fexit->nr_links; i++)
     0.00 :   ffff8000081e1b48:       add     x21, x21, #0x138
          : 158              call_ctx->args[fprobe_ctx->nr_args] = ftrace_regs_return_value(regs);
     0.00 :   ffff8000081e1b4c:       str     x1, [x0, #24]
          : 160              for (i = 0; i < fexit->nr_links; i++)
     0.00 :   ffff8000081e1b50:       ldr     w0, [x21, #304]
     0.00 :   ffff8000081e1b54:       cmp     w0, #0x0
     0.00 :   ffff8000081e1b58:       b.le    ffff8000081e1b88 <bpf_fprobe_entry+0x198>
     0.00 :   ffff8000081e1b5c:       nop
          : 161              call_bpf_prog(fexit->links[i], &call_ctx->ctx, call_ctx->args);
     0.00 :   ffff8000081e1b60:       ldr     x1, [x21, x20, lsl #3]
     0.00 :   ffff8000081e1b64:       mov     x3, x24
     0.00 :   ffff8000081e1b68:       mov     x2, x19
          : 160              for (i = 0; i < fexit->nr_links; i++)
     0.00 :   ffff8000081e1b6c:       add     x20, x20, #0x1
          : 161              call_bpf_prog(fexit->links[i], &call_ctx->ctx, call_ctx->args);
     0.00 :   ffff8000081e1b70:       ldr     x0, [x1, #24]
     0.00 :   ffff8000081e1b74:       ldr     x1, [x1, #80]
     0.00 :   ffff8000081e1b78:       bl      ffff8000081e1800 <call_bpf_prog.isra.0>
          : 160              for (i = 0; i < fexit->nr_links; i++)
     0.00 :   ffff8000081e1b7c:       ldr     w0, [x21, #304]
     0.00 :   ffff8000081e1b80:       cmp     w0, w20
     0.00 :   ffff8000081e1b84:       b.gt    ffff8000081e1b60 <bpf_fprobe_entry+0x170>
          : 164              bpf_fprobe_entry():
          : 192              return false;
     0.00 :   ffff8000081e1b88:       mov     w0, #0x0                        // #0
          : 197              }
     0.00 :   ffff8000081e1b8c:       ldp     x19, x20, [sp, #16]
     0.00 :   ffff8000081e1b90:       ldp     x21, x22, [sp, #32]
     0.00 :   ffff8000081e1b94:       ldp     x23, x24, [sp, #48]
     0.00 :   ffff8000081e1b98:       ldr     x25, [sp, #64]
     0.00 :   ffff8000081e1b9c:       ldp     x29, x30, [sp], #80
     0.00 :   ffff8000081e1ba0:       autiasp
     0.00 :   ffff8000081e1ba4:       ret
          : 196              return fexit->nr_links;
     0.00 :   ffff8000081e1ba8:       ldr     w0, [x23, #616]
          : 197              }
     0.00 :   ffff8000081e1bac:       ldp     x19, x20, [sp, #16]
          : 196              return fexit->nr_links;
     0.00 :   ffff8000081e1bb0:       cmp     w0, #0x0
     0.00 :   ffff8000081e1bb4:       cset    w0, ne  // ne = any
          : 197              }
     0.00 :   ffff8000081e1bb8:       ldp     x21, x22, [sp, #32]
     0.00 :   ffff8000081e1bbc:       ldp     x23, x24, [sp, #48]
     0.00 :   ffff8000081e1bc0:       ldr     x25, [sp, #64]
     0.00 :   ffff8000081e1bc4:       ldp     x29, x30, [sp], #80
     0.00 :   ffff8000081e1bc8:       autiasp
    16.67 :   ffff8000081e1bcc:       ret // trampoline.c:197

2.5 call_bpf_prog

          : 5                ffff8000081e1800 <call_bpf_prog.isra.0>:
          : 6                call_bpf_prog.isra.0():
          :
          : 200              if (oldp)
          : 201              *oldp = old;
          :
          : 203              if (unlikely(!old))
          : 204              refcount_warn_saturate(r, REFCOUNT_ADD_UAF);
    13.33 :   ffff8000081e1800:       nop // refcount.h:199
     0.00 :   ffff8000081e1804:       nop
          : 207              call_bpf_prog():
          :
          : 108              mutex_unlock(&tr->mutex);
          : 109              return ret;
          : 110              }
          : 111              #else
          : 112              static unsigned int call_bpf_prog(struct bpf_tramp_link *l,
     0.00 :   ffff8000081e1808:       paciasp
     0.00 :   ffff8000081e180c:       stp     x29, x30, [sp, #-64]!
     0.00 :   ffff8000081e1810:       mov     x29, sp
     0.00 :   ffff8000081e1814:       stp     x19, x20, [sp, #16]
     0.00 :   ffff8000081e1818:       mov     x19, x0
     0.00 :   ffff8000081e181c:       mov     x20, x2
     0.00 :   ffff8000081e1820:       stp     x21, x22, [sp, #32]
     6.67 :   ffff8000081e1824:       stp     x23, x24, [sp, #48] // trampoline.c:107
     0.00 :   ffff8000081e1828:       mov     x24, x3
          : 118              struct bpf_tramp_run_ctx *run_ctx) = __bpf_prog_exit;
          : 119              struct bpf_prog *p = l->link.prog;
          : 120              unsigned int ret;
          : 121              u64 start_time;
          :
          : 123              if (p->aux->sleepable) {
    60.00 :   ffff8000081e182c:       ldr     x0, [x0, #56] // trampoline.c:118
    13.33 :   ffff8000081e1830:       ldrb    w0, [x0, #140]
     0.00 :   ffff8000081e1834:       cbnz    w0, ffff8000081e1858 <call_bpf_prog.isra.0+0x58>
          : 121              enter = __bpf_prog_enter_sleepable;
          : 122              exit = __bpf_prog_exit_sleepable;
          : 123              } else if (p->expected_attach_type == BPF_LSM_CGROUP) {
     0.00 :   ffff8000081e1838:       ldr     w0, [x19, #8]
     0.00 :   ffff8000081e183c:       cmp     w0, #0x2b
     0.00 :   ffff8000081e1840:       b.eq    ffff8000081e18c4 <call_bpf_prog.isra.0+0xc4>  // b.none
          : 112              void (*exit)(struct bpf_prog *prog, u64 start,
     0.00 :   ffff8000081e1844:       adrp    x22, ffff8000081e1000 <print_bpf_insn+0x580>
          : 110              u64 (*enter)(struct bpf_prog *prog,
     0.00 :   ffff8000081e1848:       adrp    x2, ffff8000081e1000 <print_bpf_insn+0x580>
          : 112              void (*exit)(struct bpf_prog *prog, u64 start,
     0.00 :   ffff8000081e184c:       add     x22, x22, #0xbd0
          : 110              u64 (*enter)(struct bpf_prog *prog,
     0.00 :   ffff8000081e1850:       add     x2, x2, #0xd20
     0.00 :   ffff8000081e1854:       b       ffff8000081e1868 <call_bpf_prog.isra.0+0x68>
          : 120              exit = __bpf_prog_exit_sleepable;
     0.00 :   ffff8000081e1858:       adrp    x22, ffff8000081e1000 <print_bpf_insn+0x580>
          : 119              enter = __bpf_prog_enter_sleepable;
     0.00 :   ffff8000081e185c:       adrp    x2, ffff8000081e1000 <print_bpf_insn+0x580>
          : 120              exit = __bpf_prog_exit_sleepable;
     0.00 :   ffff8000081e1860:       add     x22, x22, #0xc60
          : 119              enter = __bpf_prog_enter_sleepable;
     0.00 :   ffff8000081e1864:       add     x2, x2, #0xe10
          : 126              enter = __bpf_prog_enter_lsm_cgroup;
          : 127              exit = __bpf_prog_exit_lsm_cgroup;
          : 128              }
          :
          : 130              ctx->bpf_cookie = l->cookie;
     0.00 :   ffff8000081e1868:       str     x1, [x20]
          :
          : 129              start_time = enter(p, ctx);
     0.00 :   ffff8000081e186c:       mov     x0, x19
     0.00 :   ffff8000081e1870:       mov     x1, x20
          : 130              if (!start_time)
          : 131              return 0;
     0.00 :   ffff8000081e1874:       mov     w23, #0x0                       // #0
          : 128              start_time = enter(p, ctx);
     0.00 :   ffff8000081e1878:       blr     x2
     0.00 :   ffff8000081e187c:       mov     x21, x0
          : 129              if (!start_time)
     0.00 :   ffff8000081e1880:       cbz     x0, ffff8000081e18a8 <call_bpf_prog.isra.0+0xa8>
          :
          : 133              ret = p->bpf_func(args, p->insnsi);
     0.00 :   ffff8000081e1884:       ldr     x2, [x19, #48]
     0.00 :   ffff8000081e1888:       add     x1, x19, #0x48
     0.00 :   ffff8000081e188c:       mov     x0, x24
     0.00 :   ffff8000081e1890:       blr     x2
     0.00 :   ffff8000081e1894:       mov     w23, w0
          :
          : 135              exit(p, start_time, ctx);
     0.00 :   ffff8000081e1898:       mov     x2, x20
     0.00 :   ffff8000081e189c:       mov     x1, x21
     0.00 :   ffff8000081e18a0:       mov     x0, x19
     0.00 :   ffff8000081e18a4:       blr     x22
          :
          : 138              return ret;
          : 139              }
     0.00 :   ffff8000081e18a8:       mov     w0, w23
     0.00 :   ffff8000081e18ac:       ldp     x19, x20, [sp, #16]
     0.00 :   ffff8000081e18b0:       ldp     x21, x22, [sp, #32]
     0.00 :   ffff8000081e18b4:       ldp     x23, x24, [sp, #48]
     6.67 :   ffff8000081e18b8:       ldp     x29, x30, [sp], #64 // trampoline.c:137
     0.00 :   ffff8000081e18bc:       autiasp
     0.00 :   ffff8000081e18c0:       ret
          : 123              exit = __bpf_prog_exit_lsm_cgroup;
     0.00 :   ffff8000081e18c4:       adrp    x22, ffff8000081e1000 <print_bpf_insn+0x580>
          : 122              enter = __bpf_prog_enter_lsm_cgroup;
     0.00 :   ffff8000081e18c8:       adrp    x2, ffff8000081e1000 <print_bpf_insn+0x580>
          : 123              exit = __bpf_prog_exit_lsm_cgroup;
     0.00 :   ffff8000081e18cc:       add     x22, x22, #0x200
          : 122              enter = __bpf_prog_enter_lsm_cgroup;
     0.00 :   ffff8000081e18d0:       add     x2, x2, #0x1c0
     0.00 :   ffff8000081e18d4:       b       ffff8000081e1868 <call_bpf_prog.isra.0+0x68>



More information about the linux-arm-kernel mailing list