On Fri, Mar 1, 2024 at 2:07 PM John Fastabend <john.fastabend@xxxxxxxxx> wrote: > > > > SEC("socket") > > __success __retval(16777216) > > int cond_break5(const void *ctx) > > { > > int cnt = 0; > > > > for (;;) { > > cond_break; > > cnt++; > > } > > > > cnt += full_loop(); > > > > for (;;) { > > cond_break; > > cnt++; > > } > > return cnt; > > } > > > > From verifier side story is slightly different. There are still > > two subprogs, but for subprog[0] has stack_slots==0? Debugging > > now but maybe its obvious what that static is doing to you. > > That was a typo its subprog[1] with stack_slots == 0. Also > tracing insn it seems in nonstatic case we hit multiple > insn->code (BPF_JMP| BPF_JMA) but in the static case only > find the first one. Object file seems to have multiples > though. I need to drop for the rest of the afternoon most > likely, but will try to see what sort of silly thing I did > later today or worse case Monday. Thanks for the bug report. For static case: $ bpftool p dump xlated id 36 int cond_break5(const void * ctx): ; int cond_break5(const void *ctx) 0: (7a) *(u64 *)(r10 -8) = 8388608 1: (b4) w6 = 0 ; cond_break; 2: (79) r11 = *(u64 *)(r10 -8) 3: (15) if r11 == 0x0 goto pc+4 4: (17) r11 -= 1 5: (7b) *(u64 *)(r10 -8) = r11 ; cnt++; 6: (04) w6 += 1 7: (05) goto pc-6 ; cnt += full_loop(); 8: (85) call pc+2#bpf_prog_270866f75dae27c8_full_loop ; for (;;) { 9: (0c) w0 += w6 ; return cnt; 10: (95) exit int full_loop(): ; static __noinline int full_loop(void) 11: (b4) w6 = 0 ; bpf_printk("cnt==%d\n", cnt); 12: (18) r1 = map[id:35][0]+0 14: (b4) w2 = 9 15: (bc) w3 = w6 16: (85) call bpf_trace_printk#-87376 ; return cnt; 17: (bc) w0 = w6 18: (95) exit Looks like I made a mistake in may_goto verification. Only the first loop remains. Other loops were removed as dead code. It's certainly a bug in the patch 1. Will fix in the next revision. pw-bot: cr