All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Taehee Yoo" <ap420073@gmail.com>
Cc: dri-devel@lists.freedesktop.org, media-ci@linuxtv.org,
	bpf@vger.kernel.org
Subject: Re: [RFC PATCH net-next 01/13] net: knod: add uapi and core headers
Date: Tue, 21 Jul 2026 07:17:54 +0000	[thread overview]
Message-ID: <20260721071755.3A53E1F00A3D@smtp.kernel.org> (raw)
In-Reply-To: <20260719175857.4071636-2-ap420073@gmail.com>

Thank you for your contribution! Sashiko AI review found 7 potential issue(s) to consider:
- [High] Broken lock-free API: `spsc_push` and `spsc_pop` introduce data races.
- [High] Use-After-Free in `knod_napi_kick()` due to lifecycle mismatch with standard NAPI teardown.
- [High] NULL pointer dereference in inline helpers when no accelerator is attached.
- [High] `spsc_acquire()` lacks a Write Memory Barrier (`wmb()`) before publishing the advanced cursor, risking data corruption on WC memory.
- [Medium] The `attach` Netlink operation violates uAPI design guidelines by missing reply attributes.
- [Medium] Severe false sharing in `struct spsc_ring` due to unpadded producer and consumer cursors.
- [Low] Missing `n` parameter in `for_each_xdev_safe` macro.
--

--- Patch [1]: [RFC PATCH net-next 01/13] net: knod: add uapi and core headers ---
commit 518fe6d810fd2f47140b3bb011b370cf924724ed
Author: Taehee Yoo <ap420073@gmail.com>

net: knod: add uapi and core headers

Add the uAPI and core headers for KNOD, an in-kernel network offload
device that connects a NIC RX path to an accelerator (e.g. a GPU) for
zero-copy packet processing.

> diff --git a/Documentation/netlink/specs/knod.yaml b/Documentation/netlink/specs/knod.yaml
> new file mode 100644
> index 0000000000000..7c64df4676349
> --- /dev/null
> +++ b/Documentation/netlink/specs/knod.yaml
[ ... ]
> @@ -0,0 +1,176 @@
> +# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
> +---
> +name: knod
[ ... ]
> +    -
> +      name: attach
> +      doc: Attach a NIC netdevice to an accelerator.
> +      attribute-set: dev
> +      flags: [admin-perm]
> +      do:
> +        request:
> +          attributes:
> +            - nic-ifindex
> +            - accel-id
> +        reply:
> +          attributes: []

[Severity: Medium]
UAPI design rules state that NEW/ADD operations must reply with a full
message describing the new object. By leaving attributes empty, does this
permanently freeze a broken ABI for userspace applications relying on generic
netlink?

> +    -
> +      name: detach
> +      doc: Detach a NIC netdevice from its accelerator.
> +      attribute-set: dev
[ ... ]
> diff --git a/include/net/knod.h b/include/net/knod.h
> new file mode 100644
> index 0000000000000..50333b0e028b7
> --- /dev/null
> +++ b/include/net/knod.h
[ ... ]
> @@ -0,0 +1,467 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __NET_KNOD_H
> +#define __NET_KNOD_H
[ ... ]
> +struct knod_work_priv {
> +	struct dma_buf *dmabuf;
> +	netmem_ref *netmems;
> +	unsigned int *data_lens;
> +	int *data_offs;
> +	int cnt;
> +	int index;
> +	struct napi_struct *napi;
> +	struct spsc_ring spsc_bds;
> +	void *spsc_pool_priv;	/* accel driver priv for spsc pool memory */
> +	u64 spsc_pool_gaddr;	/* device-visible address of spsc pool */
> +	/* framework-owned delivery pool */
> +	struct page_pool *pass_pool;
> +	/* provider ctx (owner storage) */
> +	struct page_pool_hostmem pass_hm;
> +	/* d2h: SDMA-issued, awaiting drain */
> +	struct spsc_ring pass_pending;
> +} ____cacheline_aligned_in_smp;
> +
> +static inline void knod_napi_kick(struct knod_work_priv *wpriv)
> +{
> +	struct napi_struct *napi;
> +
> +	rcu_read_lock();
> +	napi = READ_ONCE(wpriv->napi);
> +	if (napi)
> +		napi_schedule(napi);
> +	rcu_read_unlock();
> +}

[Severity: High]
Does this RCU lock actually protect the NAPI structure from being freed?
Standard NIC drivers often dismantle and free their queue arrays synchronously
after napi_disable(), without an RCU grace period. Could this lead to a
use-after-free when calling napi_schedule()?

> +
> +#define KNOD_DEFAULT_PASS_SLOTS	64
> +
> +/*
[ ... ]
> +struct knod_dev {
> +	struct list_head list;
> +	struct knod_netdev *knetdev;
> +	struct knod_accel *accel;
[ ... ]
> +};
> +
> +static inline bool knod_dev_active(struct knod_dev *knodev)
> +{
> +	return !!knodev->accel->xdp.xdp_hw.prog;
> +}
> +
> +static inline struct bpf_prog *
> +knod_dev_offloaded(struct knod_dev *knodev)
> +{
> +	return knodev->accel->xdp.bpf_offloaded;
> +}

[Severity: High]
Can knodev->accel be NULL when a NIC is registered but detached from an
accelerator? If so, will these inline helpers unconditionally dereference a
NULL pointer and cause a kernel panic?

> +
> +static inline void knod_dev_offload(struct knod_dev *knodev,
> +					   struct bpf_prog *bpf_offloaded)
[ ... ]
> +extern struct list_head knod_accel_list;
> +
> +#define for_each_xdev(d)         \
> +		list_for_each_entry(d, &knod_dev_list, list)
> +#define for_each_xdev_safe(d)         \
> +		list_for_each_entry_safe(d, n, &knod_dev_list, list)

[Severity: Low]
Is the n parameter missing from the macro signature? Any file using this
macro without a pre-declared local variable n will likely fail to compile.

> +#define for_each_nodev(d)         \
> +		list_for_each_entry(d, &knod_netdev_list, list)
[ ... ]
> diff --git a/include/net/spsc_ring.h b/include/net/spsc_ring.h
> new file mode 100644
> index 0000000000000..1eccadc927d62
> --- /dev/null
> +++ b/include/net/spsc_ring.h
[ ... ]
> @@ -0,0 +1,645 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
[ ... ]
> +struct spsc_ring {
> +	void		**slots;	/* pointer-per-slot into pool */
> +	unsigned int	mask;		/* capacity - 1 */
> +
> +	/* Producer side */
> +	unsigned int	head;		/* next slot to publish */
> +
> +	/* Consumer side */
> +	unsigned int	tail;		/* oldest unconsumed slot */
> +	unsigned int	acquired;	/* sliding window read cursor
> +					 *   tail <= acquired <= head
> +					 */
> +
> +	/* Element pool */
> +	struct page	*pool_page;	/* compound page backing elements */

[Severity: Medium]
Does placing the heavily contended producer cursor (head) and consumer
cursors (tail, acquired) in the same cacheline without padding cause severe
false sharing? This could significantly impact throughput due to continuous
cacheline bouncing.

> +	unsigned int	pool_order;	/* page order */
> +	unsigned int	elem_stride;	/* cacheline-aligned element size */
> +} ____cacheline_aligned_in_smp;
> +
> +/* ================================================================== */
[ ... ]
> +static inline int spsc_acquire(struct spsc_ring *r, void **out,
> +			       unsigned int max, unsigned int *cnt)
> +{
> +	/* acquire the producer's head; slots it published are now visible */
> +	unsigned int head = smp_load_acquire(&r->head);
> +	unsigned int acq = r->acquired;
> +	unsigned int avail;
> +	unsigned int i;
[ ... ]
> +	if (out) {
> +		for (i = 0; i < avail; i++)
> +			out[i] = r->slots[(acq + i) & r->mask];
> +	}
> +
> +	/* Publish the window to the releasing consumer (a different CPU than
> +	 * this acquirer): pair with the smp_load_acquire() in spsc_release()
> +	 * so it cannot observe the advanced cursor before the element stores
> +	 * (e.g. an accel verdict) those slots now point at.
> +	 */
> +	smp_store_release(&r->acquired, acq + avail);

[Severity: High]
On architectures like x86, smp_store_release is only a compiler barrier and
does not flush Write-Combining buffers. Is a wmb() needed here before
publishing the advanced cursor, similar to spsc_produce_commit, to prevent a
concurrent releaser from reading stale memory before the WC stores land?

> +
> +	if (cnt)
> +		*cnt = avail;
> +	return 0;
> +}
> +
> +/**
[ ... ]
> +static inline int spsc_push(struct spsc_ring *r, void **out)
> +{
> +	int ret;
> +
> +	ret = spsc_produce(r, out);
> +	if (ret)
> +		return ret;
> +
> +	spsc_produce_commit(r);
> +	return 0;
> +}

[Severity: High]
Doesn't spsc_produce_commit publish the slot to the consumer immediately? If
the slot is published before the caller writes the data into the pointer
returned in out, could a concurrent consumer read uninitialized data?

> +
> +/**
> + * spsc_pop - dequeue one element
> + * @r:   ring buffer
> + * @out: receives pointer to the consumed element
> + *
> + * The element pointer remains valid until the next spsc_push() or
> + * spsc_produce() reuses that slot.
> + *
> + * Returns 0 on success, -ENOENT if empty.
> + */
> +static inline int spsc_pop(struct spsc_ring *r, void **out)
> +{
> +	/* acquire the producer's head; slots it published are now visible */
> +	unsigned int head = smp_load_acquire(&r->head);
> +	unsigned int tail = r->tail;
> +
> +	if (tail == head)
> +		return -ENOENT;
> +
> +	*out = r->slots[tail & r->mask];
> +
> +	r->acquired = tail + 1;
> +	/* release: hand the consumed slot back to the producer */
> +	smp_store_release(&r->tail, tail + 1);
> +
> +	return 0;
> +}

[Severity: High]
By advancing the tail cursor before returning the element pointer to the
consumer, is the slot made available to the producer too early? A concurrent
producer might overwrite the data while the consumer is actively reading it.

> +
> +/**
> + * spsc_pop_n - dequeue up to @n elements
[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260719175857.4071636-1-ap420073@gmail.com?part=1

  reply	other threads:[~2026-07-21  7:18 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-19 17:58 [RFC PATCH net-next 00/13] net: knod: in-kernel network offload device Taehee Yoo
2026-07-19 17:58 ` [RFC PATCH net-next 01/13] net: knod: add uapi and core headers Taehee Yoo
2026-07-21  7:17   ` sashiko-bot [this message]
2026-07-19 17:58 ` [RFC PATCH net-next 02/13] net: devmem: extend memory provider for knod Taehee Yoo
2026-07-20 19:43   ` Mina Almasry
2026-07-21 16:15     ` Taehee Yoo
2026-07-21  7:17   ` sashiko-bot
2026-07-19 17:58 ` [RFC PATCH net-next 03/13] net: core: add XDP_MODE_HW offload hook " Taehee Yoo
2026-07-21  7:17   ` sashiko-bot
2026-07-19 17:58 ` [RFC PATCH net-next 04/13] net: knod: add offload device core and control plane Taehee Yoo
2026-07-21  7:17   ` sashiko-bot
2026-07-19 17:58 ` [RFC PATCH net-next 05/13] bpf: offload: allow PERCPU_ARRAY maps for offloaded programs Taehee Yoo
2026-07-21  7:17   ` sashiko-bot
2026-07-19 17:58 ` [RFC PATCH net-next 06/13] drm/amdkfd: prepare kfd core for the knod provider Taehee Yoo
2026-07-21  7:17   ` sashiko-bot
2026-07-19 17:58 ` [RFC PATCH net-next 07/13] drm/amdkfd: add knod provider core Taehee Yoo
2026-07-21  7:17   ` sashiko-bot
2026-07-19 17:58 ` [RFC PATCH net-next 08/13] drm/amdkfd: add GPU instruction emitter and disassembler Taehee Yoo
2026-07-20 20:05   ` Natalie Vock
2026-07-20 20:53     ` Andrew Lunn
2026-07-21 16:36       ` Hoyeon Lee
2026-07-19 17:58 ` [RFC PATCH net-next 09/13] drm/amdkfd: add BPF-to-GPU JIT offload Taehee Yoo
2026-07-19 17:58 ` [RFC PATCH net-next 10/13] net/mlx5e: add knod XDP offload support Taehee Yoo
2026-07-21  7:17   ` sashiko-bot
2026-07-19 17:58 ` [RFC PATCH net-next 11/13] bnxt_en: " Taehee Yoo
2026-07-21  7:18   ` sashiko-bot
2026-07-19 17:58 ` [RFC PATCH net-next 12/13] selftests: drivers/net: add knod tests Taehee Yoo
2026-07-21  7:18   ` sashiko-bot
2026-07-19 17:58 ` [RFC PATCH net-next 13/13] drm/amdkfd: add IPsec full-packet offload Taehee Yoo
2026-07-21  7:18   ` sashiko-bot
2026-07-20 19:18 ` [RFC PATCH net-next 00/13] net: knod: in-kernel network offload device Mina Almasry
2026-07-21 15:17   ` Taehee Yoo

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=20260721071755.3A53E1F00A3D@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=ap420073@gmail.com \
    --cc=bpf@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=media-ci@linuxtv.org \
    --cc=sashiko-reviews@lists.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.