Skip to content

Commit b870aa9

Browse files
4astdavem330
authored andcommitted
bpf: use different interpreter depending on required stack size
16 __bpf_prog_run() interpreters for various stack sizes add .text but not a lot comparing to run-time stack savings text data bss dec hex filename 26350 10328 624 37302 91b6 kernel/bpf/core.o.before_split 25777 10328 624 36729 8f79 kernel/bpf/core.o.after_split 26970 10328 624 37922 9422 kernel/bpf/core.o.now Signed-off-by: Alexei Starovoitov <[email protected]> Acked-by: Daniel Borkmann <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 105c036 commit b870aa9

File tree

1 file changed

+31
-9
lines changed

1 file changed

+31
-9
lines changed

kernel/bpf/core.c

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,16 +1218,38 @@ static unsigned int ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn,
12181218
}
12191219
STACK_FRAME_NON_STANDARD(___bpf_prog_run); /* jump table */
12201220

1221-
static unsigned int __bpf_prog_run(void *ctx, const struct bpf_insn *insn)
1222-
{
1223-
u64 stack[MAX_BPF_STACK / sizeof(u64)];
1224-
u64 regs[MAX_BPF_REG];
1225-
1226-
FP = (u64) (unsigned long) &stack[ARRAY_SIZE(stack)];
1227-
ARG1 = (u64) (unsigned long) ctx;
1228-
return ___bpf_prog_run(regs, insn, stack);
1221+
#define PROG_NAME(stack_size) __bpf_prog_run##stack_size
1222+
#define DEFINE_BPF_PROG_RUN(stack_size) \
1223+
static unsigned int PROG_NAME(stack_size)(const void *ctx, const struct bpf_insn *insn) \
1224+
{ \
1225+
u64 stack[stack_size / sizeof(u64)]; \
1226+
u64 regs[MAX_BPF_REG]; \
1227+
\
1228+
FP = (u64) (unsigned long) &stack[ARRAY_SIZE(stack)]; \
1229+
ARG1 = (u64) (unsigned long) ctx; \
1230+
return ___bpf_prog_run(regs, insn, stack); \
12291231
}
12301232

1233+
#define EVAL1(FN, X) FN(X)
1234+
#define EVAL2(FN, X, Y...) FN(X) EVAL1(FN, Y)
1235+
#define EVAL3(FN, X, Y...) FN(X) EVAL2(FN, Y)
1236+
#define EVAL4(FN, X, Y...) FN(X) EVAL3(FN, Y)
1237+
#define EVAL5(FN, X, Y...) FN(X) EVAL4(FN, Y)
1238+
#define EVAL6(FN, X, Y...) FN(X) EVAL5(FN, Y)
1239+
1240+
EVAL6(DEFINE_BPF_PROG_RUN, 32, 64, 96, 128, 160, 192);
1241+
EVAL6(DEFINE_BPF_PROG_RUN, 224, 256, 288, 320, 352, 384);
1242+
EVAL4(DEFINE_BPF_PROG_RUN, 416, 448, 480, 512);
1243+
1244+
#define PROG_NAME_LIST(stack_size) PROG_NAME(stack_size),
1245+
1246+
static unsigned int (*interpreters[])(const void *ctx,
1247+
const struct bpf_insn *insn) = {
1248+
EVAL6(PROG_NAME_LIST, 32, 64, 96, 128, 160, 192)
1249+
EVAL6(PROG_NAME_LIST, 224, 256, 288, 320, 352, 384)
1250+
EVAL4(PROG_NAME_LIST, 416, 448, 480, 512)
1251+
};
1252+
12311253
bool bpf_prog_array_compatible(struct bpf_array *array,
12321254
const struct bpf_prog *fp)
12331255
{
@@ -1275,7 +1297,7 @@ static int bpf_check_tail_call(const struct bpf_prog *fp)
12751297
*/
12761298
struct bpf_prog *bpf_prog_select_runtime(struct bpf_prog *fp, int *err)
12771299
{
1278-
fp->bpf_func = (void *) __bpf_prog_run;
1300+
fp->bpf_func = interpreters[round_down(fp->aux->stack_depth, 32) / 32];
12791301

12801302
/* eBPF JITs can rewrite the program in case constant
12811303
* blinding is active. However, in case of error during

0 commit comments

Comments
 (0)