On Thu, Apr 14, 2022 at 6:42 AM Yang Jihong <yangjihong1@xxxxxxxxxx> wrote:According to the notes of samples/bpf/Makefile:
Inline assembly used by asm/sysreg.h is incompatible with latest llvm,
With "latest" llvm makes it sound like LLVM has regressed. Has it? Or
have the headers changed in a way where now inline asm from a
different target (x86) than what's being targeted (BPF)? Perhaps
fixing that is simpler?
Clang will validate inline asm before LLVM drops unreferenced static
inline functions; this was a headache getting i386 building with
clang, but not insurmountable.
opt add -mtriple=bpf-pc-linux flag,If bpf C program include "linux/ptrace.h" (which is common), compile will fail:
# perf --debug verbose record -e bpf-output/no-inherit,name=evt/ \
-e ./perf_bpf_test.c/map:channel.event=evt/ ls
[SNIP]
/lib/modules/5.17/build/./arch/x86/include/asm/arch_hweight.h:20:7: error: invalid output constraint '=a' in asm
: "="REG_OUT (res)
^
/lib/modules/5.17/build/./arch/x86/include/asm/arch_hweight.h:48:7: error: invalid output constraint '=a' in asm
: "="REG_OUT (res)
^
In file included from /root/projects/perf-bpf/perf_bpf_test.c:2:
In file included from /lib/modules/5.17/build/./include/linux/ptrace.h:6:
In file included from /lib/modules/5.17/build/./include/linux/sched.h:12:
In file included from /lib/modules/5.17/build/./arch/x86/include/asm/current.h:6:
In file included from /lib/modules/5.17/build/./arch/x86/include/asm/percpu.h:27:
In file included from /lib/modules/5.17/build/./include/linux/kernel.h:25:
In file included from /lib/modules/5.17/build/./include/linux/math.h:6:
/lib/modules/5.17.0/build/./arch/x86/include/asm/div64.h:85:28: error: invalid output constraint '=a' in asm
asm ("mulq %2; divq %3" : "=a" (q)
[SNIP]
# cat /root/projects/perf-bpf/perf_bpf_test.c
/************************ BEGIN **************************/
#include <uapi/linux/bpf.h>
#include <linux/ptrace.h>
#include <linux/types.h>
#define SEC(NAME) __attribute__((section(NAME), used))
struct bpf_map_def {
unsigned int type;
unsigned int key_size;
unsigned int value_size;
unsigned int max_entries;
};
static int (*perf_event_output)(void *, struct bpf_map_def *, int, void *,
unsigned long) = (void *)BPF_FUNC_perf_event_output;
struct bpf_map_def SEC("maps") channel = {
.type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
.key_size = sizeof(int),
.value_size = sizeof(__u32),
.max_entries = __NR_CPUS__,
};
#define MIN_BYTES 1024
SEC("func=vfs_read")
int bpf_myprog(struct pt_regs *ctx)
{
long bytes = ctx->dx;
if (bytes >= MIN_BYTES) {
perf_event_output(ctx, &channel, BPF_F_CURRENT_CPU,
&bytes, sizeof(bytes));
}
return 0;
}
char _license[] SEC("license") = "GPL";
int _version SEC("version") = LINUX_VERSION_CODE;
/************************* END ***************************/
Compilation command is modified to be the same as that in samples/bpf/Makefile,
use clang | opt | llvm-dis | llc chain of commands to solve the problem.
see the comment in samples/bpf/Makefile.
Modifications:
1. Change "clang --target bpf" to chain of commands "clang | opt | llvm-dis | llc"
This will drop the --target flag. That will mess up the default target
triple, and can affect command line option feature detection.