From c8c5144fd8e9b18bdfd5c3405b755203b988a827 Mon Sep 17 00:00:00 2001 From: Michal Swiatkowski Date: Wed, 21 Jul 2021 18:30:42 -0400 Subject: [PATCH 1/5] uapi: add metadata flag to xdp flags Second approach to inform driver about metadata. Let user decide if metadata should be supported or not. Add this flag to allow user to inform driver that metadata is used. Set flag is sent to driver via exsisting ndo_bpf call in flag field. Signed-off-by: Michal Swiatkowski --- include/uapi/linux/if_link.h | 4 +++- tools/include/uapi/linux/if_link.h | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index eebd3894fe89a0..4326237c7ba1e8 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -1182,11 +1182,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 { diff --git a/tools/include/uapi/linux/if_link.h b/tools/include/uapi/linux/if_link.h index b3610fdd1feec3..595e238d489b71 100644 --- a/tools/include/uapi/linux/if_link.h +++ b/tools/include/uapi/linux/if_link.h @@ -969,11 +969,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 { From 92adc5dbc74ad07d9ed0b75ab1f4c804e6a54793 Mon Sep 17 00:00:00 2001 From: Michal Swiatkowski Date: Mon, 9 Aug 2021 20:25:18 -0400 Subject: [PATCH 2/5] net: include xdp generic metadata definition Definition is only a proposal. There should be free place for 8B of tx timestamp. Signed-off-by: Michal Swiatkowski --- include/net/xdp.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/include/net/xdp.h b/include/net/xdp.h index ad5b02dcb6f4c4..9c4d3c9ddc7de9 100644 --- a/include/net/xdp.h +++ b/include/net/xdp.h @@ -76,6 +76,24 @@ struct xdp_buff { u32 frame_sz; /* frame size to deduce data_hard_end/reserved tailroom*/ }; +struct xdp_meta_generic { + // Tx part + u32 flags; + u16 free_slot; + u16 csum_off; + u16 txcvid; + + // Rx part + u16 rxcvid; + u32 csum; + u32 hash; + u64 tstamp; + + // BTF ID + u32 btf_id; +} __packed __aligned(8); +static_assert(sizeof(struct xdp_meta_generic) == 32); + static __always_inline void xdp_init_buff(struct xdp_buff *xdp, u32 frame_sz, struct xdp_rxq_info *rxq) { From aef5c237b842bc5541b919e917c203c871538e4e Mon Sep 17 00:00:00 2001 From: Michal Swiatkowski Date: Mon, 9 Aug 2021 23:21:15 -0400 Subject: [PATCH 3/5] ice: use xdp generic metadata As starting point add vlan id and rss hash if xdp metadata is supported. Add xd_metadata_support field in VSI to allow easy passing this value to ring configuration. Signed-off-by: Michal Swiatkowski --- drivers/net/ethernet/intel/ice/ice.h | 2 ++ drivers/net/ethernet/intel/ice/ice_main.c | 20 +++++++++++++++++-- drivers/net/ethernet/intel/ice/ice_txrx.c | 3 +++ drivers/net/ethernet/intel/ice/ice_txrx.h | 3 +++ drivers/net/ethernet/intel/ice/ice_txrx_lib.h | 10 ++++++++++ 5 files changed, 36 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h index eadcb99583464f..d2441c8192919c 100644 --- a/drivers/net/ethernet/intel/ice/ice.h +++ b/drivers/net/ethernet/intel/ice/ice.h @@ -349,6 +349,8 @@ struct ice_vsi { u16 num_xdp_txq; /* Used XDP queues */ u8 xdp_mapping_mode; /* ICE_MAP_MODE_[CONTIG|SCATTER] */ + bool xdp_metadata_support; /* true if VSI should support xdp meta */ + /* setup back reference, to which aggregator node this VSI * corresponds to */ diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index 0d6c143f665327..50a3b9adc1d447 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -2419,6 +2419,17 @@ 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(struct ice_vsi *vsi) +{ + int i; + + ice_for_each_rxq(vsi, i) + vsi->rx_rings[i]->xdp_metadata_support = vsi->xdp_metadata_support; + + for (i = 0; i < vsi->num_xdp_txq; i++) + vsi->xdp_rings[i]->xdp_metadata_support = vsi->xdp_metadata_support; +} + /** * ice_prepare_xdp_rings - Allocate, configure and setup Tx rings for XDP * @vsi: VSI to bring up Tx rings used by XDP @@ -2458,6 +2469,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]; @@ -2613,7 +2626,7 @@ static void ice_vsi_rx_napi_schedule(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); @@ -2633,6 +2646,9 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog, } } + if (flags & XDP_FLAGS_USE_METADATA) + vsi->xdp_metadata_support = true; + if (!ice_is_xdp_ena_vsi(vsi) && prog) { vsi->num_xdp_txq = vsi->alloc_rxq; xdp_ring_err = ice_prepare_xdp_rings(vsi, prog); @@ -2686,7 +2702,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); diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c index 6ee8e0032d52cb..128fd49383439a 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx.c +++ b/drivers/net/ethernet/intel/ice/ice_txrx.c @@ -1135,6 +1135,9 @@ int ice_clean_rx_irq(struct ice_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); #if (PAGE_SIZE > 4096) /* At larger PAGE_SIZE, frame_sz depend on len size */ xdp.frame_sz = ice_rx_frame_truesize(rx_ring, size); diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.h b/drivers/net/ethernet/intel/ice/ice_txrx.h index 1e46e80f3d6f89..b43923ddf883cf 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx.h +++ b/drivers/net/ethernet/intel/ice/ice_txrx.h @@ -276,6 +276,7 @@ struct ice_ring { u16 q_handle; /* Queue handle per TC */ u8 ring_active:1; /* is ring online or not */ + u8 xdp_metadata_support:1; /* is xdp metadata support */ u16 count; /* Number of descriptors */ u16 reg_idx; /* HW register index of the ring */ @@ -301,6 +302,8 @@ struct ice_ring { /* CL3 - 3rd cacheline starts here */ struct xdp_rxq_info xdp_rxq; struct sk_buff *skb; + + /* CLX - the below items are only accessed infrequently and should be * in their own cache line if possible */ diff --git a/drivers/net/ethernet/intel/ice/ice_txrx_lib.h b/drivers/net/ethernet/intel/ice/ice_txrx_lib.h index 05ac3075290260..d77bc7686b61bd 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx_lib.h +++ b/drivers/net/ethernet/intel/ice/ice_txrx_lib.h @@ -46,6 +46,16 @@ static inline void ice_xdp_ring_update_tail(struct ice_ring *xdp_ring) writel_relaxed(xdp_ring->next_to_use, xdp_ring->tail); } +static inline void ice_xdp_set_meta(struct xdp_buff *xdp, union ice_32b_rx_flex_desc *desc) +{ + 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); + + xdp->data_meta = md; + md->rxcvid = le16_to_cpu(flex->flex_ts.flex.vlan_id); + md->hash = le32_to_cpu(flex->rss_hash); +} + void ice_finalize_xdp_rx(struct ice_ring *rx_ring, unsigned int xdp_res); int ice_xmit_xdp_buff(struct xdp_buff *xdp, struct ice_ring *xdp_ring); int ice_xmit_xdp_ring(void *data, u16 size, struct ice_ring *xdp_ring); From f1a04d25739258473781ed2ccd97237aff2c2097 Mon Sep 17 00:00:00 2001 From: Michal Swiatkowski Date: Thu, 16 Sep 2021 02:20:19 -0400 Subject: [PATCH 4/5] samples: bpf: add simple sample with CORE Signed-off-by: Michal Swiatkowski --- samples/bpf/Makefile | 8 +++-- samples/bpf/xdp_meta.bpf.c | 40 +++++++++++++++++++++ samples/bpf/xdp_meta_user.c | 72 +++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 samples/bpf/xdp_meta.bpf.c create mode 100644 samples/bpf/xdp_meta_user.c diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index 4dc20be5fb96a6..9b5fc9f5e6c8d3 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile @@ -57,6 +57,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 = $(TOOLS_PATH)/lib/bpf/libbpf.a @@ -118,6 +119,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 # Tell kbuild to always build the programs always-y := $(tprogs-y) @@ -314,6 +316,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 @@ -371,7 +374,8 @@ $(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 @@ -379,9 +383,9 @@ xdp_redirect_map_multi.skel.h-deps := xdp_redirect_map_multi.bpf.o xdp_sample.bp 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))) - BPF_SRCS_LINKED := $(notdir $(wildcard $(src)/*.bpf.c)) BPF_OBJS_LINKED := $(patsubst %.bpf.c,$(obj)/%.bpf.o, $(BPF_SRCS_LINKED)) BPF_SKELS_LINKED := $(addprefix $(obj)/,$(LINKED_SKELS)) diff --git a/samples/bpf/xdp_meta.bpf.c b/samples/bpf/xdp_meta.bpf.c new file mode 100644 index 00000000000000..8f49b11ab160a6 --- /dev/null +++ b/samples/bpf/xdp_meta.bpf.c @@ -0,0 +1,40 @@ +/* This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + */ +#include "vmlinux.h" + +#include +#include +#include + +struct xdp_meta_generic___empty { + u32 btf_id; +}; + +SEC("xdp") +int xdp_meta_prog(struct xdp_md *ctx) +{ + struct xdp_meta_generic___empty *data_meta = + (void *)(long)ctx->data_meta; + void *data_end = (void *)(long)ctx->data_end; + void *data = (void *)(long)ctx->data; + struct ethhdr *eth = data; + u64 nh_off; + int id; + long *value; + + nh_off = sizeof(*eth); + if (data + nh_off > data_end) + return XDP_DROP; + + if (data_meta + 1 > data) + return XDP_DROP; + + id = bpf_core_type_id_kernel(struct xdp_meta_generic___empty); + bpf_printk("id is %d\n", id); + + return XDP_PASS; +} + +char LICENSE[] SEC("license") = "GPL"; diff --git a/samples/bpf/xdp_meta_user.c b/samples/bpf/xdp_meta_user.c new file mode 100644 index 00000000000000..9422a180240d37 --- /dev/null +++ b/samples/bpf/xdp_meta_user.c @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "xdp_meta.skel.h" + +int main(int argc, char **argv) +{ + __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_USE_METADATA; + __u32 prog_id, prog_fd; + struct xdp_meta *skel; + int ifindex, ret = 1; + + if (argc == optind) { + return ret; + } + + ifindex = if_nametoindex(argv[optind]); + if (!ifindex) + ifindex = strtoul(argv[optind], NULL, 0); + if (!ifindex) { + fprintf(stderr, "Bad interface index or name\n"); + goto end; + } + + skel = xdp_meta__open(); + if (!skel) { + fprintf(stderr, "Failed to xdp_meta__open: %s\n", + strerror(errno)); + ret = 1; + goto end; + } + + ret = xdp_meta__load(skel); + if (ret < 0) { + fprintf(stderr, "Failed to xdp_meta__load: %s\n", strerror(errno)); + ret = 1; + goto end_destroy; + } + + ret = 1; + prog_fd = bpf_program__fd(skel->progs.xdp_meta_prog); + if (bpf_set_link_xdp_fd(ifindex, prog_fd, xdp_flags) < 0) { + fprintf(stderr, "Failed to set xdp link"); + goto end_destroy; + } + + if (bpf_get_link_xdp_id(ifindex, &prog_id, xdp_flags)) { + fprintf(stderr, "Failed to get XDP program id for ifindex"); + goto end_destroy; + } + + while (1) { + sleep(2); + } + + ret = 0; +end_destroy: + xdp_meta__destroy(skel); +end: + return ret; +} From 36335fefe63a4da6a1ff4f2a57e338217df64c46 Mon Sep 17 00:00:00 2001 From: Michal Swiatkowski Date: Thu, 23 Sep 2021 18:40:43 -0400 Subject: [PATCH 5/5] btf: ice: implement finding BTF type id Function btf_get_type_id is needed to get correct BTF id to fill metadata by driver. BTF id is obtained while loading XDP program and saved in ring structure to be available in irq. Calling btf_get_type_id with null pointer as module will result in searching for BTF id in vmlinux. Also cleanup sample code to print id from metadata and from libbpf. Moving btf_id in generic metadata structure is temporary solution. Signed-off-by: Ederson de Souza Signed-off-by: Michal Swiatkowski --- drivers/net/ethernet/intel/ice/ice.h | 2 + drivers/net/ethernet/intel/ice/ice_main.c | 12 ++++-- drivers/net/ethernet/intel/ice/ice_txrx.c | 3 +- drivers/net/ethernet/intel/ice/ice_txrx.h | 1 + drivers/net/ethernet/intel/ice/ice_txrx_lib.h | 14 ++++++- include/linux/btf.h | 1 + include/net/xdp.h | 6 +-- kernel/bpf/btf.c | 37 +++++++++++++++++++ samples/bpf/xdp_meta.bpf.c | 14 ++++--- 9 files changed, 76 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h index d2441c8192919c..a73f500c9be82f 100644 --- a/drivers/net/ethernet/intel/ice/ice.h +++ b/drivers/net/ethernet/intel/ice/ice.h @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -350,6 +351,7 @@ struct ice_vsi { u8 xdp_mapping_mode; /* ICE_MAP_MODE_[CONTIG|SCATTER] */ bool xdp_metadata_support; /* true if VSI should support xdp meta */ + s32 btf_id; /* setup back reference, to which aggregator node this VSI * corresponds to diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index 50a3b9adc1d447..e81f2944b1ab80 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -2423,11 +2423,15 @@ static void ice_xdp_rings_set_metadata(struct ice_vsi *vsi) { int i; - ice_for_each_rxq(vsi, i) + ice_for_each_rxq(vsi, i) { vsi->rx_rings[i]->xdp_metadata_support = vsi->xdp_metadata_support; + vsi->rx_rings[i]->btf_id = vsi->btf_id; + } - for (i = 0; i < vsi->num_xdp_txq; i++) + for (i = 0; i < vsi->num_xdp_txq; i++) { vsi->xdp_rings[i]->xdp_metadata_support = vsi->xdp_metadata_support; + vsi->xdp_rings[i]->btf_id = vsi->btf_id; + } } /** @@ -2646,8 +2650,10 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog, } } - if (flags & XDP_FLAGS_USE_METADATA) + if (flags & XDP_FLAGS_USE_METADATA) { vsi->xdp_metadata_support = true; + vsi->btf_id = btf_get_type_id(THIS_MODULE, "xdp_meta_generic", BTF_KIND_STRUCT); + } if (!ice_is_xdp_ena_vsi(vsi) && prog) { vsi->num_xdp_txq = vsi->alloc_rxq; diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c index 128fd49383439a..f52ab7b2e3258f 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx.c +++ b/drivers/net/ethernet/intel/ice/ice_txrx.c @@ -1137,7 +1137,8 @@ int ice_clean_rx_irq(struct ice_ring *rx_ring, int budget) xdp_prepare_buff(&xdp, hard_start, offset, size, true); if (likely(rx_ring->xdp_metadata_support)) - ice_xdp_set_meta(&xdp, rx_desc); + ice_xdp_set_meta(&xdp, rx_desc, rx_ring->btf_id); + #if (PAGE_SIZE > 4096) /* At larger PAGE_SIZE, frame_sz depend on len size */ xdp.frame_sz = ice_rx_frame_truesize(rx_ring, size); diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.h b/drivers/net/ethernet/intel/ice/ice_txrx.h index b43923ddf883cf..9419d4780acc1b 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx.h +++ b/drivers/net/ethernet/intel/ice/ice_txrx.h @@ -302,6 +302,7 @@ struct ice_ring { /* CL3 - 3rd cacheline starts here */ struct xdp_rxq_info xdp_rxq; struct sk_buff *skb; + s32 btf_id; /* CLX - the below items are only accessed infrequently and should be diff --git a/drivers/net/ethernet/intel/ice/ice_txrx_lib.h b/drivers/net/ethernet/intel/ice/ice_txrx_lib.h index d77bc7686b61bd..54c8acab1691b0 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx_lib.h +++ b/drivers/net/ethernet/intel/ice/ice_txrx_lib.h @@ -46,14 +46,24 @@ static inline void ice_xdp_ring_update_tail(struct ice_ring *xdp_ring) writel_relaxed(xdp_ring->next_to_use, xdp_ring->tail); } -static inline void ice_xdp_set_meta(struct xdp_buff *xdp, union ice_32b_rx_flex_desc *desc) +static inline void ice_xdp_set_meta(struct xdp_buff *xdp, union ice_32b_rx_flex_desc *desc, s32 btf_id) { 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); - xdp->data_meta = md; md->rxcvid = le16_to_cpu(flex->flex_ts.flex.vlan_id); md->hash = le32_to_cpu(flex->rss_hash); + + md->flags = 0; + md->free_slot = 0; + md->csum_off = 0; + md->txcvid = 0; + md->csum = 0; + md->tstamp = 0; + + md->btf_id = btf_id; + + xdp->data_meta = md; } void ice_finalize_xdp_rx(struct ice_ring *rx_ring, unsigned int xdp_res); diff --git a/include/linux/btf.h b/include/linux/btf.h index 214fde93214b97..cd26d037a2dda5 100644 --- a/include/linux/btf.h +++ b/include/linux/btf.h @@ -94,6 +94,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); +s32 btf_get_type_id(const struct module *mod, char *name, u32 kind); 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, diff --git a/include/net/xdp.h b/include/net/xdp.h index 9c4d3c9ddc7de9..06d7012b438341 100644 --- a/include/net/xdp.h +++ b/include/net/xdp.h @@ -77,6 +77,9 @@ struct xdp_buff { }; struct xdp_meta_generic { + // BTF ID + u32 btf_id; + // Tx part u32 flags; u16 free_slot; @@ -88,9 +91,6 @@ struct xdp_meta_generic { u32 csum; u32 hash; u64 tstamp; - - // BTF ID - u32 btf_id; } __packed __aligned(8); static_assert(sizeof(struct xdp_meta_generic) == 32); diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index dfe61df4f974d1..10fd0405fec9da 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -6152,6 +6152,43 @@ struct module *btf_try_get_module(const struct btf *btf) return res; } +struct btf *btf_get_from_module(const struct module *module) +{ + struct btf *res = NULL; +#ifdef CONFIG_DEBUG_INFO_BTF_MODULES + struct btf_module *btf_mod, *tmp; + + mutex_lock(&btf_module_mutex); + list_for_each_entry_safe(btf_mod, tmp, &btf_modules, list) { + if (btf_mod->module != module) + continue; + + res = btf_mod->btf; + + break; + } + mutex_unlock(&btf_module_mutex); +#endif + + return res; +} + +s32 btf_get_type_id(const struct module *mod, char *name, u32 kind) +{ + struct btf *btf; + + if (mod) + btf = btf_get_from_module(mod); + else + btf = bpf_get_btf_vmlinux(); + + if (!btf) + return 0; + + return btf_find_by_name_kind(btf, name, kind); +} +EXPORT_SYMBOL_GPL(btf_get_type_id); + BPF_CALL_4(bpf_btf_find_by_name_kind, char *, name, int, name_sz, u32, kind, int, flags) { struct btf *btf; diff --git a/samples/bpf/xdp_meta.bpf.c b/samples/bpf/xdp_meta.bpf.c index 8f49b11ab160a6..2781926cffd2ed 100644 --- a/samples/bpf/xdp_meta.bpf.c +++ b/samples/bpf/xdp_meta.bpf.c @@ -8,17 +8,18 @@ #include #include -struct xdp_meta_generic___empty { - u32 btf_id; +struct xdp_meta_generic___btf { + u32 btf_id; }; SEC("xdp") int xdp_meta_prog(struct xdp_md *ctx) { - struct xdp_meta_generic___empty *data_meta = + struct xdp_meta_generic___btf *data_meta = (void *)(long)ctx->data_meta; void *data_end = (void *)(long)ctx->data_end; void *data = (void *)(long)ctx->data; + u32 *btf_id = (void *)((long)ctx->data - 4); struct ethhdr *eth = data; u64 nh_off; int id; @@ -31,8 +32,11 @@ int xdp_meta_prog(struct xdp_md *ctx) if (data_meta + 1 > data) return XDP_DROP; - id = bpf_core_type_id_kernel(struct xdp_meta_generic___empty); - bpf_printk("id is %d\n", id); + id = bpf_core_type_id_kernel(struct xdp_meta_generic___btf); + bpf_printk("id from libbpf %d, id from hints metadata %d\n", id, data_meta->btf_id); + + if (id && id == data_meta->btf_id) + bpf_printk("hints match btf_id\n"); return XDP_PASS; }