Skip to content

Commit 1ba9828

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next
Daniel Borkmann says: ==================== pull-request: bpf-next 2018-08-07 The following pull-request contains BPF updates for your *net-next* tree. The main changes are: 1) Add cgroup local storage for BPF programs, which provides a fast accessible memory for storing various per-cgroup data like number of transmitted packets, etc, from Roman. 2) Support bpf_get_socket_cookie() BPF helper in several more program types that have a full socket available, from Andrey. 3) Significantly improve the performance of perf events which are reported from BPF offload. Also convert a couple of BPF AF_XDP samples overto use libbpf, both from Jakub. 4) seg6local LWT provides the End.DT6 action, which allows to decapsulate an outer IPv6 header containing a Segment Routing Header. Adds this action now to the seg6local BPF interface, from Mathieu. 5) Do not mark dst register as unbounded in MOV64 instruction when both src and dst register are the same, from Arthur. 6) Define u_smp_rmb() and u_smp_wmb() to their respective barrier instructions on arm64 for the AF_XDP sample code, from Brian. 7) Convert the tcp_client.py and tcp_server.py BPF selftest scripts over from Python 2 to Python 3, from Jeremy. 8) Enable BTF build flags to the BPF sample code Makefile, from Taeung. 9) Remove an unnecessary rcu_read_lock() in run_lwt_bpf(), from Taehee. 10) Several improvements to the README.rst from the BPF documentation to make it more consistent with RST format, from Tobin. 11) Replace all occurrences of strerror() by calls to strerror_r() in libbpf and fix a FORTIFY_SOURCE build error along with it, from Thomas. 12) Fix a bug in bpftool's get_btf() function to correctly propagate an error via PTR_ERR(), from Yue. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents c5d99d2 + 85fc4b1 commit 1ba9828

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1894
-301
lines changed

Documentation/bpf/README.rst renamed to Documentation/bpf/index.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
=================
2-
BPF documentation
2+
BPF Documentation
33
=================
44

55
This directory contains documentation for the BPF (Berkeley Packet
@@ -22,14 +22,14 @@ Frequently asked questions (FAQ)
2222

2323
Two sets of Questions and Answers (Q&A) are maintained.
2424

25-
* QA for common questions about BPF see: bpf_design_QA_
25+
.. toctree::
26+
:maxdepth: 1
2627

27-
* QA for developers interacting with BPF subsystem: bpf_devel_QA_
28+
bpf_design_QA
29+
bpf_devel_QA
2830

2931

3032
.. Links:
31-
.. _bpf_design_QA: bpf_design_QA.rst
32-
.. _bpf_devel_QA: bpf_devel_QA.rst
3333
.. _Documentation/networking/filter.txt: ../networking/filter.txt
3434
.. _man-pages: https://www.kernel.org/doc/man-pages/
3535
.. _bpf(2): http://man7.org/linux/man-pages/man2/bpf.2.html

Documentation/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ needed).
9090
crypto/index
9191
filesystems/index
9292
vm/index
93+
bpf/index
9394

9495
Architecture-specific documentation
9596
-----------------------------------

drivers/media/rc/bpf-lirc.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,14 +196,16 @@ void lirc_bpf_run(struct rc_dev *rcdev, u32 sample)
196196
*/
197197
void lirc_bpf_free(struct rc_dev *rcdev)
198198
{
199-
struct bpf_prog **progs;
199+
struct bpf_prog_array_item *item;
200200

201201
if (!rcdev->raw->progs)
202202
return;
203203

204-
progs = rcu_dereference(rcdev->raw->progs)->progs;
205-
while (*progs)
206-
bpf_prog_put(*progs++);
204+
item = rcu_dereference(rcdev->raw->progs)->items;
205+
while (item->prog) {
206+
bpf_prog_put(item->prog);
207+
item++;
208+
}
207209

208210
bpf_prog_array_free(rcdev->raw->progs);
209211
}

drivers/net/ethernet/netronome/nfp/bpf/cmsg.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@
4343
#include "fw.h"
4444
#include "main.h"
4545

46-
#define cmsg_warn(bpf, msg...) nn_dp_warn(&(bpf)->app->ctrl->dp, msg)
47-
4846
#define NFP_BPF_TAG_ALLOC_SPAN (U16_MAX / 4)
4947

5048
static bool nfp_bpf_all_tags_busy(struct nfp_app_bpf *bpf)
@@ -441,7 +439,10 @@ void nfp_bpf_ctrl_msg_rx(struct nfp_app *app, struct sk_buff *skb)
441439
}
442440

443441
if (nfp_bpf_cmsg_get_type(skb) == CMSG_TYPE_BPF_EVENT) {
444-
nfp_bpf_event_output(bpf, skb);
442+
if (!nfp_bpf_event_output(bpf, skb->data, skb->len))
443+
dev_consume_skb_any(skb);
444+
else
445+
dev_kfree_skb_any(skb);
445446
return;
446447
}
447448

@@ -465,3 +466,21 @@ void nfp_bpf_ctrl_msg_rx(struct nfp_app *app, struct sk_buff *skb)
465466
err_free:
466467
dev_kfree_skb_any(skb);
467468
}
469+
470+
void
471+
nfp_bpf_ctrl_msg_rx_raw(struct nfp_app *app, const void *data, unsigned int len)
472+
{
473+
struct nfp_app_bpf *bpf = app->priv;
474+
const struct cmsg_hdr *hdr = data;
475+
476+
if (unlikely(len < sizeof(struct cmsg_reply_map_simple))) {
477+
cmsg_warn(bpf, "cmsg drop - too short %d!\n", len);
478+
return;
479+
}
480+
481+
if (hdr->type == CMSG_TYPE_BPF_EVENT)
482+
nfp_bpf_event_output(bpf, data, len);
483+
else
484+
cmsg_warn(bpf, "cmsg drop - msg type %d with raw buffer!\n",
485+
hdr->type);
486+
}

drivers/net/ethernet/netronome/nfp/bpf/fw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ enum bpf_cap_tlv_type {
5151
NFP_BPF_CAP_TYPE_MAPS = 3,
5252
NFP_BPF_CAP_TYPE_RANDOM = 4,
5353
NFP_BPF_CAP_TYPE_QUEUE_SELECT = 5,
54+
NFP_BPF_CAP_TYPE_ADJUST_TAIL = 6,
5455
};
5556

5657
struct nfp_bpf_cap_tlv_func {

drivers/net/ethernet/netronome/nfp/bpf/jit.c

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1642,6 +1642,51 @@ static int adjust_head(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
16421642
return 0;
16431643
}
16441644

1645+
static int adjust_tail(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
1646+
{
1647+
u32 ret_einval, end;
1648+
swreg plen, delta;
1649+
1650+
BUILD_BUG_ON(plen_reg(nfp_prog) != reg_b(STATIC_REG_PKT_LEN));
1651+
1652+
plen = imm_a(nfp_prog);
1653+
delta = reg_a(2 * 2);
1654+
1655+
ret_einval = nfp_prog_current_offset(nfp_prog) + 9;
1656+
end = nfp_prog_current_offset(nfp_prog) + 11;
1657+
1658+
/* Calculate resulting length */
1659+
emit_alu(nfp_prog, plen, plen_reg(nfp_prog), ALU_OP_ADD, delta);
1660+
/* delta == 0 is not allowed by the kernel, add must overflow to make
1661+
* length smaller.
1662+
*/
1663+
emit_br(nfp_prog, BR_BCC, ret_einval, 0);
1664+
1665+
/* if (new_len < 14) then -EINVAL */
1666+
emit_alu(nfp_prog, reg_none(), plen, ALU_OP_SUB, reg_imm(ETH_HLEN));
1667+
emit_br(nfp_prog, BR_BMI, ret_einval, 0);
1668+
1669+
emit_alu(nfp_prog, plen_reg(nfp_prog),
1670+
plen_reg(nfp_prog), ALU_OP_ADD, delta);
1671+
emit_alu(nfp_prog, pv_len(nfp_prog),
1672+
pv_len(nfp_prog), ALU_OP_ADD, delta);
1673+
1674+
emit_br(nfp_prog, BR_UNC, end, 2);
1675+
wrp_immed(nfp_prog, reg_both(0), 0);
1676+
wrp_immed(nfp_prog, reg_both(1), 0);
1677+
1678+
if (!nfp_prog_confirm_current_offset(nfp_prog, ret_einval))
1679+
return -EINVAL;
1680+
1681+
wrp_immed(nfp_prog, reg_both(0), -22);
1682+
wrp_immed(nfp_prog, reg_both(1), ~0);
1683+
1684+
if (!nfp_prog_confirm_current_offset(nfp_prog, end))
1685+
return -EINVAL;
1686+
1687+
return 0;
1688+
}
1689+
16451690
static int
16461691
map_call_stack_common(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
16471692
{
@@ -3041,6 +3086,8 @@ static int call(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
30413086
switch (meta->insn.imm) {
30423087
case BPF_FUNC_xdp_adjust_head:
30433088
return adjust_head(nfp_prog, meta);
3089+
case BPF_FUNC_xdp_adjust_tail:
3090+
return adjust_tail(nfp_prog, meta);
30443091
case BPF_FUNC_map_lookup_elem:
30453092
case BPF_FUNC_map_update_elem:
30463093
case BPF_FUNC_map_delete_elem:
@@ -3883,6 +3930,7 @@ static int nfp_bpf_replace_map_ptrs(struct nfp_prog *nfp_prog)
38833930
struct nfp_insn_meta *meta1, *meta2;
38843931
struct nfp_bpf_map *nfp_map;
38853932
struct bpf_map *map;
3933+
u32 id;
38863934

38873935
nfp_for_each_insn_walk2(nfp_prog, meta1, meta2) {
38883936
if (meta1->skip || meta2->skip)
@@ -3894,11 +3942,14 @@ static int nfp_bpf_replace_map_ptrs(struct nfp_prog *nfp_prog)
38943942

38953943
map = (void *)(unsigned long)((u32)meta1->insn.imm |
38963944
(u64)meta2->insn.imm << 32);
3897-
if (bpf_map_offload_neutral(map))
3898-
continue;
3899-
nfp_map = map_to_offmap(map)->dev_priv;
3945+
if (bpf_map_offload_neutral(map)) {
3946+
id = map->id;
3947+
} else {
3948+
nfp_map = map_to_offmap(map)->dev_priv;
3949+
id = nfp_map->tid;
3950+
}
39003951

3901-
meta1->insn.imm = nfp_map->tid;
3952+
meta1->insn.imm = id;
39023953
meta2->insn.imm = 0;
39033954
}
39043955

drivers/net/ethernet/netronome/nfp/bpf/main.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@
4545

4646
const struct rhashtable_params nfp_bpf_maps_neutral_params = {
4747
.nelem_hint = 4,
48-
.key_len = FIELD_SIZEOF(struct nfp_bpf_neutral_map, ptr),
49-
.key_offset = offsetof(struct nfp_bpf_neutral_map, ptr),
48+
.key_len = FIELD_SIZEOF(struct bpf_map, id),
49+
.key_offset = offsetof(struct nfp_bpf_neutral_map, map_id),
5050
.head_offset = offsetof(struct nfp_bpf_neutral_map, l),
5151
.automatic_shrinking = true,
5252
};
@@ -334,6 +334,14 @@ nfp_bpf_parse_cap_qsel(struct nfp_app_bpf *bpf, void __iomem *value, u32 length)
334334
return 0;
335335
}
336336

337+
static int
338+
nfp_bpf_parse_cap_adjust_tail(struct nfp_app_bpf *bpf, void __iomem *value,
339+
u32 length)
340+
{
341+
bpf->adjust_tail = true;
342+
return 0;
343+
}
344+
337345
static int nfp_bpf_parse_capabilities(struct nfp_app *app)
338346
{
339347
struct nfp_cpp *cpp = app->pf->cpp;
@@ -380,6 +388,11 @@ static int nfp_bpf_parse_capabilities(struct nfp_app *app)
380388
if (nfp_bpf_parse_cap_qsel(app->priv, value, length))
381389
goto err_release_free;
382390
break;
391+
case NFP_BPF_CAP_TYPE_ADJUST_TAIL:
392+
if (nfp_bpf_parse_cap_adjust_tail(app->priv, value,
393+
length))
394+
goto err_release_free;
395+
break;
383396
default:
384397
nfp_dbg(cpp, "unknown BPF capability: %d\n", type);
385398
break;
@@ -490,6 +503,7 @@ const struct nfp_app_type app_bpf = {
490503
.vnic_free = nfp_bpf_vnic_free,
491504

492505
.ctrl_msg_rx = nfp_bpf_ctrl_msg_rx,
506+
.ctrl_msg_rx_raw = nfp_bpf_ctrl_msg_rx_raw,
493507

494508
.setup_tc = nfp_bpf_setup_tc,
495509
.bpf = nfp_ndo_bpf,

drivers/net/ethernet/netronome/nfp/bpf/main.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747
#include "../nfp_asm.h"
4848
#include "fw.h"
4949

50+
#define cmsg_warn(bpf, msg...) nn_dp_warn(&(bpf)->app->ctrl->dp, msg)
51+
5052
/* For relocation logic use up-most byte of branch instruction as scratch
5153
* area. Remember to clear this before sending instructions to HW!
5254
*/
@@ -148,6 +150,7 @@ enum pkt_vec {
148150
*
149151
* @pseudo_random: FW initialized the pseudo-random machinery (CSRs)
150152
* @queue_select: BPF can set the RX queue ID in packet vector
153+
* @adjust_tail: BPF can simply trunc packet size for adjust tail
151154
*/
152155
struct nfp_app_bpf {
153156
struct nfp_app *app;
@@ -193,6 +196,7 @@ struct nfp_app_bpf {
193196

194197
bool pseudo_random;
195198
bool queue_select;
199+
bool adjust_tail;
196200
};
197201

198202
enum nfp_bpf_map_use {
@@ -221,6 +225,7 @@ struct nfp_bpf_map {
221225
struct nfp_bpf_neutral_map {
222226
struct rhash_head l;
223227
struct bpf_map *ptr;
228+
u32 map_id;
224229
u32 count;
225230
};
226231

@@ -501,7 +506,11 @@ int nfp_bpf_ctrl_lookup_entry(struct bpf_offloaded_map *offmap,
501506
int nfp_bpf_ctrl_getnext_entry(struct bpf_offloaded_map *offmap,
502507
void *key, void *next_key);
503508

504-
int nfp_bpf_event_output(struct nfp_app_bpf *bpf, struct sk_buff *skb);
509+
int nfp_bpf_event_output(struct nfp_app_bpf *bpf, const void *data,
510+
unsigned int len);
505511

506512
void nfp_bpf_ctrl_msg_rx(struct nfp_app *app, struct sk_buff *skb);
513+
void
514+
nfp_bpf_ctrl_msg_rx_raw(struct nfp_app *app, const void *data,
515+
unsigned int len);
507516
#endif

drivers/net/ethernet/netronome/nfp/bpf/offload.c

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ nfp_map_ptr_record(struct nfp_app_bpf *bpf, struct nfp_prog *nfp_prog,
6767
ASSERT_RTNL();
6868

6969
/* Reuse path - other offloaded program is already tracking this map. */
70-
record = rhashtable_lookup_fast(&bpf->maps_neutral, &map,
70+
record = rhashtable_lookup_fast(&bpf->maps_neutral, &map->id,
7171
nfp_bpf_maps_neutral_params);
7272
if (record) {
7373
nfp_prog->map_records[nfp_prog->map_records_cnt++] = record;
@@ -89,6 +89,7 @@ nfp_map_ptr_record(struct nfp_app_bpf *bpf, struct nfp_prog *nfp_prog,
8989
}
9090

9191
record->ptr = map;
92+
record->map_id = map->id;
9293
record->count = 1;
9394

9495
err = rhashtable_insert_fast(&bpf->maps_neutral, &record->l,
@@ -379,11 +380,23 @@ nfp_bpf_map_alloc(struct nfp_app_bpf *bpf, struct bpf_offloaded_map *offmap)
379380
bpf->maps.max_elems - bpf->map_elems_in_use);
380381
return -ENOMEM;
381382
}
382-
if (offmap->map.key_size > bpf->maps.max_key_sz ||
383-
offmap->map.value_size > bpf->maps.max_val_sz ||
384-
round_up(offmap->map.key_size, 8) +
383+
384+
if (round_up(offmap->map.key_size, 8) +
385385
round_up(offmap->map.value_size, 8) > bpf->maps.max_elem_sz) {
386-
pr_info("elements don't fit in device constraints\n");
386+
pr_info("map elements too large: %u, FW max element size (key+value): %u\n",
387+
round_up(offmap->map.key_size, 8) +
388+
round_up(offmap->map.value_size, 8),
389+
bpf->maps.max_elem_sz);
390+
return -ENOMEM;
391+
}
392+
if (offmap->map.key_size > bpf->maps.max_key_sz) {
393+
pr_info("map key size %u, FW max is %u\n",
394+
offmap->map.key_size, bpf->maps.max_key_sz);
395+
return -ENOMEM;
396+
}
397+
if (offmap->map.value_size > bpf->maps.max_val_sz) {
398+
pr_info("map value size %u, FW max is %u\n",
399+
offmap->map.value_size, bpf->maps.max_val_sz);
387400
return -ENOMEM;
388401
}
389402

@@ -453,43 +466,43 @@ nfp_bpf_perf_event_copy(void *dst, const void *src,
453466
return 0;
454467
}
455468

456-
int nfp_bpf_event_output(struct nfp_app_bpf *bpf, struct sk_buff *skb)
469+
int nfp_bpf_event_output(struct nfp_app_bpf *bpf, const void *data,
470+
unsigned int len)
457471
{
458-
struct cmsg_bpf_event *cbe = (void *)skb->data;
459-
u32 pkt_size, data_size;
460-
struct bpf_map *map;
472+
struct cmsg_bpf_event *cbe = (void *)data;
473+
struct nfp_bpf_neutral_map *record;
474+
u32 pkt_size, data_size, map_id;
475+
u64 map_id_full;
461476

462-
if (skb->len < sizeof(struct cmsg_bpf_event))
463-
goto err_drop;
477+
if (len < sizeof(struct cmsg_bpf_event))
478+
return -EINVAL;
464479

465480
pkt_size = be32_to_cpu(cbe->pkt_size);
466481
data_size = be32_to_cpu(cbe->data_size);
467-
map = (void *)(unsigned long)be64_to_cpu(cbe->map_ptr);
482+
map_id_full = be64_to_cpu(cbe->map_ptr);
483+
map_id = map_id_full;
468484

469-
if (skb->len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size)
470-
goto err_drop;
485+
if (len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size)
486+
return -EINVAL;
471487
if (cbe->hdr.ver != CMSG_MAP_ABI_VERSION)
472-
goto err_drop;
488+
return -EINVAL;
473489

474490
rcu_read_lock();
475-
if (!rhashtable_lookup_fast(&bpf->maps_neutral, &map,
476-
nfp_bpf_maps_neutral_params)) {
491+
record = rhashtable_lookup_fast(&bpf->maps_neutral, &map_id,
492+
nfp_bpf_maps_neutral_params);
493+
if (!record || map_id_full > U32_MAX) {
477494
rcu_read_unlock();
478-
pr_warn("perf event: dest map pointer %px not recognized, dropping event\n",
479-
map);
480-
goto err_drop;
495+
cmsg_warn(bpf, "perf event: map id %lld (0x%llx) not recognized, dropping event\n",
496+
map_id_full, map_id_full);
497+
return -EINVAL;
481498
}
482499

483-
bpf_event_output(map, be32_to_cpu(cbe->cpu_id),
500+
bpf_event_output(record->ptr, be32_to_cpu(cbe->cpu_id),
484501
&cbe->data[round_up(pkt_size, 4)], data_size,
485502
cbe->data, pkt_size, nfp_bpf_perf_event_copy);
486503
rcu_read_unlock();
487504

488-
dev_consume_skb_any(skb);
489505
return 0;
490-
err_drop:
491-
dev_kfree_skb_any(skb);
492-
return -EINVAL;
493506
}
494507

495508
static int

0 commit comments

Comments
 (0)