Re: [PATCH dwarves v3 1/9] dwarf_loader: Reduce parameter checking with clang DW_AT_calling_convention attr

Jiri Olsa <[email protected]> Sun, 22 Mar 2026 00:10:18 +0100
Newsgroups org.kernel.vger.dwarves,org.kernel.vger.bpf
Message-ID <ab8lWhTT8LZGbtQs@krava>
On Fri, Mar 20, 2026 at 12:09:22PM -0700, Yonghong Song wrote:
> Currently every function is checked for its parameters to identify whether
> the signature changed or not. If signature indeed changed, pahole may do
> some adjustment for parameters for true signatures.
> 
> In clang, any function with the following attribute
>       DW_AT_calling_convention        (DW_CC_nocall)
> indicates this function having signature changed.
> pahole can take advantage of this to avoid parameter checking if
> DW_AT_calling_convention is not DW_CC_nocall.
> 
> But more importantly, DW_CC_nocall can identify signature-changed functions
> and parameters can be checked one-after-another to create the true
> signatures. Otherwise, it takes more effort to identify whether a
> function has signature changed or not. For example, for funciton
>   __bpf_kfunc static void bbr_main(struct sock *sk, u32 ack, int flag,
>      const struct rate_sample *rs) { ... }
> and bbr_main() is a callback function in
>   .cong_control   = bbr_main
> in 'struct tcp_congestion_ops tcp_bbr_cong_ops'.
> In the above bbr_main(...), parameter 'ack' and 'flag' are not used.
> The following are some details:
> 
> 0x0a713b8d:     DW_TAG_formal_parameter
>                   DW_AT_location        (indexed (0x28) loclist = 0x0166d452:
>                      [0xffffffff83e77fd9, 0xffffffff83e78016): DW_OP_reg5 RDI
>                      ...
>                   DW_AT_name    ("sk")
>                   DW_AT_type    (0x0a6f5b2b "sock *")
>                   ...
> 
> 0x0a713b98:     DW_TAG_formal_parameter
>                   DW_AT_name    ("ack")
>                   DW_AT_type    (0x0a6f58fd "u32")
>                   ...
> 
> 0x0a713ba2:     DW_TAG_formal_parameter
>                   DW_AT_name    ("flag")
>                   DW_AT_type    (0x0a6f57d1 "int")
>                   ...
> 
> 0x0a713bac:     DW_TAG_formal_parameter
>                   DW_AT_location        (indexed (0x29) loclist = 0x0166d4a8:
>                      [0xffffffff83e77fd9, 0xffffffff83e78016): DW_OP_reg2 RCX
>                      ...
>                   DW_AT_name    ("rs")
>                   DW_AT_type    (0x0a710da5 "const rate_sample *")
>                   DW_AT_decl_line       (1027)
> 
> Some analysis for the above dwarf can conclude that the 'ark' and 'flag'
> may be related to RSI and RDX, considering the last one is RCX. Basically this
> requires all parameters are available to collectively decide whether the
> true signature can be found or not. In such case, DW_CC_nocall can make things
> easier as parameter can be checked one after another.
> 
> For a clang built bpf-next kernel, in non-LTO setup, the number of kernel functions
> is 69103 and the number of signature changed functions is 875, based on
>       DW_AT_calling_convention        (DW_CC_nocall)
> indication.

we don't display these stats, right? would be great and probably easy
to count different flags and aggregate them

> 
> Among 875 signature changed functions, after this patch, 495 functions
> can have proper true signatures, mostly due to simple dead argument
> elimination. The number of remaining functions, which cannot get the
> true signature, is 379. They will be addressed in the subsequent commits.

after this change I have more functions added (below) and I checked
few and they seem ok (w/o DW_CC_nocall)

jirka


acpi_ex_do_debug_object
add_bits
amd_pstate_get_mode_string
dma_alloc_from_contiguous
do_set_pmd
dst_destroy
find_cpio_data
find_microcode_in_initrd
ima_write_policy
insn_init
io_tx_ubuf_complete
ip6_protocol_deliver_rcu
kvm_tdp_mmu_unmap_gfn_range
net_dim_get_def_rx_moderation
net_dim_get_def_tx_moderation
pinctrl_commit_state
string_unescape
syscall_copy_user_array
tdp_mmu_zap_leafs
usb_speed_string
__vlan_find_dev_deep_rcu
__vxlan_fdb_delete
xfs_bmbt_maxrecs
xfs_inobt_maxrecs
ZSTD_buildSequencesStatistics
ZSTD_copyCCtx
ZSTD_findFrameSizeInfo
ZSTD_get1BlockSummary
zstd_get_cparams
ZSTD_getCParams
ZSTD_getCParamsFromCCtxParams
ZSTD_getCParamsFromCDict
ZSTD_getCParams_internal
zstd_get_params
ZSTD_getParams