While attempting to learn more about BPF and libbpf, I ran into an issue I can't quite seem to resolve. While writing some tools to practice tracing with libbpf, I came across a situation where I get an error when using BPF_CORE_READ, which appears to be that CO-RE relocation failed to find a corresponding field. Compilation doesn't complain, just when I try to execute. Error Message: --------------------------------------------- 8: (85) call unknown#195896080 invalid func unknown#195896080 I'm using the Makefile from libbpf-bootstrap to build my program. The other example programs build and execute properly, and I've also successfully used tracepoints to trace the nvme_setup_cmd and nvme_complete_rq functions. My issue appears to be when I attempt to use kprobes for the nvme_submit_cmd function. In the program I'm attempting to trace the nvme_command structure to get the opcode of the command in the function nvme_submit_cmd. I'm using Rocky Linux (RedHat based distro) with their kernel version of 4.18. I verified the structures and interfaces in the source code, vs the default 4.18 version of the kernel and made the appropriate changes. traceopcode.bpf.c --------------------------------------------- #include "vmlinux.h" #include <bpf/bpf_helpers.h> #include <bpf/bpf_tracing.h> #include <bpf/bpf_core_read.h> #include "traceopcode.h" char LICENSE[] SEC("license") = "Dual BSD/GPL"; struct { __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 1024 * 1024); } ring_buffer SEC(".maps"); struct nvme_common_command { __u8 opcode; } __attribute__((preserve_access_index)); struct nvme_command { union { struct nvme_common_command common; }; } __attribute__((preserve_access_index)); SEC("kprobe/nvme_submit_cmd") int BPF_KPROBE(nvme_submit_cmd, void *nvmeq, struct nvme_command *cmd, bool write_sq) { struct opcode_event *e; e = bpf_ringbuf_reserve(&ring_buffer, sizeof(*e), 0); if (!e) return 0; e->opcode = BPF_CORE_READ(cmd, common.opcode); //e->opcode = cmd->common.opcode; bpf_ringbuf_submit(e, 0); return 0; } traceopcode.h --------------------------------------------- #ifndef __TRACEOPCODE_H #define __TRACEOPCODE_H struct opcode_event { __u8 opcode; }; #endif My userspace code is basically the same as the bootstrap example, with a modification to the handler that just prints out the opcode from the opcode_event structure. My guess is that I have some problem with how I'm defining the structs that I'm using for nvme_command, as they aren't part of vmlinux and need to be defined in my bpf program. Any help or guidance would be appreciated. Thanks, John Mazzie