From: "Alexei Starovoitov" <alexei.starovoitov@gmail.com>
To: "Tianyi Gao" <tianyi@cloudflare.com>, <bpf@vger.kernel.org>,
<netdev@vger.kernel.org>,
"Daniel Borkmann" <daniel@iogearbox.net>,
"Andrii Nakryiko" <andrii@kernel.org>,
"Martin KaFai Lau" <martin.lau@linux.dev>,
"Jakub Kicinski" <kuba@kernel.org>,
"Jesper Dangaard Brouer" <hawk@kernel.org>
Cc: "John Fastabend" <john.fastabend@gmail.com>,
"Stanislav Fomichev" <sdf@fomichev.me>,
"Lorenzo Bianconi" <lorenzo@kernel.org>,
"Vladimir Vdovin" <deliran@verdict.gg>,
"David S. Miller" <davem@davemloft.net>,
"Eric Dumazet" <edumazet@kernel.org>,
"Paolo Abeni" <pabeni@redhat.com>,
"Simon Horman" <horms@kernel.org>,
"Andrew Lunn" <andrew+netdev@lunn.ch>,
"Donald Hunter" <donald.hunter@gmail.com>,
"Eduard Zingerman" <eddyz87@gmail.com>,
"Kumar Kartikeya Dwivedi" <memxor@gmail.com>,
"Song Liu" <song@kernel.org>,
"Yonghong Song" <yonghong.song@linux.dev>,
"Jiri Olsa" <jolsa@kernel.org>,
"Emil Tsalapatis" <emil@etsalapatis.com>,
"Ihor Solodrai" <ihor.solodrai@linux.dev>,
"Tony Nguyen" <anthony.l.nguyen@intel.com>,
"Przemek Kitszel" <przemyslaw.kitszel@intel.com>,
"Maciej Fijalkowski" <maciej.fijalkowski@intel.com>,
"Alexander Lobakin" <aleksander.lobakin@intel.com>,
"Magnus Karlsson" <magnus.karlsson@intel.com>,
"Tushar Vyavahare" <tushar.vyavahare@intel.com>,
"Jason Xing" <kerneljasonxing@gmail.com>,
"Nikolay Aleksandrov" <razor@blackwall.org>,
"Madalin Bucur" <madalin.bucur@nxp.com>,
"Ioana Ciornei" <ioana.ciornei@nxp.com>,
"Jonathan Corbet" <corbet@lwn.net>,
"Shuah Khan" <skhan@linuxfoundation.org>,
"Shuah Khan" <shuah@kernel.org>,
"Randy Dunlap" <rdunlap@infradead.org>,
"Nathan Chancellor" <nathan@kernel.org>,
"Nick Desaulniers" <ndesaulniers@google.com>,
"Bill Wendling" <morbo@google.com>,
"Justin Stitt" <justinstitt@google.com>,
"Chris J Arges" <carges@cloudflare.com>,
"Jakub Sitnicki" <jakub@cloudflare.com>,
<linux-doc@vger.kernel.org>, <linux-kselftest@vger.kernel.org>,
<intel-wired-lan@lists.osuosl.org>, <llvm@lists.linux.dev>,
<kernel-team@cloudflare.com>
Subject: Re: [PATCH bpf-next 00/15] xdp: add SKB core extensions to keep RX metadata until skb creation
Date: Thu, 12 Nov 2026 00:34:54 +0000 [thread overview]
Message-ID: <DMST78XBB2RK.2BKP3O07GEWZQ@gmail.com> (raw)
In-Reply-To: <cover.1794281983.git.tianyi@cloudflare.com>
On Mon, Nov 09, 2026 at 07:56 PM Tianyi Gao <tianyi@cloudflare.com> wrote:
> The layout of the area follows skb extensions (struct skb_ext). A small
> header gives the offset of each entry. An entry takes headroom only when
> the program stores it, so the area does not grow with each new type of
> RX metadata, unlike [4]. Unlike skb_ext, the area needs no allocation.
I'm with Stan on this. It looks heavy.
How about the following idea:
diff --git a/include/net/xdp.h b/include/net/xdp.h
index 07231ad..7f30d24 100644
--- a/include/net/xdp.h
+++ b/include/net/xdp.h
@@ -81,8 +81,15 @@ enum xdp_buff_flags {
* XDP program is not attached.
*/
XDP_FLAGS_FRAGS_UNREADABLE = BIT(2),
+ /* The prog stored these members of struct xdp_rx_meta */
+ XDP_FLAGS_RX_HASH = BIT(3),
+ XDP_FLAGS_RX_VLAN = BIT(4),
+ XDP_FLAGS_RX_CSUM = BIT(5),
};
+#define XDP_FLAGS_RX_META \
+ (XDP_FLAGS_RX_HASH | XDP_FLAGS_RX_VLAN | XDP_FLAGS_RX_CSUM)
+
struct xdp_buff {
void *data;
void *data_end;
@@ -174,6 +181,7 @@ xdp_prepare_buff(struct xdp_buff *xdp, unsigned char *hard_start,
xdp->data = data;
xdp->data_end = data + data_len;
xdp->data_meta = meta_valid ? data : data + 1;
+ xdp->flags &= ~XDP_FLAGS_RX_META;
}
/* Reserve memory area at end-of data area.
@@ -310,6 +318,48 @@ struct xdp_frame {
u32 flags; /* supported values defined in xdp_buff_flags */
};
+/*
+ * RX metadata that an XDP prog stores for the skb that is built later.
+ * It follows the xdp_frame in the headroom. The headroom is taken only
+ * when one of XDP_FLAGS_RX_META is set.
+ */
+struct xdp_rx_meta {
+ u32 hash;
+ __be16 vlan_proto;
+ u16 vlan_tci;
+ u8 hash_type; /* enum pkt_hash_types */
+ u8 ip_summed;
+ u8 csum_level;
+};
+
+static __always_inline struct xdp_rx_meta *xdp_rx_meta(void *data_hard_start)
+{
+ return data_hard_start + sizeof(struct xdp_frame);
+}
+
+/* The lowest address that the packet and data_meta can use */
+static __always_inline void *xdp_buff_headroom_start(const struct xdp_buff *xdp)
+{
+ struct xdp_rx_meta *meta = xdp_rx_meta(xdp->data_hard_start);
+
+ return xdp->flags & XDP_FLAGS_RX_META ? meta + 1 : meta;
+}
+
+void __xdp_rx_meta_to_skb(struct sk_buff *skb, const struct xdp_rx_meta *meta,
+ u32 flags);
+
+/*
+ * A driver calls it on XDP_PASS after it sets the skb fields from
+ * the RX descriptor.
+ */
+static inline void xdp_buff_rx_meta_to_skb(const struct xdp_buff *xdp,
+ struct sk_buff *skb)
+{
+ if (unlikely(xdp->flags & XDP_FLAGS_RX_META))
+ __xdp_rx_meta_to_skb(skb, xdp_rx_meta(xdp->data_hard_start),
+ xdp->flags);
+}
+
static __always_inline bool xdp_frame_has_frags(const struct xdp_frame *frame)
{
return !!(frame->flags & XDP_FLAGS_HAS_FRAGS);
@@ -648,6 +698,12 @@ enum xdp_rss_hash_type {
XDP_RSS_TYPE_L4_IPV6_SCTP_EX = XDP_RSS_TYPE_L4_IPV6_SCTP | XDP_RSS_L3_DYNHDR,
};
+enum xdp_checksum {
+ XDP_CHECKSUM_NONE = BIT(CHECKSUM_NONE),
+ XDP_CHECKSUM_UNNECESSARY = BIT(CHECKSUM_UNNECESSARY),
+ XDP_CHECKSUM_COMPLETE = BIT(CHECKSUM_COMPLETE),
+};
+
struct xdp_metadata_ops {
int (*xmo_rx_timestamp)(const struct xdp_md *ctx, u64 *timestamp);
int (*xmo_rx_hash)(const struct xdp_md *ctx, u32 *hash,
diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
index d6c9dc6..f255818 100644
--- a/net/bpf/test_run.c
+++ b/net/bpf/test_run.c
@@ -223,7 +223,8 @@ static bool ctx_was_changed(struct xdp_page_head *head)
{
return head->orig_ctx.data != head->ctx.data ||
head->orig_ctx.data_meta != head->ctx.data_meta ||
- head->orig_ctx.data_end != head->ctx.data_end;
+ head->orig_ctx.data_end != head->ctx.data_end ||
+ head->orig_ctx.flags != head->ctx.flags;
}
static void reset_ctx(struct xdp_page_head *head)
@@ -234,6 +235,7 @@ static void reset_ctx(struct xdp_page_head *head)
head->ctx.data = head->orig_ctx.data;
head->ctx.data_meta = head->orig_ctx.data_meta;
head->ctx.data_end = head->orig_ctx.data_end;
+ head->ctx.flags = head->orig_ctx.flags;
xdp_update_frame_from_buff(&head->ctx, head->frame);
head->frame->mem_type = head->orig_ctx.rxq->mem.type;
}
diff --git a/net/core/filter.c b/net/core/filter.c
index 9245009..efbe293 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -4243,9 +4243,8 @@ static unsigned long xdp_get_metalen(const struct xdp_buff *xdp)
BPF_CALL_2(bpf_xdp_adjust_head, struct xdp_buff *, xdp, int, offset)
{
- void *xdp_frame_end = xdp->data_hard_start + sizeof(struct xdp_frame);
unsigned long metalen = xdp_get_metalen(xdp);
- void *data_start = xdp_frame_end + metalen;
+ void *data_start = xdp_buff_headroom_start(xdp) + metalen;
void *data = xdp->data + offset;
if (unlikely(data < data_start ||
@@ -4547,13 +4546,12 @@ static const struct bpf_func_proto bpf_xdp_adjust_tail_proto = {
BPF_CALL_2(bpf_xdp_adjust_meta, struct xdp_buff *, xdp, int, offset)
{
- void *xdp_frame_end = xdp->data_hard_start + sizeof(struct xdp_frame);
void *meta = xdp->data_meta + offset;
unsigned long metalen = xdp->data - meta;
if (xdp_data_meta_unsupported(xdp))
return -ENOTSUPP;
- if (unlikely(meta < xdp_frame_end ||
+ if (unlikely(meta < xdp_buff_headroom_start(xdp) ||
meta > xdp->data))
return -EINVAL;
if (unlikely(xdp_metalen_invalid(metalen)))
@@ -12794,7 +12792,7 @@ __bpf_kfunc int bpf_xdp_pull_data(struct xdp_md *x, u32 len)
start = xdp_data_meta_unsupported(xdp) ? xdp->data : xdp->data_meta;
- headroom = start - xdp->data_hard_start - sizeof(struct xdp_frame);
+ headroom = start - xdp_buff_headroom_start(xdp);
tailroom = data_hard_end - xdp->data_end;
delta = len - data_len;
diff --git a/net/core/xdp.c b/net/core/xdp.c
index 1d679e8..ca17609 100644
--- a/net/core/xdp.c
+++ b/net/core/xdp.c
@@ -829,10 +829,10 @@ struct sk_buff *__xdp_build_skb_from_frame(struct xdp_frame *xdpf,
/* Essential SKB info: protocol and skb->dev */
skb->protocol = eth_type_trans(skb, dev);
+ if (xdpf->flags & XDP_FLAGS_RX_META)
+ __xdp_rx_meta_to_skb(skb, xdp_rx_meta(xdpf), xdpf->flags);
/* Optional SKB info, currently missing:
- * - HW checksum info (skb->ip_summed)
- * - HW RX hash (skb_set_hash)
* - RX ring dev queue index (skb_record_rx_queue)
*/
@@ -857,6 +857,9 @@ struct sk_buff *xdp_build_skb_from_frame(struct xdp_frame *xdpf,
memset(skb, 0, offsetof(struct sk_buff, tail));
+ /* The callers set the RX fields themselves or transmit the skb */
+ xdpf->flags &= ~XDP_FLAGS_RX_META;
+
return __xdp_build_skb_from_frame(xdpf, skb, dev);
}
EXPORT_SYMBOL_GPL(xdp_build_skb_from_frame);
@@ -990,9 +993,154 @@ bool bpf_dev_bound_kfunc_id(u32 btf_id)
return btf_id_set8_contains(&xdp_metadata_kfunc_ids, btf_id);
}
+void __xdp_rx_meta_to_skb(struct sk_buff *skb, const struct xdp_rx_meta *meta,
+ u32 flags)
+{
+ if (flags & XDP_FLAGS_RX_HASH)
+ skb_set_hash(skb, meta->hash, meta->hash_type);
+ if (flags & XDP_FLAGS_RX_VLAN)
+ __vlan_hwaccel_put_tag(skb, meta->vlan_proto, meta->vlan_tci);
+ if (flags & XDP_FLAGS_RX_CSUM) {
+ skb->ip_summed = meta->ip_summed;
+ skb->csum_level = meta->csum_level;
+ }
+}
+EXPORT_SYMBOL_GPL(__xdp_rx_meta_to_skb);
+
+static struct xdp_rx_meta *xdp_rx_meta_reserve(const struct xdp_buff *xdp)
+{
+ struct xdp_rx_meta *meta = xdp_rx_meta(xdp->data_hard_start);
+ void *start = xdp_data_meta_unsupported(xdp) ? xdp->data : xdp->data_meta;
+
+ /* User space can write the headroom of AF_XDP zero-copy buffers */
+ if (xdp->rxq->mem.type == MEM_TYPE_XSK_BUFF_POOL)
+ return ERR_PTR(-EOPNOTSUPP);
+ if ((void *)(meta + 1) > start)
+ return ERR_PTR(-ENOSPC);
+ return meta;
+}
+
+__bpf_kfunc_start_defs();
+
+/**
+ * bpf_xdp_store_rx_hash - Store the RX hash for the skb of this packet.
+ * @ctx: XDP context pointer.
+ * @hash: RX hash value.
+ * @rss_type: RSS hash type, see &enum xdp_rss_hash_type.
+ *
+ * Return:
+ * * Returns 0 on success or ``-errno`` on error.
+ * * ``-ENOSPC`` : not enough headroom
+ * * ``-EOPNOTSUPP`` : AF_XDP zero-copy buffer
+ */
+__bpf_kfunc int bpf_xdp_store_rx_hash(struct xdp_md *ctx, u32 hash,
+ enum xdp_rss_hash_type rss_type)
+{
+ struct xdp_buff *xdp = (struct xdp_buff *)ctx;
+ struct xdp_rx_meta *meta = xdp_rx_meta_reserve(xdp);
+
+ if (IS_ERR(meta))
+ return PTR_ERR(meta);
+
+ meta->hash = hash;
+ if (rss_type & XDP_RSS_L4)
+ meta->hash_type = PKT_HASH_TYPE_L4;
+ else if (rss_type & (XDP_RSS_L3_IPV4 | XDP_RSS_L3_IPV6))
+ meta->hash_type = PKT_HASH_TYPE_L3;
+ else
+ meta->hash_type = PKT_HASH_TYPE_NONE;
+ xdp->flags |= XDP_FLAGS_RX_HASH;
+
+ return 0;
+}
+
+/**
+ * bpf_xdp_store_rx_vlan_tag - Store the VLAN tag for the skb of this packet.
+ * @ctx: XDP context pointer.
+ * @vlan_proto: VLAN tag protocol identifier (TPID), in network byte order.
+ * @vlan_tci: VLAN TCI, in host byte order.
+ *
+ * Return:
+ * * Returns 0 on success or ``-errno`` on error.
+ * * ``-EINVAL`` : @vlan_proto is not 802.1Q or 802.1AD
+ * * ``-ENOSPC`` : not enough headroom
+ * * ``-EOPNOTSUPP`` : AF_XDP zero-copy buffer
+ */
+__bpf_kfunc int bpf_xdp_store_rx_vlan_tag(struct xdp_md *ctx, __be16 vlan_proto,
+ u16 vlan_tci)
+{
+ struct xdp_buff *xdp = (struct xdp_buff *)ctx;
+ struct xdp_rx_meta *meta = xdp_rx_meta_reserve(xdp);
+
+ if (IS_ERR(meta))
+ return PTR_ERR(meta);
+ if (vlan_proto != htons(ETH_P_8021Q) &&
+ vlan_proto != htons(ETH_P_8021AD))
+ return -EINVAL;
+
+ meta->vlan_proto = vlan_proto;
+ meta->vlan_tci = vlan_tci;
+ xdp->flags |= XDP_FLAGS_RX_VLAN;
+
+ return 0;
+}
+
+/**
+ * bpf_xdp_store_rx_csum - Store the checksum status for the skb of this packet.
+ * @ctx: XDP context pointer.
+ * @ip_summed: ``XDP_CHECKSUM_NONE`` or ``XDP_CHECKSUM_UNNECESSARY``.
+ * @csum_level: Number of consecutive verified checksums minus one, up to
+ * ``SKB_MAX_CSUM_LEVEL``. Must be 0 with ``XDP_CHECKSUM_NONE``.
+ *
+ * Return:
+ * * Returns 0 on success or ``-errno`` on error.
+ * * ``-EINVAL`` : @ip_summed is not supported, or @csum_level is not valid
+ * for it
+ * * ``-ENOSPC`` : not enough headroom
+ * * ``-EOPNOTSUPP`` : AF_XDP zero-copy buffer
+ */
+__bpf_kfunc int bpf_xdp_store_rx_csum(struct xdp_md *ctx,
+ enum xdp_checksum ip_summed,
+ u8 csum_level)
+{
+ struct xdp_buff *xdp = (struct xdp_buff *)ctx;
+ struct xdp_rx_meta *meta = xdp_rx_meta_reserve(xdp);
+
+ if (IS_ERR(meta))
+ return PTR_ERR(meta);
+ if (ip_summed == XDP_CHECKSUM_NONE && !csum_level)
+ meta->ip_summed = CHECKSUM_NONE;
+ else if (ip_summed == XDP_CHECKSUM_UNNECESSARY &&
+ csum_level <= SKB_MAX_CSUM_LEVEL)
+ meta->ip_summed = CHECKSUM_UNNECESSARY;
+ else
+ return -EINVAL;
+
+ meta->csum_level = csum_level;
+ xdp->flags |= XDP_FLAGS_RX_CSUM;
+
+ return 0;
+}
+
+__bpf_kfunc_end_defs();
+
+BTF_KFUNCS_START(xdp_rx_meta_kfunc_ids)
+BTF_ID_FLAGS(func, bpf_xdp_store_rx_hash)
+BTF_ID_FLAGS(func, bpf_xdp_store_rx_vlan_tag)
+BTF_ID_FLAGS(func, bpf_xdp_store_rx_csum)
+BTF_KFUNCS_END(xdp_rx_meta_kfunc_ids)
+
+static const struct btf_kfunc_id_set xdp_rx_meta_kfunc_set = {
+ .owner = THIS_MODULE,
+ .set = &xdp_rx_meta_kfunc_ids,
+};
+
static int __init xdp_metadata_init(void)
{
- return register_btf_kfunc_id_set(BPF_PROG_TYPE_XDP, &xdp_metadata_kfunc_set);
+ int ret;
+
+ ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_XDP, &xdp_rx_meta_kfunc_set);
+ return ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_XDP, &xdp_metadata_kfunc_set);
}
late_initcall(xdp_metadata_init);
next prev parent reply other threads:[~2026-11-12 0:34 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-10 3:56 [PATCH bpf-next 00/15] xdp: add SKB core extensions to keep RX metadata until skb creation Tianyi Gao
2026-11-10 3:56 ` [PATCH bpf-next 01/15] xdp: reserve an skb core extension area after the xdp_frame Tianyi Gao
2026-11-10 4:18 ` sashiko-bot
2026-11-10 4:42 ` Tianyi Gao
2026-11-10 13:10 ` Jesper Dangaard Brouer
2026-11-10 3:57 ` [PATCH bpf-next 02/15] net: dpaa, dpaa2: clear the skb core extension flag Tianyi Gao
2026-11-10 3:57 ` [PATCH bpf-next 03/15] xdp: add kfuncs to store RX hash and VLAN tag Tianyi Gao
2026-11-10 14:13 ` Jesper Dangaard Brouer
2026-11-10 3:57 ` [PATCH bpf-next 04/15] xdp: add a kfunc to delete skb core extension entries Tianyi Gao
2026-11-10 14:20 ` Jesper Dangaard Brouer
2026-11-10 3:57 ` [PATCH bpf-next 05/15] xdp: add a kfunc to store the RX checksum status Tianyi Gao
2026-11-10 3:57 ` [PATCH bpf-next 06/15] selftests/bpf: Test the skb core extension kfuncs Tianyi Gao
2026-11-10 3:57 ` [PATCH bpf-next 07/15] xdp: set skb RX metadata from the skb core extension area of xdp_frame Tianyi Gao
2026-11-10 3:57 ` [PATCH bpf-next 08/15] selftests/bpf: Test RX metadata on skbs built from xdp_frames Tianyi Gao
2026-11-10 3:57 ` [PATCH bpf-next 09/15] xdp: add the skb-ext-pass XDP feature and warn without it Tianyi Gao
2026-11-10 3:57 ` [PATCH bpf-next 10/15] xdp: warn on XDP_PASS with stored values when XDP runs on an skb Tianyi Gao
2026-11-10 4:10 ` sashiko-bot
2026-11-10 4:57 ` Tianyi Gao
2026-11-10 4:53 ` bot+bpf-ci
2026-11-10 4:53 ` bot+bpf-ci
2026-11-10 3:57 ` [PATCH bpf-next 11/15] ice: set skb RX metadata from the skb core extension area of xdp_buff Tianyi Gao
2026-11-10 4:23 ` sashiko-bot
2026-11-10 3:57 ` [PATCH bpf-next 12/15] selftests: drv-net: xdp: test the stored RX metadata on XDP_PASS Tianyi Gao
2026-11-10 3:57 ` [PATCH bpf-next 13/15] xdp: add kfuncs to load the stored RX metadata Tianyi Gao
2026-11-10 3:57 ` [PATCH bpf-next 14/15] selftests/bpf: Test the load kfuncs on cpumap and veth Tianyi Gao
2026-11-10 3:57 ` [PATCH bpf-next 15/15] docs: net: document the skb core extension area Tianyi Gao
2026-11-10 4:53 ` bot+bpf-ci
2026-11-10 4:53 ` bot+bpf-ci
2026-11-10 13:01 ` [PATCH bpf-next 00/15] xdp: add SKB core extensions to keep RX metadata until skb creation Jesper Dangaard Brouer
2026-11-11 0:00 ` Stanislav Fomichev
2026-11-11 1:07 ` Tianyi Gao
2026-11-11 22:25 ` Stanislav Fomichev
2026-11-11 23:46 ` Tianyi Gao
2026-11-12 0:34 ` Alexei Starovoitov [this message]
2026-11-12 14:55 ` Tianyi Gao
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=DMST78XBB2RK.2BKP3O07GEWZQ@gmail.com \
--to=alexei.starovoitov@gmail.com \
--cc=aleksander.lobakin@intel.com \
--cc=andrew+netdev@lunn.ch \
--cc=andrii@kernel.org \
--cc=anthony.l.nguyen@intel.com \
--cc=bpf@vger.kernel.org \
--cc=carges@cloudflare.com \
--cc=corbet@lwn.net \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=deliran@verdict.gg \
--cc=donald.hunter@gmail.com \
--cc=eddyz87@gmail.com \
--cc=edumazet@kernel.org \
--cc=emil@etsalapatis.com \
--cc=hawk@kernel.org \
--cc=horms@kernel.org \
--cc=ihor.solodrai@linux.dev \
--cc=intel-wired-lan@lists.osuosl.org \
--cc=ioana.ciornei@nxp.com \
--cc=jakub@cloudflare.com \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=justinstitt@google.com \
--cc=kernel-team@cloudflare.com \
--cc=kerneljasonxing@gmail.com \
--cc=kuba@kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=llvm@lists.linux.dev \
--cc=lorenzo@kernel.org \
--cc=maciej.fijalkowski@intel.com \
--cc=madalin.bucur@nxp.com \
--cc=magnus.karlsson@intel.com \
--cc=martin.lau@linux.dev \
--cc=memxor@gmail.com \
--cc=morbo@google.com \
--cc=nathan@kernel.org \
--cc=ndesaulniers@google.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=przemyslaw.kitszel@intel.com \
--cc=razor@blackwall.org \
--cc=rdunlap@infradead.org \
--cc=sdf@fomichev.me \
--cc=shuah@kernel.org \
--cc=skhan@linuxfoundation.org \
--cc=song@kernel.org \
--cc=tianyi@cloudflare.com \
--cc=tushar.vyavahare@intel.com \
--cc=yonghong.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.