• Andrii Nakryiko's avatar
    kbuild: Build kernel module BTFs if BTF is enabled and pahole supports it · 5f9ae91f
    Andrii Nakryiko authored
    Detect if pahole supports split BTF generation, and generate BTF for each
    selected kernel module, if it does. This is exposed to Makefiles and C code as
    CONFIG_DEBUG_INFO_BTF_MODULES flag.
    
    Kernel module BTF has to be re-generated if either vmlinux's BTF changes or
    module's .ko changes. To achieve that, I needed a helper similar to
    if_changed, but that would allow to filter out vmlinux from the list of
    updated dependencies for .ko building. I've put it next to the only place that
    uses and needs it, but it might be a better idea to just add it along the
    other if_changed variants into scripts/Kbuild.include.
    
    Each kernel module's BTF deduplication is pretty fast, as it does only
    incremental BTF deduplication on top of already deduplicated vmlinux BTF. To
    show the added build time, I've first ran make only just built kernel (to
    establish the baseline) and then forced only BTF re-generation, without
    regenerating .ko files. The build was performed with -j60 parallelization on
    56-core machine. The final time also includes bzImage building, so it's not
    a pure BTF overhead.
    
    $ time make -j60
    ...
    make -j60  27.65s user 10.96s system 782% cpu 4.933 total
    $ touch ~/linux-build/default/vmlinux && time make -j60
    ...
    make -j60  123.69s user 27.85s system 1566% cpu 9.675 total
    
    So 4.6 seconds real time, with noticeable part spent in compressed vmlinux and
    bzImage building.
    
    To show size savings, I've built my kernel configuration with about 700 kernel
    modules with full BTF per each kernel module (without deduplicating against
    vmlinux) and with split BTF against deduplicated vmlinux (approach in this
    patch). Below are top 10 modules with biggest BTF sizes. And total size of BTF
    data across all kernel modules.
    
    It shows that split BTF "compresses" 115MB down to 5MB total. And the biggest
    kernel modules get a downsize from 500-570KB down to 200-300KB.
    
    FULL BTF
    ========
    
    $ for f in $(find . -name '*.ko'); do size -A -d $f | grep BTF | awk '{print $2}'; done | awk '{ s += $1 } END { print s }'
    115710691
    
    $ for f in $(find . -name '*.ko'); do printf "%s %d\n" $f $(size -A -d $f | grep BTF | awk '{print $2}'); done | sort -nr -k2 | head -n10
    ./drivers/gpu/drm/i915/i915.ko 570570
    ./drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko 520240
    ./drivers/gpu/drm/radeon/radeon.ko 503849
    ./drivers/infiniband/hw/mlx5/mlx5_ib.ko 491777
    ./fs/xfs/xfs.ko 411544
    ./drivers/net/ethernet/intel/i40e/i40e.ko 403904
    ./drivers/net/ethernet/broadcom/bnx2x/bnx2x.ko 398754
    ./drivers/infiniband/core/ib_core.ko 397224
    ./fs/cifs/cifs.ko 386249
    ./fs/nfsd/nfsd.ko 379738
    
    SPLIT BTF
    =========
    
    $ for f in $(find . -name '*.ko'); do size -A -d $f | grep BTF | awk '{print $2}'; done | awk '{ s += $1 } END { print s }'
    5194047
    
    $ for f in $(find . -name '*.ko'); do printf "%s %d\n" $f $(size -A -d $f | grep BTF | awk '{print $2}'); done | sort -nr -k2 | head -n10
    ./drivers/gpu/drm/i915/i915.ko 293206
    ./drivers/gpu/drm/radeon/radeon.ko 282103
    ./fs/xfs/xfs.ko 222150
    ./drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko 198503
    ./drivers/infiniband/hw/mlx5/mlx5_ib.ko 198356
    ./drivers/net/ethernet/broadcom/bnx2x/bnx2x.ko 113444
    ./fs/cifs/cifs.ko 109379
    ./arch/x86/kvm/kvm.ko 100225
    ./drivers/gpu/drm/drm.ko 94827
    ./drivers/infiniband/core/ib_core.ko 91188
    Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
    Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    Link: https://lore.kernel.org/bpf/20201110011932.3201430-4-andrii@kernel.org
    5f9ae91f
Makefile.modfinal 2.48 KB