On Thu, Sep 2, 2021 at 9:58 AM Song Liu <songliubraving@xxxxxx> wrote: > > +BPF_CALL_3(bpf_get_branch_snapshot, void *, buf, u32, size, u64, flags) > +{ > +#ifndef CONFIG_X86 > + return -ENOENT; > +#else > + static const u32 br_entry_size = sizeof(struct perf_branch_entry); > + u32 entry_cnt = size / br_entry_size; > + > + if (unlikely(flags)) > + return -EINVAL; > + > + if (!buf || (size % br_entry_size != 0)) > + return -EINVAL; > + > + entry_cnt = static_call(perf_snapshot_branch_stack)(buf, entry_cnt); Not taken branches will not be counted even with PERF_SAMPLE_BRANCH_ANY, right? Probably the first unlikely(flags) will be a fallthrough in asm. Maybe worth adding unlikely to 2nd condition as well to make sure that the compiler will generate default fallthrough code for it ? So both will not appear in lbr entries? Or maybe do: if (unlikely(!buf)) return -EINVAL; entry_cnt = static_call if (size % br_entry_size) return -EINVAL; The lbr trace will be collected anyway. If there are jmps in lbr due to earlier "if"s we can move them after static_call. Like if (unlikely(flags) can be done afterwards too. Bigger bang for the buck would be static-inline-ing migrate_disable, though.