From: Arthur <arthur@xxxxxxxxxxxxxxx> Date: Wed, 05 Mar 2025 15:32:04 +0100 > From: Arthur Fabre <afabre@xxxxxxxxxxxxxx> > > xdp_buff stores whether metadata is supported by a NIC by setting > data_meta to be greater than data. > > But xdp_frame only stores the metadata size (as metasize), so converting > between xdp_frame and xdp_buff is lossy. > > Steal an unused bit in xdp_frame to track whether metadata is supported > or not. > > This will lets us have "generic" functions for setting skb fields from > either xdp_frame or xdp_buff from drivers. > > Signed-off-by: Arthur Fabre <afabre@xxxxxxxxxxxxxx> > --- > include/net/xdp.h | 10 +++++++++- > 1 file changed, 9 insertions(+), 1 deletion(-) > > diff --git a/include/net/xdp.h b/include/net/xdp.h > index 58019fa299b56dbd45c104fdfa807f73af6e4fa4..84afe07d09efdb2ab0cb78b904f02cb74f9a56b6 100644 > --- a/include/net/xdp.h > +++ b/include/net/xdp.h > @@ -116,6 +116,9 @@ static __always_inline void xdp_buff_set_frag_pfmemalloc(struct xdp_buff *xdp) > xdp->flags |= XDP_FLAGS_FRAGS_PF_MEMALLOC; > } > > +static bool xdp_data_meta_unsupported(const struct xdp_buff *xdp); > +static void xdp_set_data_meta_invalid(struct xdp_buff *xdp); > + > static __always_inline void *xdp_buff_traits(const struct xdp_buff *xdp) > { > return xdp->data_hard_start + _XDP_FRAME_SIZE; > @@ -270,7 +273,9 @@ struct xdp_frame { > void *data; > u32 len; > u32 headroom; > - u32 metasize; /* uses lower 8-bits */ > + u32 :23, /* unused */ > + meta_unsupported:1, > + metasize:8; See the history of this structure how we got rid of using bitfields here and why. ...because of performance. Even though metasize uses only 8 bits, 1-byte access is slower than 32-byte access. I was going to write "you can use the fact that metasize is always a multiple of 4 or that it's never > 252, for example, you could reuse LSB as a flag indicating that meta is not supported", but first of all Do we still have drivers which don't support metadata? Why don't they do that? It's not HW-specific or even driver-specific. They don't reserve headroom? Then they're invalid, at least XDP_REDIRECT won't work. So maybe we need to fix those drivers first, if there are any. > /* Lifetime of xdp_rxq_info is limited to NAPI/enqueue time, > * while mem_type is valid on remote CPU. > */ > @@ -369,6 +374,8 @@ void xdp_convert_frame_to_buff(const struct xdp_frame *frame, > xdp->data = frame->data; > xdp->data_end = frame->data + frame->len; > xdp->data_meta = frame->data - frame->metasize; > + if (frame->meta_unsupported) > + xdp_set_data_meta_invalid(xdp); > xdp->frame_sz = frame->frame_sz; > xdp->flags = frame->flags; > } > @@ -396,6 +403,7 @@ int xdp_update_frame_from_buff(const struct xdp_buff *xdp, > xdp_frame->len = xdp->data_end - xdp->data; > xdp_frame->headroom = headroom - sizeof(*xdp_frame); > xdp_frame->metasize = metasize; > + xdp_frame->meta_unsupported = xdp_data_meta_unsupported(xdp); > xdp_frame->frame_sz = xdp->frame_sz; > xdp_frame->flags = xdp->flags; Thanks, Olek