mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Christian König" <christian.koenig@amd.com>
To: Philipp Stanner <phasta@kernel.org>,
	David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>,
	Alex Deucher <alexander.deucher@amd.com>,
	Andrey Grodzovsky <Andrey.Grodzovsky@amd.com>,
	dakr@kernel.org, Matthew Brost <matthew.brost@intel.com>
Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
	stable@vger.kernel.org
Subject: Re: [PATCH] drm/sched: Fix UB in spsc_queue
Date: Mon, 10 Nov 2025 12:24:46 +0100	[thread overview]
Message-ID: <ee63ca7d-77d2-44d8-973b-7276f8c4d4a5@amd.com> (raw)
In-Reply-To: <20251110081903.11539-2-phasta@kernel.org>

As far as I can see that is not correct or rather not complete.

The peek function should only be used to opportunistically look at the top of the queue. It would only be problematic if it returns a non NULL value once and then a NULL value later.

The whole idea of the SPSC is that it is barrier-free and the signaling of new entries to the consumer side is providing the barrier.

So basically on the provider side you have
spsc_push(entry)
wake_up(consumer)

And on the consumer side you have:

woken_up_by_provider() {
	entry = spsc_peek();
	...
	spsc_pop();
}

The problem we are facing here is that the spsc only provides the guarantee that you see the entry pointer, but not the content of entry itself.

So use cases like:

woken_up_by_provider() {
	while (entry = spsc_peek()) {
		...
		spsc_pop();
	}
}

Are illegal since you don't have the correct memory barriers any more.

Took me an eternity to understand that as well, so bear with me that I didn't previously explained that.

Question is what should we do?

Regards,
Christian.

On 11/10/25 09:19, Philipp Stanner wrote:
> The spsc_queue is an unlocked, highly asynchronous piece of
> infrastructure. Its inline function spsc_queue_peek() obtains the head
> entry of the queue.
> 
> This access is performed without READ_ONCE() and is, therefore,
> undefined behavior. In order to prevent the compiler from ever
> reordering that access, or even optimizing it away, a READ_ONCE() is
> strictly necessary. This is easily proven by the fact that
> spsc_queue_pop() uses this very pattern to access the head.
> 
> Add READ_ONCE() to spsc_queue_peek().
> 
> Cc: stable@vger.kernel.org # v4.16+
> Fixes: 27105db6c63a ("drm/amdgpu: Add SPSC queue to scheduler.")
> Signed-off-by: Philipp Stanner <phasta@kernel.org>
> ---
> I think this makes it less broken, but I'm not even sure if it's enough
> or more memory barriers or an rcu_dereference() would be correct. The
> spsc_queue is, of course, not documented and the existing barrier
> comments are either false or not telling.
> 
> If someone has an idea, shoot us the info. Otherwise I think this is the
> right thing to do for now.
> 
> P.
> ---
>  include/drm/spsc_queue.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/include/drm/spsc_queue.h b/include/drm/spsc_queue.h
> index ee9df8cc67b7..39bada748ffc 100644
> --- a/include/drm/spsc_queue.h
> +++ b/include/drm/spsc_queue.h
> @@ -54,7 +54,7 @@ static inline void spsc_queue_init(struct spsc_queue *queue)
>  
>  static inline struct spsc_node *spsc_queue_peek(struct spsc_queue *queue)
>  {
> -	return queue->head;
> +	return READ_ONCE(queue->head);
>  }
>  
>  static inline int spsc_queue_count(struct spsc_queue *queue)


  reply	other threads:[~2025-11-10 11:24 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-10  8:19 Philipp Stanner
2025-11-10 11:24 ` Christian König [this message]
2025-11-10 12:27   ` Philipp Stanner
2025-11-10 14:07     ` Christian König
2025-11-10 14:20       ` Philipp Stanner
2025-11-10 15:14         ` Christian König
2025-11-10 15:55           ` Philipp Stanner
2025-11-10 16:08             ` Christian König
2025-11-11  6:52               ` Philipp Stanner

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=ee63ca7d-77d2-44d8-973b-7276f8c4d4a5@amd.com \
    --to=christian.koenig@amd.com \
    --cc=Andrey.Grodzovsky@amd.com \
    --cc=airlied@gmail.com \
    --cc=alexander.deucher@amd.com \
    --cc=dakr@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=matthew.brost@intel.com \
    --cc=phasta@kernel.org \
    --cc=simona@ffwll.ch \
    --cc=stable@vger.kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®