Skip to content

Commit 4d9c5c5

Browse files
Alexei Starovoitovdavem330
authored andcommitted
test_bpf: add bpf_skb_vlan_push/pop() tests
improve accuracy of timing in test_bpf and add two stress tests: - {skb->data[0], get_smp_processor_id} repeated 2k times - {skb->data[0], vlan_push} x 68 followed by {skb->data[0], vlan_pop} x 68 1st test is useful to test performance of JIT implementation of BPF_LD_ABS together with BPF_CALL instructions. 2nd test is stressing skb_vlan_push/pop logic together with skb->data access via BPF_LD_ABS insn which checks that re-caching of skb->data is done correctly. In order to call bpf_skb_vlan_push() from test_bpf.ko have to add three export_symbol_gpl. Signed-off-by: Alexei Starovoitov <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 4e10df9 commit 4d9c5c5

File tree

3 files changed

+98
-3
lines changed

3 files changed

+98
-3
lines changed

kernel/bpf/core.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ noinline u64 __bpf_call_base(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
177177
{
178178
return 0;
179179
}
180+
EXPORT_SYMBOL_GPL(__bpf_call_base);
180181

181182
/**
182183
* __bpf_prog_run - run eBPF program on a given context

lib/test_bpf.c

Lines changed: 95 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/init.h>
1919
#include <linux/module.h>
2020
#include <linux/filter.h>
21+
#include <linux/bpf.h>
2122
#include <linux/skbuff.h>
2223
#include <linux/netdevice.h>
2324
#include <linux/if_vlan.h>
@@ -355,6 +356,81 @@ static int bpf_fill_ja(struct bpf_test *self)
355356
return __bpf_fill_ja(self, 12, 9);
356357
}
357358

359+
static int bpf_fill_ld_abs_get_processor_id(struct bpf_test *self)
360+
{
361+
unsigned int len = BPF_MAXINSNS;
362+
struct sock_filter *insn;
363+
int i;
364+
365+
insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL);
366+
if (!insn)
367+
return -ENOMEM;
368+
369+
for (i = 0; i < len - 1; i += 2) {
370+
insn[i] = __BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 0);
371+
insn[i + 1] = __BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
372+
SKF_AD_OFF + SKF_AD_CPU);
373+
}
374+
375+
insn[len - 1] = __BPF_STMT(BPF_RET | BPF_K, 0xbee);
376+
377+
self->u.ptr.insns = insn;
378+
self->u.ptr.len = len;
379+
380+
return 0;
381+
}
382+
383+
#define PUSH_CNT 68
384+
/* test: {skb->data[0], vlan_push} x 68 + {skb->data[0], vlan_pop} x 68 */
385+
static int bpf_fill_ld_abs_vlan_push_pop(struct bpf_test *self)
386+
{
387+
unsigned int len = BPF_MAXINSNS;
388+
struct bpf_insn *insn;
389+
int i = 0, j, k = 0;
390+
391+
insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL);
392+
if (!insn)
393+
return -ENOMEM;
394+
395+
insn[i++] = BPF_MOV64_REG(R6, R1);
396+
loop:
397+
for (j = 0; j < PUSH_CNT; j++) {
398+
insn[i++] = BPF_LD_ABS(BPF_B, 0);
399+
insn[i] = BPF_JMP_IMM(BPF_JNE, R0, 0x34, len - i - 2);
400+
i++;
401+
insn[i++] = BPF_MOV64_REG(R1, R6);
402+
insn[i++] = BPF_MOV64_IMM(R2, 1);
403+
insn[i++] = BPF_MOV64_IMM(R3, 2);
404+
insn[i++] = BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
405+
bpf_skb_vlan_push_proto.func - __bpf_call_base);
406+
insn[i] = BPF_JMP_IMM(BPF_JNE, R0, 0, len - i - 2);
407+
i++;
408+
}
409+
410+
for (j = 0; j < PUSH_CNT; j++) {
411+
insn[i++] = BPF_LD_ABS(BPF_B, 0);
412+
insn[i] = BPF_JMP_IMM(BPF_JNE, R0, 0x34, len - i - 2);
413+
i++;
414+
insn[i++] = BPF_MOV64_REG(R1, R6);
415+
insn[i++] = BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
416+
bpf_skb_vlan_pop_proto.func - __bpf_call_base);
417+
insn[i] = BPF_JMP_IMM(BPF_JNE, R0, 0, len - i - 2);
418+
i++;
419+
}
420+
if (++k < 5)
421+
goto loop;
422+
423+
for (; i < len - 1; i++)
424+
insn[i] = BPF_ALU32_IMM(BPF_MOV, R0, 0xbef);
425+
426+
insn[len - 1] = BPF_EXIT_INSN();
427+
428+
self->u.ptr.insns = insn;
429+
self->u.ptr.len = len;
430+
431+
return 0;
432+
}
433+
358434
static struct bpf_test tests[] = {
359435
{
360436
"TAX",
@@ -4398,6 +4474,22 @@ static struct bpf_test tests[] = {
43984474
{ { 0, 0xababcbac } },
43994475
.fill_helper = bpf_fill_maxinsns11,
44004476
},
4477+
{
4478+
"BPF_MAXINSNS: ld_abs+get_processor_id",
4479+
{ },
4480+
CLASSIC,
4481+
{ },
4482+
{ { 1, 0xbee } },
4483+
.fill_helper = bpf_fill_ld_abs_get_processor_id,
4484+
},
4485+
{
4486+
"BPF_MAXINSNS: ld_abs+vlan_push/pop",
4487+
{ },
4488+
INTERNAL,
4489+
{ 0x34 },
4490+
{ { 1, 0xbef } },
4491+
.fill_helper = bpf_fill_ld_abs_vlan_push_pop,
4492+
},
44014493
};
44024494

44034495
static struct net_device dev;
@@ -4551,14 +4643,14 @@ static int __run_one(const struct bpf_prog *fp, const void *data,
45514643
u64 start, finish;
45524644
int ret = 0, i;
45534645

4554-
start = ktime_to_us(ktime_get());
4646+
start = ktime_get_ns();
45554647

45564648
for (i = 0; i < runs; i++)
45574649
ret = BPF_PROG_RUN(fp, data);
45584650

4559-
finish = ktime_to_us(ktime_get());
4651+
finish = ktime_get_ns();
45604652

4561-
*duration = (finish - start) * 1000ULL;
4653+
*duration = finish - start;
45624654
do_div(*duration, runs);
45634655

45644656
return ret;

net/core/filter.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,6 +1457,7 @@ const struct bpf_func_proto bpf_skb_vlan_push_proto = {
14571457
.arg2_type = ARG_ANYTHING,
14581458
.arg3_type = ARG_ANYTHING,
14591459
};
1460+
EXPORT_SYMBOL_GPL(bpf_skb_vlan_push_proto);
14601461

14611462
static u64 bpf_skb_vlan_pop(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
14621463
{
@@ -1471,6 +1472,7 @@ const struct bpf_func_proto bpf_skb_vlan_pop_proto = {
14711472
.ret_type = RET_INTEGER,
14721473
.arg1_type = ARG_PTR_TO_CTX,
14731474
};
1475+
EXPORT_SYMBOL_GPL(bpf_skb_vlan_pop_proto);
14741476

14751477
bool bpf_helper_changes_skb_data(void *func)
14761478
{

0 commit comments

Comments
 (0)