Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bpf: Refactor BPF_PROG_RUN into a function

Turn BPF_PROG_RUN into a proper always inlined function. No functional and
performance changes are intended, but it makes it much easier to understand
what's going on with how BPF programs are actually get executed. It's more
obvious what types and callbacks are expected. Also extra () around input
parameters can be dropped, as well as `__` variable prefixes intended to avoid
naming collisions, which makes the code simpler to read and write.

This refactoring also highlighted one extra issue. BPF_PROG_RUN is both
a macro and an enum value (BPF_PROG_RUN == BPF_PROG_TEST_RUN). Turning
BPF_PROG_RUN into a function causes naming conflict compilation error. So
rename BPF_PROG_RUN into lower-case bpf_prog_run(), similar to
bpf_prog_run_xdp(), bpf_prog_run_pin_on_cpu(), etc. All existing callers of
BPF_PROG_RUN, the macro, are switched to bpf_prog_run() explicitly.

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Yonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/bpf/20210815070609.987780-2-andrii@kernel.org

authored by

Andrii Nakryiko and committed by
Daniel Borkmann
fb7dd8bc 1bda52f8

+72 -59
+2 -2
Documentation/networking/filter.rst
··· 638 638 converted by the kernel into the new instruction set representation and run 639 639 in the eBPF interpreter. For in-kernel handlers, this all works transparently 640 640 by using bpf_prog_create() for setting up the filter, resp. 641 - bpf_prog_destroy() for destroying it. The macro 642 - BPF_PROG_RUN(filter, ctx) transparently invokes eBPF interpreter or JITed 641 + bpf_prog_destroy() for destroying it. The function 642 + bpf_prog_run(filter, ctx) transparently invokes eBPF interpreter or JITed 643 643 code to run the filter. 'filter' is a pointer to struct bpf_prog that we 644 644 got from bpf_prog_create(), and 'ctx' the given context (e.g. 645 645 skb pointer). All constraints and restrictions from bpf_check_classic() apply
+1 -1
drivers/media/rc/bpf-lirc.c
··· 217 217 raw->bpf_sample = sample; 218 218 219 219 if (raw->progs) 220 - BPF_PROG_RUN_ARRAY(raw->progs, &raw->bpf_sample, BPF_PROG_RUN); 220 + BPF_PROG_RUN_ARRAY(raw->progs, &raw->bpf_sample, bpf_prog_run); 221 221 } 222 222 223 223 /*
+4 -4
drivers/net/ppp/ppp_generic.c
··· 1744 1744 a four-byte PPP header on each packet */ 1745 1745 *(u8 *)skb_push(skb, 2) = 1; 1746 1746 if (ppp->pass_filter && 1747 - BPF_PROG_RUN(ppp->pass_filter, skb) == 0) { 1747 + bpf_prog_run(ppp->pass_filter, skb) == 0) { 1748 1748 if (ppp->debug & 1) 1749 1749 netdev_printk(KERN_DEBUG, ppp->dev, 1750 1750 "PPP: outbound frame " ··· 1754 1754 } 1755 1755 /* if this packet passes the active filter, record the time */ 1756 1756 if (!(ppp->active_filter && 1757 - BPF_PROG_RUN(ppp->active_filter, skb) == 0)) 1757 + bpf_prog_run(ppp->active_filter, skb) == 0)) 1758 1758 ppp->last_xmit = jiffies; 1759 1759 skb_pull(skb, 2); 1760 1760 #else ··· 2468 2468 2469 2469 *(u8 *)skb_push(skb, 2) = 0; 2470 2470 if (ppp->pass_filter && 2471 - BPF_PROG_RUN(ppp->pass_filter, skb) == 0) { 2471 + bpf_prog_run(ppp->pass_filter, skb) == 0) { 2472 2472 if (ppp->debug & 1) 2473 2473 netdev_printk(KERN_DEBUG, ppp->dev, 2474 2474 "PPP: inbound frame " ··· 2477 2477 return; 2478 2478 } 2479 2479 if (!(ppp->active_filter && 2480 - BPF_PROG_RUN(ppp->active_filter, skb) == 0)) 2480 + bpf_prog_run(ppp->active_filter, skb) == 0)) 2481 2481 ppp->last_recv = jiffies; 2482 2482 __skb_pull(skb, 2); 2483 2483 } else
+1 -1
drivers/net/team/team_mode_loadbalance.c
··· 197 197 fp = rcu_dereference_bh(lb_priv->fp); 198 198 if (unlikely(!fp)) 199 199 return 0; 200 - lhash = BPF_PROG_RUN(fp, skb); 200 + lhash = bpf_prog_run(fp, skb); 201 201 c = (char *) &lhash; 202 202 return c[0] ^ c[1] ^ c[2] ^ c[3]; 203 203 }
+1 -1
include/linux/bpf.h
··· 1103 1103 /* an array of programs to be executed under rcu_lock. 1104 1104 * 1105 1105 * Typical usage: 1106 - * ret = BPF_PROG_RUN_ARRAY(&bpf_prog_array, ctx, BPF_PROG_RUN); 1106 + * ret = BPF_PROG_RUN_ARRAY(&bpf_prog_array, ctx, bpf_prog_run); 1107 1107 * 1108 1108 * the structure returned by bpf_prog_array_alloc() should be populated 1109 1109 * with program pointers and the last pointer must be NULL.
+36 -23
include/linux/filter.h
··· 600 600 601 601 DECLARE_STATIC_KEY_FALSE(bpf_stats_enabled_key); 602 602 603 - #define __BPF_PROG_RUN(prog, ctx, dfunc) ({ \ 604 - u32 __ret; \ 605 - cant_migrate(); \ 606 - if (static_branch_unlikely(&bpf_stats_enabled_key)) { \ 607 - struct bpf_prog_stats *__stats; \ 608 - u64 __start = sched_clock(); \ 609 - __ret = dfunc(ctx, (prog)->insnsi, (prog)->bpf_func); \ 610 - __stats = this_cpu_ptr(prog->stats); \ 611 - u64_stats_update_begin(&__stats->syncp); \ 612 - __stats->cnt++; \ 613 - __stats->nsecs += sched_clock() - __start; \ 614 - u64_stats_update_end(&__stats->syncp); \ 615 - } else { \ 616 - __ret = dfunc(ctx, (prog)->insnsi, (prog)->bpf_func); \ 617 - } \ 618 - __ret; }) 603 + typedef unsigned int (*bpf_dispatcher_fn)(const void *ctx, 604 + const struct bpf_insn *insnsi, 605 + unsigned int (*bpf_func)(const void *, 606 + const struct bpf_insn *)); 619 607 620 - #define BPF_PROG_RUN(prog, ctx) \ 621 - __BPF_PROG_RUN(prog, ctx, bpf_dispatcher_nop_func) 608 + static __always_inline u32 __bpf_prog_run(const struct bpf_prog *prog, 609 + const void *ctx, 610 + bpf_dispatcher_fn dfunc) 611 + { 612 + u32 ret; 613 + 614 + cant_migrate(); 615 + if (static_branch_unlikely(&bpf_stats_enabled_key)) { 616 + struct bpf_prog_stats *stats; 617 + u64 start = sched_clock(); 618 + 619 + ret = dfunc(ctx, prog->insnsi, prog->bpf_func); 620 + stats = this_cpu_ptr(prog->stats); 621 + u64_stats_update_begin(&stats->syncp); 622 + stats->cnt++; 623 + stats->nsecs += sched_clock() - start; 624 + u64_stats_update_end(&stats->syncp); 625 + } else { 626 + ret = dfunc(ctx, prog->insnsi, prog->bpf_func); 627 + } 628 + return ret; 629 + } 630 + 631 + static __always_inline u32 bpf_prog_run(const struct bpf_prog *prog, const void *ctx) 632 + { 633 + return __bpf_prog_run(prog, ctx, bpf_dispatcher_nop_func); 634 + } 622 635 623 636 /* 624 637 * Use in preemptible and therefore migratable context to make sure that ··· 650 637 u32 ret; 651 638 652 639 migrate_disable(); 653 - ret = __BPF_PROG_RUN(prog, ctx, bpf_dispatcher_nop_func); 640 + ret = bpf_prog_run(prog, ctx); 654 641 migrate_enable(); 655 642 return ret; 656 643 } ··· 755 742 memset(cb_data, 0, sizeof(cb_saved)); 756 743 } 757 744 758 - res = BPF_PROG_RUN(prog, skb); 745 + res = bpf_prog_run(prog, skb); 759 746 760 747 if (unlikely(prog->cb_access)) 761 748 memcpy(cb_data, cb_saved, sizeof(cb_saved)); ··· 800 787 * under local_bh_disable(), which provides the needed RCU protection 801 788 * for accessing map entries. 802 789 */ 803 - u32 act = __BPF_PROG_RUN(prog, xdp, BPF_DISPATCHER_FUNC(xdp)); 790 + u32 act = __bpf_prog_run(prog, xdp, BPF_DISPATCHER_FUNC(xdp)); 804 791 805 792 if (static_branch_unlikely(&bpf_master_redirect_enabled_key)) { 806 793 if (act == XDP_TX && netif_is_bond_slave(xdp->rxq->dev)) ··· 1453 1440 }; 1454 1441 u32 act; 1455 1442 1456 - act = BPF_PROG_SK_LOOKUP_RUN_ARRAY(run_array, ctx, BPF_PROG_RUN); 1443 + act = BPF_PROG_SK_LOOKUP_RUN_ARRAY(run_array, ctx, bpf_prog_run); 1457 1444 if (act == SK_PASS) { 1458 1445 selected_sk = ctx.selected_sk; 1459 1446 no_reuseport = ctx.no_reuseport; ··· 1491 1478 }; 1492 1479 u32 act; 1493 1480 1494 - act = BPF_PROG_SK_LOOKUP_RUN_ARRAY(run_array, ctx, BPF_PROG_RUN); 1481 + act = BPF_PROG_SK_LOOKUP_RUN_ARRAY(run_array, ctx, bpf_prog_run); 1495 1482 if (act == SK_PASS) { 1496 1483 selected_sk = ctx.selected_sk; 1497 1484 no_reuseport = ctx.no_reuseport;
+1 -1
kernel/bpf/bpf_iter.c
··· 686 686 687 687 rcu_read_lock(); 688 688 migrate_disable(); 689 - ret = BPF_PROG_RUN(prog, ctx); 689 + ret = bpf_prog_run(prog, ctx); 690 690 migrate_enable(); 691 691 rcu_read_unlock(); 692 692
+8 -8
kernel/bpf/cgroup.c
··· 1043 1043 struct cgroup *cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data); 1044 1044 int ret; 1045 1045 1046 - ret = BPF_PROG_RUN_ARRAY(cgrp->bpf.effective[type], sk, BPF_PROG_RUN); 1046 + ret = BPF_PROG_RUN_ARRAY(cgrp->bpf.effective[type], sk, bpf_prog_run); 1047 1047 return ret == 1 ? 0 : -EPERM; 1048 1048 } 1049 1049 EXPORT_SYMBOL(__cgroup_bpf_run_filter_sk); ··· 1091 1091 1092 1092 cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data); 1093 1093 ret = BPF_PROG_RUN_ARRAY_FLAGS(cgrp->bpf.effective[type], &ctx, 1094 - BPF_PROG_RUN, flags); 1094 + bpf_prog_run, flags); 1095 1095 1096 1096 return ret == 1 ? 0 : -EPERM; 1097 1097 } ··· 1121 1121 int ret; 1122 1122 1123 1123 ret = BPF_PROG_RUN_ARRAY(cgrp->bpf.effective[type], sock_ops, 1124 - BPF_PROG_RUN); 1124 + bpf_prog_run); 1125 1125 return ret == 1 ? 0 : -EPERM; 1126 1126 } 1127 1127 EXPORT_SYMBOL(__cgroup_bpf_run_filter_sock_ops); ··· 1140 1140 rcu_read_lock(); 1141 1141 cgrp = task_dfl_cgroup(current); 1142 1142 allow = BPF_PROG_RUN_ARRAY(cgrp->bpf.effective[type], &ctx, 1143 - BPF_PROG_RUN); 1143 + bpf_prog_run); 1144 1144 rcu_read_unlock(); 1145 1145 1146 1146 return !allow; ··· 1271 1271 1272 1272 rcu_read_lock(); 1273 1273 cgrp = task_dfl_cgroup(current); 1274 - ret = BPF_PROG_RUN_ARRAY(cgrp->bpf.effective[type], &ctx, BPF_PROG_RUN); 1274 + ret = BPF_PROG_RUN_ARRAY(cgrp->bpf.effective[type], &ctx, bpf_prog_run); 1275 1275 rcu_read_unlock(); 1276 1276 1277 1277 kfree(ctx.cur_val); ··· 1386 1386 1387 1387 lock_sock(sk); 1388 1388 ret = BPF_PROG_RUN_ARRAY(cgrp->bpf.effective[BPF_CGROUP_SETSOCKOPT], 1389 - &ctx, BPF_PROG_RUN); 1389 + &ctx, bpf_prog_run); 1390 1390 release_sock(sk); 1391 1391 1392 1392 if (!ret) { ··· 1496 1496 1497 1497 lock_sock(sk); 1498 1498 ret = BPF_PROG_RUN_ARRAY(cgrp->bpf.effective[BPF_CGROUP_GETSOCKOPT], 1499 - &ctx, BPF_PROG_RUN); 1499 + &ctx, bpf_prog_run); 1500 1500 release_sock(sk); 1501 1501 1502 1502 if (!ret) { ··· 1557 1557 */ 1558 1558 1559 1559 ret = BPF_PROG_RUN_ARRAY(cgrp->bpf.effective[BPF_CGROUP_GETSOCKOPT], 1560 - &ctx, BPF_PROG_RUN); 1560 + &ctx, bpf_prog_run); 1561 1561 if (!ret) 1562 1562 return -EPERM; 1563 1563
+1 -1
kernel/bpf/core.c
··· 1879 1879 * @err: pointer to error variable 1880 1880 * 1881 1881 * Try to JIT eBPF program, if JIT is not available, use interpreter. 1882 - * The BPF program will be executed via BPF_PROG_RUN() macro. 1882 + * The BPF program will be executed via bpf_prog_run() function. 1883 1883 * 1884 1884 * Return: the &fp argument along with &err set to 0 for success or 1885 1885 * a negative errno code on failure
+1 -1
kernel/bpf/trampoline.c
··· 548 548 u64_stats_update_end(&stats->syncp); 549 549 } 550 550 551 - /* The logic is similar to BPF_PROG_RUN, but with an explicit 551 + /* The logic is similar to bpf_prog_run(), but with an explicit 552 552 * rcu_read_lock() and migrate_disable() which are required 553 553 * for the trampoline. The macro is split into 554 554 * call __bpf_prog_enter
+1 -1
kernel/bpf/verifier.c
··· 12383 12383 subprog_end = env->subprog_info[i + 1].start; 12384 12384 12385 12385 len = subprog_end - subprog_start; 12386 - /* BPF_PROG_RUN doesn't call subprogs directly, 12386 + /* bpf_prog_run() doesn't call subprogs directly, 12387 12387 * hence main prog stats include the runtime of subprogs. 12388 12388 * subprogs don't have IDs and not reachable via prog_get_next_id 12389 12389 * func[i]->stats will never be accessed and stays NULL
+1 -1
kernel/events/core.c
··· 9913 9913 if (unlikely(__this_cpu_inc_return(bpf_prog_active) != 1)) 9914 9914 goto out; 9915 9915 rcu_read_lock(); 9916 - ret = BPF_PROG_RUN(event->prog, &ctx); 9916 + ret = bpf_prog_run(event->prog, &ctx); 9917 9917 rcu_read_unlock(); 9918 9918 out: 9919 9919 __this_cpu_dec(bpf_prog_active);
+2 -2
kernel/trace/bpf_trace.c
··· 124 124 * out of events when it was updated in between this and the 125 125 * rcu_dereference() which is accepted risk. 126 126 */ 127 - ret = BPF_PROG_RUN_ARRAY_CHECK(call->prog_array, ctx, BPF_PROG_RUN); 127 + ret = BPF_PROG_RUN_ARRAY_CHECK(call->prog_array, ctx, bpf_prog_run); 128 128 129 129 out: 130 130 __this_cpu_dec(bpf_prog_active); ··· 1816 1816 { 1817 1817 cant_sleep(); 1818 1818 rcu_read_lock(); 1819 - (void) BPF_PROG_RUN(prog, args); 1819 + (void) bpf_prog_run(prog, args); 1820 1820 rcu_read_unlock(); 1821 1821 } 1822 1822
+1 -1
lib/test_bpf.c
··· 8616 8616 start = ktime_get_ns(); 8617 8617 8618 8618 for (i = 0; i < runs; i++) 8619 - ret = BPF_PROG_RUN(fp, data); 8619 + ret = bpf_prog_run(fp, data); 8620 8620 8621 8621 finish = ktime_get_ns(); 8622 8622 migrate_enable();
+3 -3
net/bpf/test_run.c
··· 116 116 if (xdp) 117 117 *retval = bpf_prog_run_xdp(prog, ctx); 118 118 else 119 - *retval = BPF_PROG_RUN(prog, ctx); 119 + *retval = bpf_prog_run(prog, ctx); 120 120 } while (bpf_test_timer_continue(&t, repeat, &ret, time)); 121 121 bpf_reset_run_ctx(old_ctx); 122 122 bpf_test_timer_leave(&t); ··· 327 327 struct bpf_raw_tp_test_run_info *info = data; 328 328 329 329 rcu_read_lock(); 330 - info->retval = BPF_PROG_RUN(info->prog, info->ctx); 330 + info->retval = bpf_prog_run(info->prog, info->ctx); 331 331 rcu_read_unlock(); 332 332 } 333 333 ··· 989 989 bpf_test_timer_enter(&t); 990 990 do { 991 991 ctx.selected_sk = NULL; 992 - retval = BPF_PROG_SK_LOOKUP_RUN_ARRAY(progs, ctx, BPF_PROG_RUN); 992 + retval = BPF_PROG_SK_LOOKUP_RUN_ARRAY(progs, ctx, bpf_prog_run); 993 993 } while (bpf_test_timer_continue(&t, repeat, &ret, &duration)); 994 994 bpf_test_timer_leave(&t); 995 995
+2 -2
net/core/filter.c
··· 114 114 * Run the eBPF program and then cut skb->data to correct size returned by 115 115 * the program. If pkt_len is 0 we toss packet. If skb->len is smaller 116 116 * than pkt_len we keep whole skb->data. This is the socket level 117 - * wrapper to BPF_PROG_RUN. It returns 0 if the packet should 117 + * wrapper to bpf_prog_run. It returns 0 if the packet should 118 118 * be accepted or -EPERM if the packet should be tossed. 119 119 * 120 120 */ ··· 10115 10115 enum sk_action action; 10116 10116 10117 10117 bpf_init_reuseport_kern(&reuse_kern, reuse, sk, skb, migrating_sk, hash); 10118 - action = BPF_PROG_RUN(prog, &reuse_kern); 10118 + action = bpf_prog_run(prog, &reuse_kern); 10119 10119 10120 10120 if (action == SK_PASS) 10121 10121 return reuse_kern.selected_sk;
+1 -1
net/core/ptp_classifier.c
··· 103 103 104 104 unsigned int ptp_classify_raw(const struct sk_buff *skb) 105 105 { 106 - return BPF_PROG_RUN(ptp_insns, skb); 106 + return bpf_prog_run(ptp_insns, skb); 107 107 } 108 108 EXPORT_SYMBOL_GPL(ptp_classify_raw); 109 109
+1 -1
net/netfilter/xt_bpf.c
··· 90 90 { 91 91 const struct xt_bpf_info *info = par->matchinfo; 92 92 93 - return BPF_PROG_RUN(info->filter, skb); 93 + return bpf_prog_run(info->filter, skb); 94 94 } 95 95 96 96 static bool bpf_mt_v1(const struct sk_buff *skb, struct xt_action_param *par)
+2 -2
net/sched/act_bpf.c
··· 47 47 if (at_ingress) { 48 48 __skb_push(skb, skb->mac_len); 49 49 bpf_compute_data_pointers(skb); 50 - filter_res = BPF_PROG_RUN(filter, skb); 50 + filter_res = bpf_prog_run(filter, skb); 51 51 __skb_pull(skb, skb->mac_len); 52 52 } else { 53 53 bpf_compute_data_pointers(skb); 54 - filter_res = BPF_PROG_RUN(filter, skb); 54 + filter_res = bpf_prog_run(filter, skb); 55 55 } 56 56 if (skb_sk_is_prefetched(skb) && filter_res != TC_ACT_OK) 57 57 skb_orphan(skb);
+2 -2
net/sched/cls_bpf.c
··· 96 96 /* It is safe to push/pull even if skb_shared() */ 97 97 __skb_push(skb, skb->mac_len); 98 98 bpf_compute_data_pointers(skb); 99 - filter_res = BPF_PROG_RUN(prog->filter, skb); 99 + filter_res = bpf_prog_run(prog->filter, skb); 100 100 __skb_pull(skb, skb->mac_len); 101 101 } else { 102 102 bpf_compute_data_pointers(skb); 103 - filter_res = BPF_PROG_RUN(prog->filter, skb); 103 + filter_res = bpf_prog_run(prog->filter, skb); 104 104 } 105 105 106 106 if (prog->exts_integrated) {