Skip to content

Commit

Permalink
fix(driver/modern_bpf): avoid bpf_loop() helper.
Browse files Browse the repository at this point in the history
We can't use bpf_loop() helper since the `bpf_core_enum_value_exists` check
triggers a verifier failure on kernels prior to 5.13 that hadn't got `PTR_TO_FUNC` support.
See https://lore.kernel.org/bpf/CAGQdkDt9zyQwr5JyftXqL=OLKscNcqUtEteY4hvOkx2S4GdEkQ@mail.gmail.com/T/#u.

Instead, loop up to 16 messages.

Signed-off-by: Federico Di Pierro <[email protected]>

Co-authored-by: Andrea Terzolo <[email protected]>
  • Loading branch information
2 people authored and poiana committed Jan 14, 2025
1 parent 4f9be74 commit 8362ae9
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 16 deletions.
3 changes: 3 additions & 0 deletions driver/modern_bpf/helpers/base/shared_size.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
/* Maximum number of `iovec` structures that we can analyze. */
#define MAX_IOVCNT 32

/* Maximum number of supported sendmmsg/recvmmsg messages */
#define MAX_SENDMMSG_RECVMMSG_SIZE 16

/* Maximum number of `pollfd` structures that we can analyze. */
#define MAX_POLLFD 16

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ typedef struct {
void *ctx;
} recvmmsg_data_t;

static long handle_exit(uint32_t index, void *ctx) {
static __always_inline long handle_exit(uint32_t index, void *ctx) {
recvmmsg_data_t *data = (recvmmsg_data_t *)ctx;
struct mmsghdr mmh = {0};
if(bpf_probe_read_user((void *)&mmh,
Expand Down Expand Up @@ -159,14 +159,17 @@ int BPF_PROG(recvmmsg_x, struct pt_regs *regs, long ret) {
.ctx = ctx,
};

if(bpf_core_enum_value_exists(enum bpf_func_id, BPF_FUNC_loop)) {
uint32_t nr_loops = ret < 1024 ? ret : 1024;
bpf_loop(nr_loops, handle_exit, &data, 0);
} else {
for(int i = 0; i < ret && i < MAX_IOVCNT; i++) {
handle_exit(i, &data);
}
// We can't use bpf_loop() helper since the below check triggers a verifier failure:
// see
// https://lore.kernel.org/bpf/CAGQdkDt9zyQwr5JyftXqL=OLKscNcqUtEteY4hvOkx2S4GdEkQ@mail.gmail.com/T/#u
/*if(bpf_core_enum_value_exists(enum bpf_func_id, BPF_FUNC_loop)) {
uint32_t nr_loops = ret < 1024 ? ret : 1024;
bpf_loop(nr_loops, handle_exit, &data, 0);
} else {*/
for(int i = 0; i < ret && i < MAX_SENDMMSG_RECVMMSG_SIZE; i++) {
handle_exit(i, &data);
}
//}

return 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ typedef struct {
void *ctx;
} sendmmsg_exit_t;

static long handle_exit(uint32_t index, void *ctx) {
static __always_inline long handle_exit(uint32_t index, void *ctx) {
sendmmsg_exit_t *data = (sendmmsg_exit_t *)ctx;
struct mmsghdr mmh = {0};

Expand Down Expand Up @@ -152,14 +152,17 @@ int BPF_PROG(sendmmsg_x, struct pt_regs *regs, long ret) {
.ctx = ctx,
};

if(bpf_core_enum_value_exists(enum bpf_func_id, BPF_FUNC_loop)) {
uint32_t nr_loops = ret < 1024 ? ret : 1024;
bpf_loop(nr_loops, handle_exit, &data, 0);
} else {
for(int i = 0; i < ret && i < MAX_IOVCNT; i++) {
handle_exit(i, &data);
}
// We can't use bpf_loop() helper since the below check triggers a verifier failure:
// see
// https://lore.kernel.org/bpf/CAGQdkDt9zyQwr5JyftXqL=OLKscNcqUtEteY4hvOkx2S4GdEkQ@mail.gmail.com/T/#u
/*if(bpf_core_enum_value_exists(enum bpf_func_id, BPF_FUNC_loop)) {
uint32_t nr_loops = ret < 1024 ? ret : 1024;
bpf_loop(nr_loops, handle_exit, &data, 0);
} else {*/
for(int i = 0; i < ret && i < MAX_SENDMMSG_RECVMMSG_SIZE; i++) {
handle_exit(i, &data);
}
//}

return 0;
}
Expand Down

0 comments on commit 8362ae9

Please sign in to comment.