Skip to content

Commit

Permalink
btf: ice: implement finding BTF type id
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Michal Swiatkowski <[email protected]>
  • Loading branch information
mswiatko committed Sep 23, 2021
1 parent f1a04d2 commit 36335fe
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 14 deletions.
2 changes: 2 additions & 0 deletions drivers/net/ethernet/intel/ice/ice.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <linux/avf/virtchnl.h>
#include <linux/cpu_rmap.h>
#include <linux/dim.h>
#include <linux/btf.h>
#include <net/devlink.h>
#include <net/ipv6.h>
#include <net/xdp_sock.h>
Expand Down Expand Up @@ -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
Expand Down
12 changes: 9 additions & 3 deletions drivers/net/ethernet/intel/ice/ice_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

/**
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/ethernet/intel/ice/ice_txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/ice/ice_txrx.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 12 additions & 2 deletions drivers/net/ethernet/intel/ice/ice_txrx_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions include/linux/btf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 3 additions & 3 deletions include/net/xdp.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ struct xdp_buff {
};

struct xdp_meta_generic {
// BTF ID
u32 btf_id;

// Tx part
u32 flags;
u16 free_slot;
Expand All @@ -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);

Expand Down
37 changes: 37 additions & 0 deletions kernel/bpf/btf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
14 changes: 9 additions & 5 deletions samples/bpf/xdp_meta.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,18 @@
#include <bpf/bpf_core_read.h>
#include <bpf/bpf_helpers.h>

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;
Expand All @@ -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;
}
Expand Down

0 comments on commit 36335fe

Please sign in to comment.