Skip to content

Commit 67f29e0

Browse files
netoptimizerAlexei Starovoitov
authored andcommitted
bpf: devmap introduce dev_map_enqueue
Functionality is the same, but the ndo_xdp_xmit call is now simply invoked from inside the devmap.c code. V2: Fix compile issue reported by kbuild test robot <[email protected]> V5: Cleanups requested by Daniel - Newlines before func definition - Use BUILD_BUG_ON checks - Remove unnecessary use return value store in dev_map_enqueue Signed-off-by: Jesper Dangaard Brouer <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent f80acbd commit 67f29e0

File tree

4 files changed

+51
-23
lines changed

4 files changed

+51
-23
lines changed

include/linux/bpf.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -487,14 +487,16 @@ int bpf_check(struct bpf_prog **fp, union bpf_attr *attr);
487487
void bpf_patch_call_args(struct bpf_insn *insn, u32 stack_depth);
488488

489489
/* Map specifics */
490-
struct net_device *__dev_map_lookup_elem(struct bpf_map *map, u32 key);
490+
struct xdp_buff;
491+
492+
struct bpf_dtab_netdev *__dev_map_lookup_elem(struct bpf_map *map, u32 key);
491493
void __dev_map_insert_ctx(struct bpf_map *map, u32 index);
492494
void __dev_map_flush(struct bpf_map *map);
495+
int dev_map_enqueue(struct bpf_dtab_netdev *dst, struct xdp_buff *xdp);
493496

494497
struct bpf_cpu_map_entry *__cpu_map_lookup_elem(struct bpf_map *map, u32 key);
495498
void __cpu_map_insert_ctx(struct bpf_map *map, u32 index);
496499
void __cpu_map_flush(struct bpf_map *map);
497-
struct xdp_buff;
498500
int cpu_map_enqueue(struct bpf_cpu_map_entry *rcpu, struct xdp_buff *xdp,
499501
struct net_device *dev_rx);
500502

@@ -573,6 +575,15 @@ static inline void __dev_map_flush(struct bpf_map *map)
573575
{
574576
}
575577

578+
struct xdp_buff;
579+
struct bpf_dtab_netdev;
580+
581+
static inline
582+
int dev_map_enqueue(struct bpf_dtab_netdev *dst, struct xdp_buff *xdp)
583+
{
584+
return 0;
585+
}
586+
576587
static inline
577588
struct bpf_cpu_map_entry *__cpu_map_lookup_elem(struct bpf_map *map, u32 key)
578589
{
@@ -587,7 +598,6 @@ static inline void __cpu_map_flush(struct bpf_map *map)
587598
{
588599
}
589600

590-
struct xdp_buff;
591601
static inline int cpu_map_enqueue(struct bpf_cpu_map_entry *rcpu,
592602
struct xdp_buff *xdp,
593603
struct net_device *dev_rx)

include/trace/events/xdp.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,18 @@ DEFINE_EVENT_PRINT(xdp_redirect_template, xdp_redirect_map_err,
138138
__entry->map_id, __entry->map_index)
139139
);
140140

141+
#ifndef __DEVMAP_OBJ_TYPE
142+
#define __DEVMAP_OBJ_TYPE
143+
struct _bpf_dtab_netdev {
144+
struct net_device *dev;
145+
};
146+
#endif /* __DEVMAP_OBJ_TYPE */
147+
141148
#define devmap_ifindex(fwd, map) \
142149
(!fwd ? 0 : \
143150
(!map ? 0 : \
144151
((map->map_type == BPF_MAP_TYPE_DEVMAP) ? \
145-
((struct net_device *)fwd)->ifindex : 0)))
152+
((struct _bpf_dtab_netdev *)fwd)->dev->ifindex : 0)))
146153

147154
#define _trace_xdp_redirect_map(dev, xdp, fwd, map, idx) \
148155
trace_xdp_redirect_map(dev, xdp, devmap_ifindex(fwd, map), \

kernel/bpf/devmap.c

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,15 @@
4848
* calls will fail at this point.
4949
*/
5050
#include <linux/bpf.h>
51+
#include <net/xdp.h>
5152
#include <linux/filter.h>
53+
#include <trace/events/xdp.h>
5254

5355
#define DEV_CREATE_FLAG_MASK \
5456
(BPF_F_NUMA_NODE | BPF_F_RDONLY | BPF_F_WRONLY)
5557

5658
struct bpf_dtab_netdev {
57-
struct net_device *dev;
59+
struct net_device *dev; /* must be first member, due to tracepoint */
5860
struct bpf_dtab *dtab;
5961
unsigned int bit;
6062
struct rcu_head rcu;
@@ -240,21 +242,38 @@ void __dev_map_flush(struct bpf_map *map)
240242
* update happens in parallel here a dev_put wont happen until after reading the
241243
* ifindex.
242244
*/
243-
struct net_device *__dev_map_lookup_elem(struct bpf_map *map, u32 key)
245+
struct bpf_dtab_netdev *__dev_map_lookup_elem(struct bpf_map *map, u32 key)
244246
{
245247
struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);
246-
struct bpf_dtab_netdev *dev;
248+
struct bpf_dtab_netdev *obj;
247249

248250
if (key >= map->max_entries)
249251
return NULL;
250252

251-
dev = READ_ONCE(dtab->netdev_map[key]);
252-
return dev ? dev->dev : NULL;
253+
obj = READ_ONCE(dtab->netdev_map[key]);
254+
return obj;
255+
}
256+
257+
int dev_map_enqueue(struct bpf_dtab_netdev *dst, struct xdp_buff *xdp)
258+
{
259+
struct net_device *dev = dst->dev;
260+
struct xdp_frame *xdpf;
261+
262+
if (!dev->netdev_ops->ndo_xdp_xmit)
263+
return -EOPNOTSUPP;
264+
265+
xdpf = convert_to_xdp_frame(xdp);
266+
if (unlikely(!xdpf))
267+
return -EOVERFLOW;
268+
269+
/* TODO: implement a bulking/enqueue step later */
270+
return dev->netdev_ops->ndo_xdp_xmit(dev, xdpf);
253271
}
254272

255273
static void *dev_map_lookup_elem(struct bpf_map *map, void *key)
256274
{
257-
struct net_device *dev = __dev_map_lookup_elem(map, *(u32 *)key);
275+
struct bpf_dtab_netdev *obj = __dev_map_lookup_elem(map, *(u32 *)key);
276+
struct net_device *dev = dev = obj ? obj->dev : NULL;
258277

259278
return dev ? &dev->ifindex : NULL;
260279
}
@@ -405,6 +424,9 @@ static struct notifier_block dev_map_notifier = {
405424

406425
static int __init dev_map_init(void)
407426
{
427+
/* Assure tracepoint shadow struct _bpf_dtab_netdev is in sync */
428+
BUILD_BUG_ON(offsetof(struct bpf_dtab_netdev, dev) !=
429+
offsetof(struct _bpf_dtab_netdev, dev));
408430
register_netdevice_notifier(&dev_map_notifier);
409431
return 0;
410432
}

net/core/filter.c

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3065,20 +3065,9 @@ static int __bpf_tx_xdp_map(struct net_device *dev_rx, void *fwd,
30653065

30663066
switch (map->map_type) {
30673067
case BPF_MAP_TYPE_DEVMAP: {
3068-
struct net_device *dev = fwd;
3069-
struct xdp_frame *xdpf;
3068+
struct bpf_dtab_netdev *dst = fwd;
30703069

3071-
if (!dev->netdev_ops->ndo_xdp_xmit)
3072-
return -EOPNOTSUPP;
3073-
3074-
xdpf = convert_to_xdp_frame(xdp);
3075-
if (unlikely(!xdpf))
3076-
return -EOVERFLOW;
3077-
3078-
/* TODO: move to inside map code instead, for bulk support
3079-
* err = dev_map_enqueue(dev, xdp);
3080-
*/
3081-
err = dev->netdev_ops->ndo_xdp_xmit(dev, xdpf);
3070+
err = dev_map_enqueue(dst, xdp);
30823071
if (err)
30833072
return err;
30843073
__dev_map_insert_ctx(map, index);

0 commit comments

Comments
 (0)