Skip to content

Commit 0c9864c

Browse files
Jakub Kicinskiborkmann
authored andcommitted
nfp: bpf: allow control message sizing for map ops
In current ABI the size of the messages carrying map elements was statically defined to at most 16 words of key and 16 words of value (NFP word is 4 bytes). We should not make this assumption and use the max key and value sizes from the BPF capability instead. To make sure old kernels don't get surprised with larger (or smaller) messages bump the FW ABI version to 3 when key/value size is different than 16 words. Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
1 parent 9bbdd41 commit 0c9864c

File tree

5 files changed

+83
-17
lines changed

5 files changed

+83
-17
lines changed

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

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,15 +89,32 @@ nfp_bpf_cmsg_alloc(struct nfp_app_bpf *bpf, unsigned int size)
8989
return skb;
9090
}
9191

92+
static unsigned int
93+
nfp_bpf_cmsg_map_req_size(struct nfp_app_bpf *bpf, unsigned int n)
94+
{
95+
unsigned int size;
96+
97+
size = sizeof(struct cmsg_req_map_op);
98+
size += (bpf->cmsg_key_sz + bpf->cmsg_val_sz) * n;
99+
100+
return size;
101+
}
102+
92103
static struct sk_buff *
93104
nfp_bpf_cmsg_map_req_alloc(struct nfp_app_bpf *bpf, unsigned int n)
105+
{
106+
return nfp_bpf_cmsg_alloc(bpf, nfp_bpf_cmsg_map_req_size(bpf, n));
107+
}
108+
109+
static unsigned int
110+
nfp_bpf_cmsg_map_reply_size(struct nfp_app_bpf *bpf, unsigned int n)
94111
{
95112
unsigned int size;
96113

97-
size = sizeof(struct cmsg_req_map_op);
98-
size += sizeof(struct cmsg_key_value_pair) * n;
114+
size = sizeof(struct cmsg_reply_map_op);
115+
size += (bpf->cmsg_key_sz + bpf->cmsg_val_sz) * n;
99116

100-
return nfp_bpf_cmsg_alloc(bpf, size);
117+
return size;
101118
}
102119

103120
static u8 nfp_bpf_cmsg_get_type(struct sk_buff *skb)
@@ -338,6 +355,34 @@ void nfp_bpf_ctrl_free_map(struct nfp_app_bpf *bpf, struct nfp_bpf_map *nfp_map)
338355
dev_consume_skb_any(skb);
339356
}
340357

358+
static void *
359+
nfp_bpf_ctrl_req_key(struct nfp_app_bpf *bpf, struct cmsg_req_map_op *req,
360+
unsigned int n)
361+
{
362+
return &req->data[bpf->cmsg_key_sz * n + bpf->cmsg_val_sz * n];
363+
}
364+
365+
static void *
366+
nfp_bpf_ctrl_req_val(struct nfp_app_bpf *bpf, struct cmsg_req_map_op *req,
367+
unsigned int n)
368+
{
369+
return &req->data[bpf->cmsg_key_sz * (n + 1) + bpf->cmsg_val_sz * n];
370+
}
371+
372+
static void *
373+
nfp_bpf_ctrl_reply_key(struct nfp_app_bpf *bpf, struct cmsg_reply_map_op *reply,
374+
unsigned int n)
375+
{
376+
return &reply->data[bpf->cmsg_key_sz * n + bpf->cmsg_val_sz * n];
377+
}
378+
379+
static void *
380+
nfp_bpf_ctrl_reply_val(struct nfp_app_bpf *bpf, struct cmsg_reply_map_op *reply,
381+
unsigned int n)
382+
{
383+
return &reply->data[bpf->cmsg_key_sz * (n + 1) + bpf->cmsg_val_sz * n];
384+
}
385+
341386
static int
342387
nfp_bpf_ctrl_entry_op(struct bpf_offloaded_map *offmap,
343388
enum nfp_bpf_cmsg_type op,
@@ -366,12 +411,13 @@ nfp_bpf_ctrl_entry_op(struct bpf_offloaded_map *offmap,
366411

367412
/* Copy inputs */
368413
if (key)
369-
memcpy(&req->elem[0].key, key, map->key_size);
414+
memcpy(nfp_bpf_ctrl_req_key(bpf, req, 0), key, map->key_size);
370415
if (value)
371-
memcpy(&req->elem[0].value, value, map->value_size);
416+
memcpy(nfp_bpf_ctrl_req_val(bpf, req, 0), value,
417+
map->value_size);
372418

373419
skb = nfp_bpf_cmsg_communicate(bpf, skb, op,
374-
sizeof(*reply) + sizeof(*reply->elem));
420+
nfp_bpf_cmsg_map_reply_size(bpf, 1));
375421
if (IS_ERR(skb))
376422
return PTR_ERR(skb);
377423

@@ -382,9 +428,11 @@ nfp_bpf_ctrl_entry_op(struct bpf_offloaded_map *offmap,
382428

383429
/* Copy outputs */
384430
if (out_key)
385-
memcpy(out_key, &reply->elem[0].key, map->key_size);
431+
memcpy(out_key, nfp_bpf_ctrl_reply_key(bpf, reply, 0),
432+
map->key_size);
386433
if (out_value)
387-
memcpy(out_value, &reply->elem[0].value, map->value_size);
434+
memcpy(out_value, nfp_bpf_ctrl_reply_val(bpf, reply, 0),
435+
map->value_size);
388436

389437
dev_consume_skb_any(skb);
390438

@@ -428,6 +476,13 @@ int nfp_bpf_ctrl_getnext_entry(struct bpf_offloaded_map *offmap,
428476
key, NULL, 0, next_key, NULL);
429477
}
430478

479+
unsigned int nfp_bpf_ctrl_cmsg_mtu(struct nfp_app_bpf *bpf)
480+
{
481+
return max3((unsigned int)NFP_NET_DEFAULT_MTU,
482+
nfp_bpf_cmsg_map_req_size(bpf, 1),
483+
nfp_bpf_cmsg_map_reply_size(bpf, 1));
484+
}
485+
431486
void nfp_bpf_ctrl_msg_rx(struct nfp_app *app, struct sk_buff *skb)
432487
{
433488
struct nfp_app_bpf *bpf = app->priv;

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

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ enum nfp_bpf_cmsg_type {
9999
#define CMSG_TYPE_MAP_REPLY_BIT 7
100100
#define __CMSG_REPLY(req) (BIT(CMSG_TYPE_MAP_REPLY_BIT) | (req))
101101

102+
/* BPF ABIv2 fixed-length control message fields */
102103
#define CMSG_MAP_KEY_LW 16
103104
#define CMSG_MAP_VALUE_LW 16
104105

@@ -148,24 +149,19 @@ struct cmsg_reply_map_free_tbl {
148149
__be32 count;
149150
};
150151

151-
struct cmsg_key_value_pair {
152-
__be32 key[CMSG_MAP_KEY_LW];
153-
__be32 value[CMSG_MAP_VALUE_LW];
154-
};
155-
156152
struct cmsg_req_map_op {
157153
struct cmsg_hdr hdr;
158154
__be32 tid;
159155
__be32 count;
160156
__be32 flags;
161-
struct cmsg_key_value_pair elem[0];
157+
u8 data[0];
162158
};
163159

164160
struct cmsg_reply_map_op {
165161
struct cmsg_reply_map_simple reply_hdr;
166162
__be32 count;
167163
__be32 resv;
168-
struct cmsg_key_value_pair elem[0];
164+
u8 data[0];
169165
};
170166

171167
struct cmsg_bpf_event {

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ nfp_bpf_parse_cap_abi_version(struct nfp_app_bpf *bpf, void __iomem *value,
356356
}
357357

358358
bpf->abi_version = readl(value);
359-
if (bpf->abi_version != 2) {
359+
if (bpf->abi_version < 2 || bpf->abi_version > 3) {
360360
nfp_warn(bpf->app->cpp, "unsupported BPF ABI version: %d\n",
361361
bpf->abi_version);
362362
bpf->abi_version = 0;
@@ -486,6 +486,15 @@ static int nfp_bpf_init(struct nfp_app *app)
486486
if (err)
487487
goto err_free_neutral_maps;
488488

489+
if (bpf->abi_version < 3) {
490+
bpf->cmsg_key_sz = CMSG_MAP_KEY_LW * 4;
491+
bpf->cmsg_val_sz = CMSG_MAP_VALUE_LW * 4;
492+
} else {
493+
bpf->cmsg_key_sz = bpf->maps.max_key_sz;
494+
bpf->cmsg_val_sz = bpf->maps.max_val_sz;
495+
app->ctrl_mtu = nfp_bpf_ctrl_cmsg_mtu(bpf);
496+
}
497+
489498
bpf->bpf_dev = bpf_offload_dev_create();
490499
err = PTR_ERR_OR_ZERO(bpf->bpf_dev);
491500
if (err)

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ enum pkt_vec {
121121
* @cmsg_replies: received cmsg replies waiting to be consumed
122122
* @cmsg_wq: work queue for waiting for cmsg replies
123123
*
124+
* @cmsg_key_sz: size of key in cmsg element array
125+
* @cmsg_val_sz: size of value in cmsg element array
126+
*
124127
* @map_list: list of offloaded maps
125128
* @maps_in_use: number of currently offloaded maps
126129
* @map_elems_in_use: number of elements allocated to offloaded maps
@@ -166,6 +169,9 @@ struct nfp_app_bpf {
166169
struct sk_buff_head cmsg_replies;
167170
struct wait_queue_head cmsg_wq;
168171

172+
unsigned int cmsg_key_sz;
173+
unsigned int cmsg_val_sz;
174+
169175
struct list_head map_list;
170176
unsigned int maps_in_use;
171177
unsigned int map_elems_in_use;
@@ -496,6 +502,7 @@ nfp_bpf_goto_meta(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
496502

497503
void *nfp_bpf_relo_for_vnic(struct nfp_prog *nfp_prog, struct nfp_bpf_vnic *bv);
498504

505+
unsigned int nfp_bpf_ctrl_cmsg_mtu(struct nfp_app_bpf *bpf);
499506
long long int
500507
nfp_bpf_ctrl_alloc_map(struct nfp_app_bpf *bpf, struct bpf_map *map);
501508
void

drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,6 @@
264264
* %NFP_NET_CFG_BPF_ADDR: DMA address of the buffer with JITed BPF code
265265
*/
266266
#define NFP_NET_CFG_BPF_ABI 0x0080
267-
#define NFP_NET_BPF_ABI 2
268267
#define NFP_NET_CFG_BPF_CAP 0x0081
269268
#define NFP_NET_BPF_CAP_RELO (1 << 0) /* seamless reload */
270269
#define NFP_NET_CFG_BPF_MAX_LEN 0x0082

0 commit comments

Comments
 (0)