Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
2d2f0d6
samples: bpf: pass a struct to sample_install_xdp()
alobakin Feb 17, 2022
1a7dfcb
uapi: Add metadata flag to xdp flags
mswiatko Jul 21, 2021
f1e8503
uapi: bpf: Include xdp generic metadata definition
mswiatko Aug 10, 2021
844d805
xdp: Add helper to fill in magic, type and btf id
walking-machine Feb 3, 2022
dafd55a
ice: Use xdp generic metadata
mswiatko Aug 10, 2021
4e3c682
ice: Expose hints type with 3 last fields
walking-machine Jan 10, 2022
8c8945a
libbpf: Use kernel BTF id in userspace
walking-machine Feb 3, 2022
3d44fe4
libbpf: Patch module BTF id into bpf insns
walking-machine Feb 3, 2022
7a2e68f
[TEMP] bpf: use xdp_meta_generic in kernel
walking-machine Oct 7, 2021
1079485
samples: bpf: Add simple sample with CORE
walking-machine Oct 4, 2021
52c0d1b
samples: Update copyright comment in sample (both kern and user parts)
walking-machine Feb 10, 2022
88c95ca
Fix xdp: Add helper to fill in magic, type and btf id
walking-machine Feb 11, 2022
3ae10ef
Fix xdp: ice: Use xdp generic metadata
walking-machine Feb 11, 2022
456cea4
Fix ice: Expose hints type with 3 last fields
walking-machine Feb 11, 2022
771695c
Fix bpf part of the example
walking-machine Feb 16, 2022
d4ce6d2
Fix libbpf: Use kernel BTF id in userspace
walking-machine Feb 17, 2022
772ea7b
Fix uapi: bpf: Include xdp generic metadata definition
walking-machine Feb 17, 2022
1ebd166
ice: fix metadata vsi flag
walking-machine Feb 21, 2022
d94387c
Add use_meta flag to xdp_meta_user install_opts
walking-machine Feb 21, 2022
1dd10a7
samples: bpf: Refactor userspace part of the sample
walking-machine Feb 21, 2022
9fa8f22
Fix sample compilation with LLVM
walking-machine Mar 10, 2022
fa3e1f2
Avoid false positive when building selftests
walking-machine Mar 21, 2022
623ba95
module BTF id test
walking-machine Mar 25, 2022
f2a1c36
Fix poisoned u32/s32 in core reloc bitfield tests
walking-machine Mar 25, 2022
aa1f95f
uapi: bpf: Move all hints defines to a single enum to make sure they …
walking-machine Apr 4, 2022
1215fab
libbpf: Add endianness conversion macros for LE
walking-machine Apr 5, 2022
9614207
samples: bpf: Read RX hints fields in xdp_meta sample (and also remov…
walking-machine Apr 4, 2022
e4d0d0d
net: xdp: Increase data_meta size limit
walking-machine Apr 11, 2022
de81e6c
samples: bpf: Access data_meta memory directly
walking-machine Apr 11, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions drivers/net/ethernet/intel/ice/ice.h
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,9 @@ struct ice_vsi {

struct ice_channel *ch;

u8 xdp_metadata_support:1; /* true if VSI should support xdp meta */
struct xdp_meta_tail xdp_meta_tail;

/* setup back reference, to which aggregator node this VSI
* corresponds to
*/
Expand Down
33 changes: 31 additions & 2 deletions drivers/net/ethernet/intel/ice/ice_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2607,6 +2607,21 @@ static void ice_vsi_assign_bpf_prog(struct ice_vsi *vsi, struct bpf_prog *prog)
WRITE_ONCE(vsi->rx_rings[i]->xdp_prog, vsi->xdp_prog);
}

static void ice_xdp_rings_set_metadata(const struct ice_vsi *vsi)
{
int i;

ice_for_each_rxq(vsi, i) {
vsi->rx_rings[i]->xdp_metadata_support = vsi->xdp_metadata_support;
vsi->rx_rings[i]->xdp_meta_tail = vsi->xdp_meta_tail;
}

for (i = 0; i < vsi->num_xdp_txq; i++) {
vsi->xdp_rings[i]->xdp_metadata_support = vsi->xdp_metadata_support;
vsi->xdp_rings[i]->xdp_meta_tail = vsi->xdp_meta_tail;
}
}

/**
* ice_prepare_xdp_rings - Allocate, configure and setup Tx rings for XDP
* @vsi: VSI to bring up Tx rings used by XDP
Expand Down Expand Up @@ -2650,6 +2665,8 @@ int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog)
if (ice_xdp_alloc_setup_rings(vsi))
goto clear_xdp_rings;

ice_xdp_rings_set_metadata(vsi);

/* follow the logic from ice_vsi_map_rings_to_vectors */
ice_for_each_q_vector(vsi, v_idx) {
struct ice_q_vector *q_vector = vsi->q_vectors[v_idx];
Expand Down Expand Up @@ -2842,7 +2859,7 @@ int ice_vsi_determine_xdp_res(struct ice_vsi *vsi)
*/
static int
ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog,
struct netlink_ext_ack *extack)
struct netlink_ext_ack *extack, u32 flags)
{
int frame_size = vsi->netdev->mtu + ICE_ETH_PKT_HDR_PAD;
bool if_running = netif_running(vsi->netdev);
Expand All @@ -2862,6 +2879,18 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog,
}
}

if (flags & XDP_FLAGS_USE_METADATA) {
vsi->xdp_metadata_support = true;
ret = xdp_meta_fill_id_magic(&vsi->xdp_meta_tail, THIS_MODULE,
"xdp_meta_generic");
if (ret) {
NL_SET_ERR_MSG_MOD(extack, "Could not fill in xdp meta tail");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should either stop the operation and return early, or, if you want to still allow use XDP, but without metadata, revert vsi->xdp_metadata_support back to false, so the driver wouldn't even try to build it.

vsi->xdp_metadata_support = false;
}
} else {
vsi->xdp_metadata_support = false;
}

if (!ice_is_xdp_ena_vsi(vsi) && prog) {
xdp_ring_err = ice_vsi_determine_xdp_res(vsi);
if (xdp_ring_err) {
Expand Down Expand Up @@ -2924,7 +2953,7 @@ static int ice_xdp(struct net_device *dev, struct netdev_bpf *xdp)

switch (xdp->command) {
case XDP_SETUP_PROG:
return ice_xdp_setup_prog(vsi, xdp->prog, xdp->extack);
return ice_xdp_setup_prog(vsi, xdp->prog, xdp->extack, xdp->flags);
case XDP_SETUP_XSK_POOL:
return ice_xsk_pool_setup(vsi, xdp->xsk.pool,
xdp->xsk.queue_id);
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1184,6 +1184,10 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
hard_start = page_address(rx_buf->page) + rx_buf->page_offset -
offset;
xdp_prepare_buff(&xdp, hard_start, offset, size, true);

if (likely(rx_ring->xdp_metadata_support))
ice_xdp_set_meta(&xdp, rx_desc, rx_ring->xdp_meta_tail);

#if (PAGE_SIZE > 4096)
/* At larger PAGE_SIZE, frame_sz depend on len size */
xdp.frame_sz = ice_rx_frame_truesize(rx_ring, size);
Expand Down
9 changes: 9 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_txrx.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,10 @@ struct ice_rx_ring {
struct xsk_buff_pool *xsk_pool;
struct sk_buff *skb;
dma_addr_t dma; /* physical address of ring */

u8 xdp_metadata_support:1; /* is xdp metadata supported */
struct xdp_meta_tail xdp_meta_tail;

#define ICE_RX_FLAGS_RING_BUILD_SKB BIT(1)
u64 cached_phctime;
u8 dcb_tc; /* Traffic class of ring */
Expand Down Expand Up @@ -322,6 +326,7 @@ struct ice_tx_ring {
u16 reg_idx; /* HW register index of the ring */
u16 count; /* Number of descriptors */
u16 q_index; /* Queue number of ring */

/* stats structs */
struct ice_txq_stats tx_stats;
/* CL3 - 3rd cacheline starts here */
Expand All @@ -335,6 +340,10 @@ struct ice_tx_ring {
u32 txq_teid; /* Added Tx queue TEID */
/* CL4 - 4th cacheline starts here */
u16 xdp_tx_active;

u8 xdp_metadata_support:1; /* is xdp metadata supported */
struct xdp_meta_tail xdp_meta_tail;

#define ICE_TX_FLAGS_RING_XDP BIT(0)
#define ICE_TX_FLAGS_RING_VLAN_L2TAG1 BIT(1)
#define ICE_TX_FLAGS_RING_VLAN_L2TAG2 BIT(2)
Expand Down
26 changes: 26 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_txrx_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,32 @@ static inline void ice_xdp_ring_update_tail(struct ice_tx_ring *xdp_ring)
writel_relaxed(xdp_ring->next_to_use, xdp_ring->tail);
}

static inline void ice_xdp_set_meta(struct xdp_buff *xdp, const union ice_32b_rx_flex_desc *desc,
const struct xdp_meta_tail tail)
{
const struct ice_32b_rx_flex_desc_nic *flex = (struct ice_32b_rx_flex_desc_nic *)desc;
struct xdp_meta_generic *md = xdp->data - sizeof(struct xdp_meta_generic);

/* Fields are already in little endian*/
md->rx_vid = flex->flex_ts.flex.vlan_id;
md->rx_hash = flex->rss_hash;

md->rx_flags = 0;
md->rx_qid = 0;
md->rx_csum = 0;
md->rx_tstamp = 0;

md->tx_flags = 0;
md->tx_csum_off = 0;
md->tx_vid = 0;

md->btf_id = tail.btf_id;
md->type_id = tail.type_id;
md->magic = tail.magic;

xdp->data_meta = md;
}

void ice_finalize_xdp_rx(struct ice_tx_ring *xdp_ring, unsigned int xdp_res);
int ice_xmit_xdp_buff(struct xdp_buff *xdp, struct ice_tx_ring *xdp_ring);
int ice_xmit_xdp_ring(void *data, u16 size, struct ice_tx_ring *xdp_ring);
Expand Down
1 change: 1 addition & 0 deletions include/linux/btf.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ u32 btf_obj_id(const struct btf *btf);
bool btf_is_kernel(const struct btf *btf);
bool btf_is_module(const struct btf *btf);
struct module *btf_try_get_module(const struct btf *btf);
struct btf *btf_get_module_btf(const struct module *module);
u32 btf_nr_types(const struct btf *btf);
bool btf_member_is_reg_int(const struct btf *btf, const struct btf_type *s,
const struct btf_member *m,
Expand Down
11 changes: 10 additions & 1 deletion include/net/xdp.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,15 @@ struct sk_buff *xdp_build_skb_from_frame(struct xdp_frame *xdpf,
int xdp_alloc_skb_bulk(void **skbs, int n_skb, gfp_t gfp);
struct xdp_frame *xdpf_clone(struct xdp_frame *xdpf);

struct xdp_meta_tail {
__le32 btf_id;
__le32 type_id;
__le32 magic;
};

int xdp_meta_fill_id_magic(struct xdp_meta_tail *tail, const struct module *mod,
const char *type_name);

static inline
void xdp_convert_frame_to_buff(struct xdp_frame *frame, struct xdp_buff *xdp)
{
Expand Down Expand Up @@ -395,7 +404,7 @@ xdp_data_meta_unsupported(const struct xdp_buff *xdp)

static inline bool xdp_metalen_invalid(unsigned long metalen)
{
return (metalen & (sizeof(__u32) - 1)) || (metalen > 32);
return (metalen & (sizeof(__u32) - 1)) || (metalen > 256);
}

struct xdp_attachment_info {
Expand Down
54 changes: 54 additions & 0 deletions include/uapi/linux/bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -6634,4 +6634,58 @@ struct bpf_core_relo {
enum bpf_core_relo_kind kind;
};

enum {
XDP_META_RX_QID_BIT = (0x1 << 9),
XDP_META_RX_TSTAMP_BIT = (0x1 << 8),
XDP_META_RX_VLAN_TYPE = (0x3 << 6),
XDP_META_RX_VLAN_NONE = 0x0,
XDP_META_RX_CVID = 0x1,
XDP_META_RX_SVID = 0x2,
XDP_META_RX_HASH_TYPE = (0x3 << 4),
XDP_META_RX_HASH_NONE = 0x0,
XDP_META_RX_HASH_L2 = 0x1,
XDP_META_RX_HASH_L3 = 0x2,
XDP_META_RX_HASH_L4 = 0x3,
XDP_META_RX_CSUM_LEVEL = (0x3 << 2),
XDP_META_RX_CSUM_STATUS = (0x3 << 0),
XDP_META_RX_CSUM_NONE = 0x0,
XDP_META_RX_CSUM_OK = 0x1,
XDP_META_RX_CSUM_COMP = 0x2,
XDP_META_TX_VLAN_TYPE = (0x3 << 1),
XDP_META_TX_CVID = 0x1,
XDP_META_TX_SVID = 0x2,
XDP_META_TX_CSUM_BIT = (0x1 << 0),
XDP_META_GENERIC_MAGIC = 0xe4a6327d,
XDP_META_ALIGN = 8,
};

struct xdp_meta_generic {
__u8 padding[4];

/* Add new fields here */

/* Ingress */
__le32 rx_flags;

__le16 rx_qid;
__le16 rx_vid;
__le32 rx_csum;
__le32 rx_hash;
__le64 rx_tstamp;

/* Egress */

__le32 tx_flags;

__le16 tx_csum_off;
__le16 tx_vid;

/* Unique identifiers */
__le32 btf_id;
__le32 type_id;
__le32 magic;
}
__attribute__((__packed__)) /* Might be composed directly by HW */
__attribute__((aligned(XDP_META_ALIGN))); /* Resides before Eth header, padded/aligned */

#endif /* _UAPI__LINUX_BPF_H__ */
4 changes: 3 additions & 1 deletion include/uapi/linux/if_link.h
Original file line number Diff line number Diff line change
Expand Up @@ -1275,11 +1275,13 @@ enum {
#define XDP_FLAGS_DRV_MODE (1U << 2)
#define XDP_FLAGS_HW_MODE (1U << 3)
#define XDP_FLAGS_REPLACE (1U << 4)
#define XDP_FLAGS_USE_METADATA (1U << 5)
#define XDP_FLAGS_MODES (XDP_FLAGS_SKB_MODE | \
XDP_FLAGS_DRV_MODE | \
XDP_FLAGS_HW_MODE)
#define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST | \
XDP_FLAGS_MODES | XDP_FLAGS_REPLACE)
XDP_FLAGS_MODES | XDP_FLAGS_REPLACE | \
XDP_FLAGS_USE_METADATA)

/* These are stored into IFLA_XDP_ATTACHED on dump. */
enum {
Expand Down
2 changes: 1 addition & 1 deletion kernel/bpf/btf.c
Original file line number Diff line number Diff line change
Expand Up @@ -6576,7 +6576,7 @@ struct module *btf_try_get_module(const struct btf *btf)
/* Returns struct btf corresponding to the struct module.
* This function can return NULL or ERR_PTR.
*/
static struct btf *btf_get_module_btf(const struct module *module)
struct btf *btf_get_module_btf(const struct module *module)
{
#ifdef CONFIG_DEBUG_INFO_BTF_MODULES
struct btf_module *btf_mod, *tmp;
Expand Down
1 change: 1 addition & 0 deletions kernel/bpf/cpumap.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ static int cpu_map_bpf_prog_run_xdp(struct bpf_cpu_map_entry *rcpu,
{
struct xdp_rxq_info rxq;
struct xdp_buff xdp;
volatile struct xdp_meta_generic xdp_meta_generic;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've discovered that you can get away with no volatile, just by placing a pointer here with a __always_unused attribute. The compiler won't wipe it, and you will still have struct BTF in the vmlinux itself.
But it's just some unneeded details as it's purely temporary code.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found some more stuff, actually there's a special macro for making particular enums or structures being included in BTFs, BTF_TYPE_EMIT() ([0]).
I dicovered it pretty randomly when was working around struct bpf_type_event_value not being available when !CONFIG_BPF_EVENTS. Not that it comes handy for this particular draft line, but for the future (:

[0] https://elixir.bootlin.com/linux/v5.17-rc4/source/include/linux/btf.h#L12

int i, nframes = 0;

xdp_set_return_frame_no_direct();
Expand Down
37 changes: 37 additions & 0 deletions net/core/xdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Copyright (c) 2017 Jesper Dangaard Brouer, Red Hat Inc.
*/
#include <linux/bpf.h>
#include <linux/btf.h>
#include <linux/filter.h>
#include <linux/types.h>
#include <linux/mm.h>
Expand Down Expand Up @@ -711,3 +712,39 @@ struct xdp_frame *xdpf_clone(struct xdp_frame *xdpf)

return nxdpf;
}

int xdp_meta_fill_id_magic(struct xdp_meta_tail *tail, const struct module *mod,
const char *type_name)
{
struct btf *btf = NULL, *vmlinux;
int id, err = 0;
u32 vmlinux_len;

vmlinux = bpf_get_btf_vmlinux();
if (IS_ERR(vmlinux))
return PTR_ERR(vmlinux);

btf = btf_get_module_btf(mod);
if (IS_ERR(btf))
return PTR_ERR(btf);
else if (!btf)
btf = vmlinux;

id = btf_find_by_name_kind(btf, type_name, BTF_KIND_STRUCT);
if (id < 0) {
err = id;
goto put;
}

tail->type_id = cpu_to_le32(id);
tail->magic = cpu_to_le32(XDP_META_GENERIC_MAGIC);

vmlinux_len = btf_nr_types(vmlinux);
tail->btf_id = cpu_to_le32(btf_obj_id(id < vmlinux_len ? vmlinux : btf));
put:
if (btf_is_module(btf))
btf_put(btf);

return err;
}
EXPORT_SYMBOL_GPL(xdp_meta_fill_id_magic);
8 changes: 7 additions & 1 deletion samples/bpf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ tprogs-y += xdp_redirect_map_multi
tprogs-y += xdp_redirect_map
tprogs-y += xdp_redirect
tprogs-y += xdp_monitor
tprogs-y += xdp_meta

# Libbpf dependencies
LIBBPF_SRC = $(TOOLS_PATH)/lib/bpf
Expand Down Expand Up @@ -124,6 +125,7 @@ xdp_redirect_cpu-objs := xdp_redirect_cpu_user.o $(XDP_SAMPLE)
xdp_redirect_map-objs := xdp_redirect_map_user.o $(XDP_SAMPLE)
xdp_redirect-objs := xdp_redirect_user.o $(XDP_SAMPLE)
xdp_monitor-objs := xdp_monitor_user.o $(XDP_SAMPLE)
xdp_meta-objs := xdp_meta_user.o $(XDP_SAMPLE)

# Tell kbuild to always build the programs
always-y := $(tprogs-y)
Expand Down Expand Up @@ -220,6 +222,7 @@ TPROGLDLIBS_xdp_redirect += -lm
TPROGLDLIBS_xdp_redirect_cpu += -lm
TPROGLDLIBS_xdp_redirect_map += -lm
TPROGLDLIBS_xdp_redirect_map_multi += -lm
TPROGLDLIBS_xdp_meta += -lm
TPROGLDLIBS_tracex4 += -lrt
TPROGLDLIBS_trace_output += -lrt
TPROGLDLIBS_map_perf_test += -lrt
Expand Down Expand Up @@ -342,6 +345,7 @@ $(obj)/xdp_redirect_map_multi_user.o: $(obj)/xdp_redirect_map_multi.skel.h
$(obj)/xdp_redirect_map_user.o: $(obj)/xdp_redirect_map.skel.h
$(obj)/xdp_redirect_user.o: $(obj)/xdp_redirect.skel.h
$(obj)/xdp_monitor_user.o: $(obj)/xdp_monitor.skel.h
$(obj)/xdp_meta_user.o: $(obj)/xdp_meta.skel.h

$(obj)/tracex5_kern.o: $(obj)/syscall_nrs.h
$(obj)/hbm_out_kern.o: $(src)/hbm.h $(src)/hbm_kern.h
Expand Down Expand Up @@ -409,14 +413,16 @@ $(obj)/%.bpf.o: $(src)/%.bpf.c $(obj)/vmlinux.h $(src)/xdp_sample.bpf.h $(src)/x
-c $(filter %.bpf.c,$^) -o $@

LINKED_SKELS := xdp_redirect_cpu.skel.h xdp_redirect_map_multi.skel.h \
xdp_redirect_map.skel.h xdp_redirect.skel.h xdp_monitor.skel.h
xdp_redirect_map.skel.h xdp_redirect.skel.h xdp_monitor.skel.h \
xdp_meta.skel.h
clean-files += $(LINKED_SKELS)

xdp_redirect_cpu.skel.h-deps := xdp_redirect_cpu.bpf.o xdp_sample.bpf.o
xdp_redirect_map_multi.skel.h-deps := xdp_redirect_map_multi.bpf.o xdp_sample.bpf.o
xdp_redirect_map.skel.h-deps := xdp_redirect_map.bpf.o xdp_sample.bpf.o
xdp_redirect.skel.h-deps := xdp_redirect.bpf.o xdp_sample.bpf.o
xdp_monitor.skel.h-deps := xdp_monitor.bpf.o xdp_sample.bpf.o
xdp_meta.skel.h-deps := xdp_meta.bpf.o

LINKED_BPF_SRCS := $(patsubst %.bpf.o,%.bpf.c,$(foreach skel,$(LINKED_SKELS),$($(skel)-deps)))

Expand Down
Loading