mirror of
https://github.com/t2linux/kernel.git
synced 2026-04-30 13:48:59 -07:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next
Daniel Borkmann says: ==================== pull-request: bpf-next 2021-06-28 The following pull-request contains BPF updates for your *net-next* tree. We've added 37 non-merge commits during the last 12 day(s) which contain a total of 56 files changed, 394 insertions(+), 380 deletions(-). The main changes are: 1) XDP driver RCU cleanups, from Toke Høiland-Jørgensen and Paul E. McKenney. 2) Fix bpf_skb_change_proto() IPv4/v6 GSO handling, from Maciej Żenczykowski. 3) Fix false positive kmemleak report for BPF ringbuf alloc, from Rustam Kovhaev. 4) Fix x86 JIT's extable offset calculation for PROBE_LDX NULL, from Ravi Bangoria. 5) Enable libbpf fallback probing with tracing under RHEL7, from Jonathan Edwards. 6) Clean up x86 JIT to remove unused cnt tracking from EMIT macro, from Jiri Olsa. 7) Netlink cleanups for libbpf to please Coverity, from Kumar Kartikeya Dwivedi. 8) Allow to retrieve ancestor cgroup id in tracing programs, from Namhyung Kim. 9) Fix lirc BPF program query to use user-provided prog_cnt, from Sean Young. 10) Add initial libbpf doc including generated kdoc for its API, from Grant Seltzer. 11) Make xdp_rxq_info_unreg_mem_model() more robust, from Jakub Kicinski. 12) Fix up bpfilter startup log-level to info level, from Gary Lin. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -211,27 +211,40 @@ over a rather long period of time, but improvements are always welcome!
|
||||
of the system, especially to real-time workloads running on
|
||||
the rest of the system.
|
||||
|
||||
7. As of v4.20, a given kernel implements only one RCU flavor,
|
||||
which is RCU-sched for PREEMPTION=n and RCU-preempt for PREEMPTION=y.
|
||||
If the updater uses call_rcu() or synchronize_rcu(),
|
||||
then the corresponding readers may use rcu_read_lock() and
|
||||
rcu_read_unlock(), rcu_read_lock_bh() and rcu_read_unlock_bh(),
|
||||
or any pair of primitives that disables and re-enables preemption,
|
||||
for example, rcu_read_lock_sched() and rcu_read_unlock_sched().
|
||||
If the updater uses synchronize_srcu() or call_srcu(),
|
||||
then the corresponding readers must use srcu_read_lock() and
|
||||
srcu_read_unlock(), and with the same srcu_struct. The rules for
|
||||
the expedited primitives are the same as for their non-expedited
|
||||
counterparts. Mixing things up will result in confusion and
|
||||
broken kernels, and has even resulted in an exploitable security
|
||||
issue.
|
||||
7. As of v4.20, a given kernel implements only one RCU flavor, which
|
||||
is RCU-sched for PREEMPTION=n and RCU-preempt for PREEMPTION=y.
|
||||
If the updater uses call_rcu() or synchronize_rcu(), then
|
||||
the corresponding readers may use: (1) rcu_read_lock() and
|
||||
rcu_read_unlock(), (2) any pair of primitives that disables
|
||||
and re-enables softirq, for example, rcu_read_lock_bh() and
|
||||
rcu_read_unlock_bh(), or (3) any pair of primitives that disables
|
||||
and re-enables preemption, for example, rcu_read_lock_sched() and
|
||||
rcu_read_unlock_sched(). If the updater uses synchronize_srcu()
|
||||
or call_srcu(), then the corresponding readers must use
|
||||
srcu_read_lock() and srcu_read_unlock(), and with the same
|
||||
srcu_struct. The rules for the expedited RCU grace-period-wait
|
||||
primitives are the same as for their non-expedited counterparts.
|
||||
|
||||
One exception to this rule: rcu_read_lock() and rcu_read_unlock()
|
||||
may be substituted for rcu_read_lock_bh() and rcu_read_unlock_bh()
|
||||
in cases where local bottom halves are already known to be
|
||||
disabled, for example, in irq or softirq context. Commenting
|
||||
such cases is a must, of course! And the jury is still out on
|
||||
whether the increased speed is worth it.
|
||||
If the updater uses call_rcu_tasks() or synchronize_rcu_tasks(),
|
||||
then the readers must refrain from executing voluntary
|
||||
context switches, that is, from blocking. If the updater uses
|
||||
call_rcu_tasks_trace() or synchronize_rcu_tasks_trace(), then
|
||||
the corresponding readers must use rcu_read_lock_trace() and
|
||||
rcu_read_unlock_trace(). If an updater uses call_rcu_tasks_rude()
|
||||
or synchronize_rcu_tasks_rude(), then the corresponding readers
|
||||
must use anything that disables interrupts.
|
||||
|
||||
Mixing things up will result in confusion and broken kernels, and
|
||||
has even resulted in an exploitable security issue. Therefore,
|
||||
when using non-obvious pairs of primitives, commenting is
|
||||
of course a must. One example of non-obvious pairing is
|
||||
the XDP feature in networking, which calls BPF programs from
|
||||
network-driver NAPI (softirq) context. BPF relies heavily on RCU
|
||||
protection for its data structures, but because the BPF program
|
||||
invocation happens entirely within a single local_bh_disable()
|
||||
section in a NAPI poll cycle, this usage is safe. The reason
|
||||
that this usage is safe is that readers can use anything that
|
||||
disables BH when updaters use call_rcu() or synchronize_rcu().
|
||||
|
||||
8. Although synchronize_rcu() is slower than is call_rcu(), it
|
||||
usually results in simpler code. So, unless update performance is
|
||||
|
||||
@@ -12,6 +12,19 @@ BPF instruction-set.
|
||||
The Cilium project also maintains a `BPF and XDP Reference Guide`_
|
||||
that goes into great technical depth about the BPF Architecture.
|
||||
|
||||
libbpf
|
||||
======
|
||||
|
||||
Libbpf is a userspace library for loading and interacting with bpf programs.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
libbpf/libbpf
|
||||
libbpf/libbpf_api
|
||||
libbpf/libbpf_build
|
||||
libbpf/libbpf_naming_convention
|
||||
|
||||
BPF Type Format (BTF)
|
||||
=====================
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
||||
|
||||
libbpf
|
||||
======
|
||||
|
||||
This is documentation for libbpf, a userspace library for loading and
|
||||
interacting with bpf programs.
|
||||
|
||||
All general BPF questions, including kernel functionality, libbpf APIs and
|
||||
their application, should be sent to bpf@vger.kernel.org mailing list.
|
||||
You can `subscribe <http://vger.kernel.org/vger-lists.html#bpf>`_ to the
|
||||
mailing list search its `archive <https://lore.kernel.org/bpf/>`_.
|
||||
Please search the archive before asking new questions. It very well might
|
||||
be that this was already addressed or answered before.
|
||||
@@ -0,0 +1,27 @@
|
||||
.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
||||
|
||||
API
|
||||
===
|
||||
|
||||
This documentation is autogenerated from header files in libbpf, tools/lib/bpf
|
||||
|
||||
.. kernel-doc:: tools/lib/bpf/libbpf.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: tools/lib/bpf/bpf.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: tools/lib/bpf/btf.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: tools/lib/bpf/xsk.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: tools/lib/bpf/bpf_tracing.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: tools/lib/bpf/bpf_core_read.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: tools/lib/bpf/bpf_endian.h
|
||||
:internal:
|
||||
@@ -0,0 +1,37 @@
|
||||
.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
||||
|
||||
Building libbpf
|
||||
===============
|
||||
|
||||
libelf and zlib are internal dependencies of libbpf and thus are required to link
|
||||
against and must be installed on the system for applications to work.
|
||||
pkg-config is used by default to find libelf, and the program called
|
||||
can be overridden with PKG_CONFIG.
|
||||
|
||||
If using pkg-config at build time is not desired, it can be disabled by
|
||||
setting NO_PKG_CONFIG=1 when calling make.
|
||||
|
||||
To build both static libbpf.a and shared libbpf.so:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ cd src
|
||||
$ make
|
||||
|
||||
To build only static libbpf.a library in directory build/ and install them
|
||||
together with libbpf headers in a staging directory root/:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ cd src
|
||||
$ mkdir build root
|
||||
$ BUILD_STATIC_ONLY=y OBJDIR=build DESTDIR=root make install
|
||||
|
||||
To build both static libbpf.a and shared libbpf.so against a custom libelf
|
||||
dependency installed in /build/root/ and install them together with libbpf
|
||||
headers in a build directory /build/root/:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ cd src
|
||||
$ PKG_CONFIG_PATH=/build/root/lib64/pkgconfig DESTDIR=/build/root make
|
||||
@@ -1,7 +1,7 @@
|
||||
.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
||||
|
||||
libbpf API naming convention
|
||||
============================
|
||||
API naming convention
|
||||
=====================
|
||||
|
||||
libbpf API provides access to a few logically separated groups of
|
||||
functions and types. Every group has its own naming convention
|
||||
@@ -10,14 +10,14 @@ new function or type is added to keep libbpf API clean and consistent.
|
||||
|
||||
All types and functions provided by libbpf API should have one of the
|
||||
following prefixes: ``bpf_``, ``btf_``, ``libbpf_``, ``xsk_``,
|
||||
``perf_buffer_``.
|
||||
``btf_dump_``, ``ring_buffer_``, ``perf_buffer_``.
|
||||
|
||||
System call wrappers
|
||||
--------------------
|
||||
|
||||
System call wrappers are simple wrappers for commands supported by
|
||||
sys_bpf system call. These wrappers should go to ``bpf.h`` header file
|
||||
and map one-on-one to corresponding commands.
|
||||
and map one to one to corresponding commands.
|
||||
|
||||
For example ``bpf_map_lookup_elem`` wraps ``BPF_MAP_LOOKUP_ELEM``
|
||||
command of sys_bpf, ``bpf_prog_attach`` wraps ``BPF_PROG_ATTACH``, etc.
|
||||
@@ -49,10 +49,6 @@ object, ``bpf_object``, double underscore and ``open`` that defines the
|
||||
purpose of the function to open ELF file and create ``bpf_object`` from
|
||||
it.
|
||||
|
||||
Another example: ``bpf_program__load`` is named for corresponding
|
||||
object, ``bpf_program``, that is separated from other part of the name
|
||||
by double underscore.
|
||||
|
||||
All objects and corresponding functions other than BTF related should go
|
||||
to ``libbpf.h``. BTF types and functions should go to ``btf.h``.
|
||||
|
||||
@@ -72,11 +68,7 @@ of both low-level ring access functions and high-level configuration
|
||||
functions. These can be mixed and matched. Note that these functions
|
||||
are not reentrant for performance reasons.
|
||||
|
||||
Please take a look at Documentation/networking/af_xdp.rst in the Linux
|
||||
kernel source tree on how to use XDP sockets and for some common
|
||||
mistakes in case you do not get any traffic up to user space.
|
||||
|
||||
libbpf ABI
|
||||
ABI
|
||||
==========
|
||||
|
||||
libbpf can be both linked statically or used as DSO. To avoid possible
|
||||
@@ -116,7 +108,8 @@ This bump in ABI version is at most once per kernel development cycle.
|
||||
|
||||
For example, if current state of ``libbpf.map`` is:
|
||||
|
||||
.. code-block::
|
||||
.. code-block:: c
|
||||
|
||||
LIBBPF_0.0.1 {
|
||||
global:
|
||||
bpf_func_a;
|
||||
@@ -128,7 +121,8 @@ For example, if current state of ``libbpf.map`` is:
|
||||
, and a new symbol ``bpf_func_c`` is being introduced, then
|
||||
``libbpf.map`` should be changed like this:
|
||||
|
||||
.. code-block::
|
||||
.. code-block:: c
|
||||
|
||||
LIBBPF_0.0.1 {
|
||||
global:
|
||||
bpf_func_a;
|
||||
@@ -148,7 +142,7 @@ Format of version script and ways to handle ABI changes, including
|
||||
incompatible ones, described in details in [1].
|
||||
|
||||
Stand-alone build
|
||||
=================
|
||||
-------------------
|
||||
|
||||
Under https://github.com/libbpf/libbpf there is a (semi-)automated
|
||||
mirror of the mainline's version of libbpf for a stand-alone build.
|
||||
@@ -157,12 +151,12 @@ However, all changes to libbpf's code base must be upstreamed through
|
||||
the mainline kernel tree.
|
||||
|
||||
License
|
||||
=======
|
||||
-------------------
|
||||
|
||||
libbpf is dual-licensed under LGPL 2.1 and BSD 2-Clause.
|
||||
|
||||
Links
|
||||
=====
|
||||
-------------------
|
||||
|
||||
[1] https://www.akkadia.org/drepper/dsohowto.pdf
|
||||
(Chapter 3. Maintaining APIs and ABIs).
|
||||
@@ -290,19 +290,19 @@ round-robin example of distributing packets is shown below:
|
||||
#define MAX_SOCKS 16
|
||||
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_XSKMAP);
|
||||
__uint(max_entries, MAX_SOCKS);
|
||||
__uint(key_size, sizeof(int));
|
||||
__uint(value_size, sizeof(int));
|
||||
__uint(type, BPF_MAP_TYPE_XSKMAP);
|
||||
__uint(max_entries, MAX_SOCKS);
|
||||
__uint(key_size, sizeof(int));
|
||||
__uint(value_size, sizeof(int));
|
||||
} xsks_map SEC(".maps");
|
||||
|
||||
static unsigned int rr;
|
||||
|
||||
SEC("xdp_sock") int xdp_sock_prog(struct xdp_md *ctx)
|
||||
{
|
||||
rr = (rr + 1) & (MAX_SOCKS - 1);
|
||||
rr = (rr + 1) & (MAX_SOCKS - 1);
|
||||
|
||||
return bpf_redirect_map(&xsks_map, rr, XDP_DROP);
|
||||
return bpf_redirect_map(&xsks_map, rr, XDP_DROP);
|
||||
}
|
||||
|
||||
Note, that since there is only a single set of FILL and COMPLETION
|
||||
@@ -379,7 +379,7 @@ would look like this for the TX path:
|
||||
.. code-block:: c
|
||||
|
||||
if (xsk_ring_prod__needs_wakeup(&my_tx_ring))
|
||||
sendto(xsk_socket__fd(xsk_handle), NULL, 0, MSG_DONTWAIT, NULL, 0);
|
||||
sendto(xsk_socket__fd(xsk_handle), NULL, 0, MSG_DONTWAIT, NULL, 0);
|
||||
|
||||
I.e., only use the syscall if the flag is set.
|
||||
|
||||
@@ -442,9 +442,9 @@ purposes. The supported statistics are shown below:
|
||||
.. code-block:: c
|
||||
|
||||
struct xdp_statistics {
|
||||
__u64 rx_dropped; /* Dropped for reasons other than invalid desc */
|
||||
__u64 rx_invalid_descs; /* Dropped due to invalid descriptor */
|
||||
__u64 tx_invalid_descs; /* Dropped due to invalid descriptor */
|
||||
__u64 rx_dropped; /* Dropped for reasons other than invalid desc */
|
||||
__u64 rx_invalid_descs; /* Dropped due to invalid descriptor */
|
||||
__u64 tx_invalid_descs; /* Dropped due to invalid descriptor */
|
||||
};
|
||||
|
||||
XDP_OPTIONS getsockopt
|
||||
@@ -483,15 +483,15 @@ like this:
|
||||
.. code-block:: c
|
||||
|
||||
// struct xdp_rxtx_ring {
|
||||
// __u32 *producer;
|
||||
// __u32 *consumer;
|
||||
// struct xdp_desc *desc;
|
||||
// __u32 *producer;
|
||||
// __u32 *consumer;
|
||||
// struct xdp_desc *desc;
|
||||
// };
|
||||
|
||||
// struct xdp_umem_ring {
|
||||
// __u32 *producer;
|
||||
// __u32 *consumer;
|
||||
// __u64 *desc;
|
||||
// __u32 *producer;
|
||||
// __u32 *consumer;
|
||||
// __u64 *desc;
|
||||
// };
|
||||
|
||||
// typedef struct xdp_rxtx_ring RING;
|
||||
|
||||
+13
-33
@@ -31,7 +31,7 @@ static u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len)
|
||||
}
|
||||
|
||||
#define EMIT(bytes, len) \
|
||||
do { prog = emit_code(prog, bytes, len); cnt += len; } while (0)
|
||||
do { prog = emit_code(prog, bytes, len); } while (0)
|
||||
|
||||
#define EMIT1(b1) EMIT(b1, 1)
|
||||
#define EMIT2(b1, b2) EMIT((b1) + ((b2) << 8), 2)
|
||||
@@ -239,7 +239,6 @@ struct jit_context {
|
||||
static void push_callee_regs(u8 **pprog, bool *callee_regs_used)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
|
||||
if (callee_regs_used[0])
|
||||
EMIT1(0x53); /* push rbx */
|
||||
@@ -255,7 +254,6 @@ static void push_callee_regs(u8 **pprog, bool *callee_regs_used)
|
||||
static void pop_callee_regs(u8 **pprog, bool *callee_regs_used)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
|
||||
if (callee_regs_used[3])
|
||||
EMIT2(0x41, 0x5F); /* pop r15 */
|
||||
@@ -277,13 +275,12 @@ static void emit_prologue(u8 **pprog, u32 stack_depth, bool ebpf_from_cbpf,
|
||||
bool tail_call_reachable, bool is_subprog)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = X86_PATCH_SIZE;
|
||||
|
||||
/* BPF trampoline can be made to work without these nops,
|
||||
* but let's waste 5 bytes for now and optimize later
|
||||
*/
|
||||
memcpy(prog, x86_nops[5], cnt);
|
||||
prog += cnt;
|
||||
memcpy(prog, x86_nops[5], X86_PATCH_SIZE);
|
||||
prog += X86_PATCH_SIZE;
|
||||
if (!ebpf_from_cbpf) {
|
||||
if (tail_call_reachable && !is_subprog)
|
||||
EMIT2(0x31, 0xC0); /* xor eax, eax */
|
||||
@@ -303,7 +300,6 @@ static void emit_prologue(u8 **pprog, u32 stack_depth, bool ebpf_from_cbpf,
|
||||
static int emit_patch(u8 **pprog, void *func, void *ip, u8 opcode)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
s64 offset;
|
||||
|
||||
offset = func - (ip + X86_PATCH_SIZE);
|
||||
@@ -423,7 +419,6 @@ static void emit_bpf_tail_call_indirect(u8 **pprog, bool *callee_regs_used,
|
||||
int off1 = 42;
|
||||
int off2 = 31;
|
||||
int off3 = 9;
|
||||
int cnt = 0;
|
||||
|
||||
/* count the additional bytes used for popping callee regs from stack
|
||||
* that need to be taken into account for each of the offsets that
|
||||
@@ -513,7 +508,6 @@ static void emit_bpf_tail_call_direct(struct bpf_jit_poke_descriptor *poke,
|
||||
int pop_bytes = 0;
|
||||
int off1 = 20;
|
||||
int poke_off;
|
||||
int cnt = 0;
|
||||
|
||||
/* count the additional bytes used for popping callee regs to stack
|
||||
* that need to be taken into account for jump offset that is used for
|
||||
@@ -615,7 +609,6 @@ static void emit_mov_imm32(u8 **pprog, bool sign_propagate,
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
u8 b1, b2, b3;
|
||||
int cnt = 0;
|
||||
|
||||
/*
|
||||
* Optimization: if imm32 is positive, use 'mov %eax, imm32'
|
||||
@@ -655,7 +648,6 @@ static void emit_mov_imm64(u8 **pprog, u32 dst_reg,
|
||||
const u32 imm32_hi, const u32 imm32_lo)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
|
||||
if (is_uimm32(((u64)imm32_hi << 32) | (u32)imm32_lo)) {
|
||||
/*
|
||||
@@ -678,7 +670,6 @@ static void emit_mov_imm64(u8 **pprog, u32 dst_reg,
|
||||
static void emit_mov_reg(u8 **pprog, bool is64, u32 dst_reg, u32 src_reg)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
|
||||
if (is64) {
|
||||
/* mov dst, src */
|
||||
@@ -697,7 +688,6 @@ static void emit_mov_reg(u8 **pprog, bool is64, u32 dst_reg, u32 src_reg)
|
||||
static void emit_insn_suffix(u8 **pprog, u32 ptr_reg, u32 val_reg, int off)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
|
||||
if (is_imm8(off)) {
|
||||
/* 1-byte signed displacement.
|
||||
@@ -720,7 +710,6 @@ static void emit_insn_suffix(u8 **pprog, u32 ptr_reg, u32 val_reg, int off)
|
||||
static void maybe_emit_mod(u8 **pprog, u32 dst_reg, u32 src_reg, bool is64)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
|
||||
if (is64)
|
||||
EMIT1(add_2mod(0x48, dst_reg, src_reg));
|
||||
@@ -733,7 +722,6 @@ static void maybe_emit_mod(u8 **pprog, u32 dst_reg, u32 src_reg, bool is64)
|
||||
static void emit_ldx(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, int off)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
|
||||
switch (size) {
|
||||
case BPF_B:
|
||||
@@ -764,7 +752,6 @@ static void emit_ldx(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, int off)
|
||||
static void emit_stx(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, int off)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
|
||||
switch (size) {
|
||||
case BPF_B:
|
||||
@@ -799,7 +786,6 @@ static int emit_atomic(u8 **pprog, u8 atomic_op,
|
||||
u32 dst_reg, u32 src_reg, s16 off, u8 bpf_size)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
|
||||
EMIT1(0xF0); /* lock prefix */
|
||||
|
||||
@@ -869,10 +855,10 @@ static void detect_reg_usage(struct bpf_insn *insn, int insn_cnt,
|
||||
}
|
||||
}
|
||||
|
||||
static int emit_nops(u8 **pprog, int len)
|
||||
static void emit_nops(u8 **pprog, int len)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int i, noplen, cnt = 0;
|
||||
int i, noplen;
|
||||
|
||||
while (len > 0) {
|
||||
noplen = len;
|
||||
@@ -886,8 +872,6 @@ static int emit_nops(u8 **pprog, int len)
|
||||
}
|
||||
|
||||
*pprog = prog;
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
#define INSN_SZ_DIFF (((addrs[i] - addrs[i - 1]) - (prog - temp)))
|
||||
@@ -902,7 +886,7 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
|
||||
bool tail_call_seen = false;
|
||||
bool seen_exit = false;
|
||||
u8 temp[BPF_MAX_INSN_SIZE + BPF_INSN_SAFETY];
|
||||
int i, cnt = 0, excnt = 0;
|
||||
int i, excnt = 0;
|
||||
int ilen, proglen = 0;
|
||||
u8 *prog = temp;
|
||||
int err;
|
||||
@@ -1297,7 +1281,7 @@ st: if (is_imm8(insn->off))
|
||||
emit_ldx(&prog, BPF_SIZE(insn->code), dst_reg, src_reg, insn->off);
|
||||
if (BPF_MODE(insn->code) == BPF_PROBE_MEM) {
|
||||
struct exception_table_entry *ex;
|
||||
u8 *_insn = image + proglen;
|
||||
u8 *_insn = image + proglen + (start_of_ldx - temp);
|
||||
s64 delta;
|
||||
|
||||
/* populate jmp_offset for JMP above */
|
||||
@@ -1576,7 +1560,7 @@ emit_cond_jmp: /* Convert BPF opcode to x86 */
|
||||
nops);
|
||||
return -EFAULT;
|
||||
}
|
||||
cnt += emit_nops(&prog, nops);
|
||||
emit_nops(&prog, nops);
|
||||
}
|
||||
EMIT2(jmp_cond, jmp_offset);
|
||||
} else if (is_simm32(jmp_offset)) {
|
||||
@@ -1622,7 +1606,7 @@ emit_cond_jmp: /* Convert BPF opcode to x86 */
|
||||
nops);
|
||||
return -EFAULT;
|
||||
}
|
||||
cnt += emit_nops(&prog, nops);
|
||||
emit_nops(&prog, nops);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1647,7 +1631,7 @@ emit_jmp:
|
||||
nops);
|
||||
return -EFAULT;
|
||||
}
|
||||
cnt += emit_nops(&prog, INSN_SZ_DIFF - 2);
|
||||
emit_nops(&prog, INSN_SZ_DIFF - 2);
|
||||
}
|
||||
EMIT2(0xEB, jmp_offset);
|
||||
} else if (is_simm32(jmp_offset)) {
|
||||
@@ -1754,7 +1738,6 @@ static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog,
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
u8 *jmp_insn;
|
||||
int cnt = 0;
|
||||
|
||||
/* arg1: mov rdi, progs[i] */
|
||||
emit_mov_imm64(&prog, BPF_REG_1, (long) p >> 32, (u32) (long) p);
|
||||
@@ -1822,7 +1805,6 @@ static void emit_align(u8 **pprog, u32 align)
|
||||
static int emit_cond_near_jump(u8 **pprog, void *func, void *ip, u8 jmp_cond)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
s64 offset;
|
||||
|
||||
offset = func - (ip + 2 + 4);
|
||||
@@ -1854,7 +1836,7 @@ static int invoke_bpf_mod_ret(const struct btf_func_model *m, u8 **pprog,
|
||||
u8 **branches)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int i, cnt = 0;
|
||||
int i;
|
||||
|
||||
/* The first fmod_ret program will receive a garbage return value.
|
||||
* Set this to 0 to avoid confusing the program.
|
||||
@@ -1950,7 +1932,7 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
|
||||
struct bpf_tramp_progs *tprogs,
|
||||
void *orig_call)
|
||||
{
|
||||
int ret, i, cnt = 0, nr_args = m->nr_args;
|
||||
int ret, i, nr_args = m->nr_args;
|
||||
int stack_size = nr_args * 8;
|
||||
struct bpf_tramp_progs *fentry = &tprogs[BPF_TRAMP_FENTRY];
|
||||
struct bpf_tramp_progs *fexit = &tprogs[BPF_TRAMP_FEXIT];
|
||||
@@ -2095,8 +2077,6 @@ static int emit_fallback_jump(u8 **pprog)
|
||||
*/
|
||||
err = emit_jump(&prog, __x86_indirect_thunk_rdx, prog);
|
||||
#else
|
||||
int cnt = 0;
|
||||
|
||||
EMIT2(0xFF, 0xE2); /* jmp rdx */
|
||||
#endif
|
||||
*pprog = prog;
|
||||
@@ -2106,7 +2086,7 @@ static int emit_fallback_jump(u8 **pprog)
|
||||
static int emit_bpf_dispatcher(u8 **pprog, int a, int b, s64 *progs)
|
||||
{
|
||||
u8 *jg_reloc, *prog = *pprog;
|
||||
int pivot, err, jg_bytes = 1, cnt = 0;
|
||||
int pivot, err, jg_bytes = 1;
|
||||
s64 jg_offset;
|
||||
|
||||
if (a == b) {
|
||||
|
||||
@@ -326,7 +326,8 @@ int lirc_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr)
|
||||
}
|
||||
|
||||
if (attr->query.prog_cnt != 0 && prog_ids && cnt)
|
||||
ret = bpf_prog_array_copy_to_user(progs, prog_ids, cnt);
|
||||
ret = bpf_prog_array_copy_to_user(progs, prog_ids,
|
||||
attr->query.prog_cnt);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&ir_raw_handler_lock);
|
||||
|
||||
@@ -384,7 +384,6 @@ static int ena_xdp_execute(struct ena_ring *rx_ring, struct xdp_buff *xdp)
|
||||
struct xdp_frame *xdpf;
|
||||
u64 *xdp_stat;
|
||||
|
||||
rcu_read_lock();
|
||||
xdp_prog = READ_ONCE(rx_ring->xdp_bpf_prog);
|
||||
|
||||
if (!xdp_prog)
|
||||
@@ -441,8 +440,6 @@ static int ena_xdp_execute(struct ena_ring *rx_ring, struct xdp_buff *xdp)
|
||||
|
||||
ena_increase_stat(xdp_stat, 1, &rx_ring->syncp);
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
|
||||
return verdict;
|
||||
}
|
||||
|
||||
|
||||
@@ -138,9 +138,7 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
|
||||
xdp_prepare_buff(&xdp, *data_ptr - offset, offset, *len, false);
|
||||
orig_data = xdp.data;
|
||||
|
||||
rcu_read_lock();
|
||||
act = bpf_prog_run_xdp(xdp_prog, &xdp);
|
||||
rcu_read_unlock();
|
||||
|
||||
tx_avail = bnxt_tx_avail(bp, txr);
|
||||
/* If the tx ring is not full, we must not update the rx producer yet
|
||||
|
||||
@@ -555,9 +555,7 @@ static inline bool nicvf_xdp_rx(struct nicvf *nic, struct bpf_prog *prog,
|
||||
xdp_prepare_buff(&xdp, hard_start, data - hard_start, len, false);
|
||||
orig_data = xdp.data;
|
||||
|
||||
rcu_read_lock();
|
||||
action = bpf_prog_run_xdp(prog, &xdp);
|
||||
rcu_read_unlock();
|
||||
|
||||
len = xdp.data_end - xdp.data;
|
||||
/* Check if XDP program has changed headers */
|
||||
|
||||
@@ -2558,13 +2558,9 @@ static u32 dpaa_run_xdp(struct dpaa_priv *priv, struct qm_fd *fd, void *vaddr,
|
||||
u32 xdp_act;
|
||||
int err;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
xdp_prog = READ_ONCE(priv->xdp_prog);
|
||||
if (!xdp_prog) {
|
||||
rcu_read_unlock();
|
||||
if (!xdp_prog)
|
||||
return XDP_PASS;
|
||||
}
|
||||
|
||||
xdp_init_buff(&xdp, DPAA_BP_RAW_SIZE - DPAA_TX_PRIV_DATA_SIZE,
|
||||
&dpaa_fq->xdp_rxq);
|
||||
@@ -2638,8 +2634,6 @@ static u32 dpaa_run_xdp(struct dpaa_priv *priv, struct qm_fd *fd, void *vaddr,
|
||||
break;
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
return xdp_act;
|
||||
}
|
||||
|
||||
|
||||
@@ -352,8 +352,6 @@ static u32 dpaa2_eth_run_xdp(struct dpaa2_eth_priv *priv,
|
||||
u32 xdp_act = XDP_PASS;
|
||||
int err, offset;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
xdp_prog = READ_ONCE(ch->xdp.prog);
|
||||
if (!xdp_prog)
|
||||
goto out;
|
||||
@@ -414,7 +412,6 @@ static u32 dpaa2_eth_run_xdp(struct dpaa2_eth_priv *priv,
|
||||
|
||||
ch->xdp.res |= xdp_act;
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
return xdp_act;
|
||||
}
|
||||
|
||||
|
||||
@@ -2298,7 +2298,6 @@ static int i40e_run_xdp(struct i40e_ring *rx_ring, struct xdp_buff *xdp)
|
||||
struct bpf_prog *xdp_prog;
|
||||
u32 act;
|
||||
|
||||
rcu_read_lock();
|
||||
xdp_prog = READ_ONCE(rx_ring->xdp_prog);
|
||||
|
||||
if (!xdp_prog)
|
||||
@@ -2334,7 +2333,6 @@ out_failure:
|
||||
break;
|
||||
}
|
||||
xdp_out:
|
||||
rcu_read_unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -153,7 +153,6 @@ static int i40e_run_xdp_zc(struct i40e_ring *rx_ring, struct xdp_buff *xdp)
|
||||
struct bpf_prog *xdp_prog;
|
||||
u32 act;
|
||||
|
||||
rcu_read_lock();
|
||||
/* NB! xdp_prog will always be !NULL, due to the fact that
|
||||
* this path is enabled by setting an XDP program.
|
||||
*/
|
||||
@@ -164,7 +163,6 @@ static int i40e_run_xdp_zc(struct i40e_ring *rx_ring, struct xdp_buff *xdp)
|
||||
err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog);
|
||||
if (err)
|
||||
goto out_failure;
|
||||
rcu_read_unlock();
|
||||
return I40E_XDP_REDIR;
|
||||
}
|
||||
|
||||
@@ -188,7 +186,6 @@ out_failure:
|
||||
result = I40E_XDP_CONSUMED;
|
||||
break;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1140,15 +1140,11 @@ int ice_clean_rx_irq(struct ice_ring *rx_ring, int budget)
|
||||
xdp.frame_sz = ice_rx_frame_truesize(rx_ring, size);
|
||||
#endif
|
||||
|
||||
rcu_read_lock();
|
||||
xdp_prog = READ_ONCE(rx_ring->xdp_prog);
|
||||
if (!xdp_prog) {
|
||||
rcu_read_unlock();
|
||||
if (!xdp_prog)
|
||||
goto construct_skb;
|
||||
}
|
||||
|
||||
xdp_res = ice_run_xdp(rx_ring, &xdp, xdp_prog);
|
||||
rcu_read_unlock();
|
||||
if (!xdp_res)
|
||||
goto construct_skb;
|
||||
if (xdp_res & (ICE_XDP_TX | ICE_XDP_REDIR)) {
|
||||
|
||||
@@ -466,7 +466,6 @@ ice_run_xdp_zc(struct ice_ring *rx_ring, struct xdp_buff *xdp)
|
||||
struct ice_ring *xdp_ring;
|
||||
u32 act;
|
||||
|
||||
rcu_read_lock();
|
||||
/* ZC patch is enabled only when XDP program is set,
|
||||
* so here it can not be NULL
|
||||
*/
|
||||
@@ -478,7 +477,6 @@ ice_run_xdp_zc(struct ice_ring *rx_ring, struct xdp_buff *xdp)
|
||||
err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog);
|
||||
if (err)
|
||||
goto out_failure;
|
||||
rcu_read_unlock();
|
||||
return ICE_XDP_REDIR;
|
||||
}
|
||||
|
||||
@@ -503,7 +501,6 @@ out_failure:
|
||||
break;
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -8381,7 +8381,6 @@ static struct sk_buff *igb_run_xdp(struct igb_adapter *adapter,
|
||||
struct bpf_prog *xdp_prog;
|
||||
u32 act;
|
||||
|
||||
rcu_read_lock();
|
||||
xdp_prog = READ_ONCE(rx_ring->xdp_prog);
|
||||
|
||||
if (!xdp_prog)
|
||||
@@ -8416,7 +8415,6 @@ out_failure:
|
||||
break;
|
||||
}
|
||||
xdp_out:
|
||||
rcu_read_unlock();
|
||||
return ERR_PTR(-result);
|
||||
}
|
||||
|
||||
|
||||
@@ -2240,18 +2240,15 @@ static struct sk_buff *igc_xdp_run_prog(struct igc_adapter *adapter,
|
||||
struct bpf_prog *prog;
|
||||
int res;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
prog = READ_ONCE(adapter->xdp_prog);
|
||||
if (!prog) {
|
||||
res = IGC_XDP_PASS;
|
||||
goto unlock;
|
||||
goto out;
|
||||
}
|
||||
|
||||
res = __igc_xdp_run_prog(adapter, prog, xdp);
|
||||
|
||||
unlock:
|
||||
rcu_read_unlock();
|
||||
out:
|
||||
return ERR_PTR(-res);
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user