Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 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
2cccf28
libbpf: add BPF helper to access pkt memory with variable offset
walking-machine May 9, 2022
48df76d
samples: bpf: [FIXUP] use new helper in meta sample
walking-machine May 9, 2022
08a7b89
bpf helper FIXUP
walking-machine May 9, 2022
318d3bb
[TEMP] new meta definition
walking-machine May 11, 2022
a08fb15
bpf helper FIXUP-2
walking-machine May 11, 2022
31d542f
[FIXUP-endian] add 16b and 64b
walking-machine May 11, 2022
d3b78fc
[FIXUP-bpf-sample-meta] minor fixes 1
walking-machine May 11, 2022
96ca274
[FIXUP-bpf-sample-meta] minor fixes 2
walking-machine May 12, 2022
e0ee1e1
bpf helper FIXUP-2
walking-machine May 12, 2022
2a1e144
[FIXUP-bpf-sample-meta] minor fixes 3
walking-machine May 13, 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");
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
9 changes: 9 additions & 0 deletions 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
167 changes: 167 additions & 0 deletions include/uapi/linux/bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#ifndef _UAPI__LINUX_BPF_H__
#define _UAPI__LINUX_BPF_H__

#include <asm/byteorder.h>
#include <linux/types.h>
#include <linux/bpf_common.h>

Expand Down Expand Up @@ -6634,4 +6635,170 @@ struct bpf_core_relo {
enum bpf_core_relo_kind kind;
};

/* Definitions being used to work with &xdp_meta_generic, declared as an enum
* so they are visible for BPF programs via vmlinux.h.
*/
enum xdp_meta_generic_defs {
/* xdp_meta_generic::tx_flags */

/* Metadata carries valid Tx timestamp */
XDP_META_TX_TSTAMP_PRESENT = (0x1 << 4),
/* Mask of the bits containing Tx VLAN action */
XDP_META_TX_VLAN_TYPE = (0x3 << 2),
/* No action is needed */
XDP_META_TX_VLAN_NONE = 0x0,
/* NIC must push C-VLAN tag */
XDP_META_TX_CVID = 0x1,
/* NIC must push S-VLAN tag */
XDP_META_TX_SVID = 0x2,
/* Mask of the bits containing Tx checksum action */
XDP_META_TX_CSUM_ACT = (0x3 << 0),
/* No action for checksum */
XDP_META_TX_CSUM_ASIS = 0x0,
/* NIC must compute checksum, no start/offset are provided */
XDP_META_TX_CSUM_AUTO = 0x1,
/* NIC must compute checksum using the provided start and offset */
XDP_META_TX_CSUM_HELP = 0x2,

/* xdp_meta_generic::rx_flags */

/* Metadata contains valid Rx queue ID */
XDP_META_RX_QID_PRESENT = (0x1 << 9),
/* Metadata contains valid Rx timestamp */
XDP_META_RX_TSTAMP_PRESENT = (0x1 << 8),
/* Mask of the bits containing Rx VLAN status */
XDP_META_RX_VLAN_TYPE = (0x3 << 6),
/* Metadata does not have any VLAN tags */
XDP_META_RX_VLAN_NONE = 0x0,
/* Metadata carries valid C-VLAN tag */
XDP_META_RX_CVID = 0x1,
/* Metadata carries valid S-VLAN tag */
XDP_META_RX_SVID = 0x2,
/* Mask of the bits containing Rx hash status */
XDP_META_RX_HASH_TYPE = (0x3 << 4),
/* Metadata has no RSS hash */
XDP_META_RX_HASH_NONE = 0x0,
/* Metadata has valid L2 hash */
XDP_META_RX_HASH_L2 = 0x1,
/* Metadata has valid L3 hash */
XDP_META_RX_HASH_L3 = 0x2,
/* Metadata has valid L4 hash */
XDP_META_RX_HASH_L4 = 0x3,
/* Mask of the field containing checksum level (if there's encap) */
XDP_META_RX_CSUM_LEVEL = (0x3 << 2),
/* Mask of the bits containing Rx checksum status */
XDP_META_RX_CSUM_STATUS = (0x3 << 0),
/* Metadata has no checksum info */
XDP_META_RX_CSUM_NONE = 0x0,
/* Checksum has been verified by NIC */
XDP_META_RX_CSUM_OK = 0x1,
/* Metadata carries valid checksum */
XDP_META_RX_CSUM_COMP = 0x2,

/* xdp_meta_generic::magic_id indicates that the metadata is either
* struct xdp_meta_generic itself or contains it at the end -> can be
* used to get/set HW hints.
* Direct btf_id comparison is not enough here as a custom structure
* caring xdp_meta_generic at the end will have a different ID.
*/
XDP_META_GENERIC_MAGIC = 0xeda6,
};

/* Generic metadata can be composed directly by HW, plus it should always
* have the first field as __le16 to account the 2 bytes of "IP align", so
* we pack it to avoid unexpected paddings. Also, it should be aligned to
* sizeof(__be16) as any other Ethernet data, and to optimize access on the
* 32-bit platforms.
*/
#define __xdp_meta_generic_attrs \
__attribute__((__packed__)) \
__attribute__((aligned(sizeof(__be16))))

/* Depending on the field layout inside the structure, it might or might not
* emit a "packed attribute is unnecessary" warning (when enabled, e.g. in
* libbpf). To not add and remove the attributes on each field addition,
* just suppress it.
*/
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpacked"

/* All fields have explicit endianness, as it might be composed by HW.
* Byteswaps are needed for the Big Endian architectures to access the
* fields.
*/
struct xdp_meta_generic {
/* Add new fields here */

/* Egress part */
__struct_group(/* no tag */, tx, __xdp_meta_generic_attrs,
/* Offset from the start of the frame to the L4 header
* to compute checksum for
*/
__le16 tx_csum_start;
/* Offset inside the L4 header to the checksum field */
__le16 tx_csum_off;
/* ID for hardware VLAN push */
__le16 tx_vid;
/* Flags indicating which Tx metadata is used */
__le32 tx_flags;
/* Tx timestamp value */
__le64 tx_tstamp;
);

/* Shortcut for the half relevant on ingress: Rx + IDs */
__struct_group(xdp_meta_generic_rx, rx_full, __xdp_meta_generic_attrs,
/* Ingress part */
__struct_group(/* no tag */, rx, __xdp_meta_generic_attrs,
/* Rx timestamp value */
__le64 rx_tstamp;
/* Rx hash value */
__le32 rx_hash;
/* Rx checksum value */
__le32 rx_csum;
/* VLAN ID popped on Rx */
__le16 rx_vid;
/* Rx queue ID on which the frame has arrived */
__le16 rx_qid;
/* Flags indicating which Rx metadata is used */
__le32 rx_flags;
);

/* Unique metadata identifiers */
__struct_group(/* no tag */, id, __xdp_meta_generic_attrs,
union {
struct {
#ifdef __BIG_ENDIAN_BITFIELD
/* Indicates the ID of the BTF which
* the below type ID comes from, as
* several kernel modules may have
* identical type IDs
*/
__le32 btf_id;
/* Indicates the ID of the actual
* structure passed as metadata,
* within the above BTF ID
*/
__le32 type_id;
#else /* __LITTLE_ENDIAN_BITFIELD */
__le32 type_id;
__le32 btf_id;
#endif /* __LITTLE_ENDIAN_BITFIELD */
};
/* BPF program gets IDs coded as one __u64:
* `btf_id << 32 | type_id`, allow direct
* comparison
*/
__le64 full_id;
};
/* If set to the correct value, indicates that the
* meta is generic-compatible and can be used by
* the consumers of generic metadata
*/
__le16 magic;
);
);
} __xdp_meta_generic_attrs;

#pragma GCC diagnostic pop

#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;
int i, nframes = 0;

xdp_set_return_frame_no_direct();
Expand Down
Loading