From: sashiko-bot@kernel.org
To: "Ekansh Gupta" <ekansh.gupta@oss.qualcomm.com>
Cc: dri-devel@lists.freedesktop.org, media-ci@linuxtv.org
Subject: Re: [PATCH v4 10/25] accel/qda: Add FastRPC invocation contexts
Date: Sun, 01 Nov 2026 22:44:30 +0000 [thread overview]
Message-ID: <sashiko-outbox-192731@kernel.org> (raw)
In-Reply-To: <20261102-v4-v4-10-88f2f24a5f0b@qti.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] accel/qda: premature publication of ctx in qda_fastrpc_context_alloc()
- [High] accel/qda: premature ctx_xa destruction in qda_deinit_device()
--
commit 0b392f877740b474d80d7f4392edfd3f880836d4
Author: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
accel/qda: Add FastRPC invocation contexts
This commit adds FastRPC invocation context allocation and reference-counted
cleanup, tracking in-flight invocations per device in an XArray with an 8-bit
context ID and a 48-bit sequence number.
> diff --git a/drivers/accel/qda/qda_drv.c b/drivers/accel/qda/qda_drv.c
> index 21113deceaadb..bdfb23c3c0b1d 100644
> --- a/drivers/accel/qda/qda_drv.c
> +++ b/drivers/accel/qda/qda_drv.c
> @@ -100,6 +100,8 @@ struct qda_dev *qda_alloc_device(struct device *dev)
>
> INIT_LIST_HEAD(&qdev->cb_devs);
> mutex_init(&qdev->import_lock);
> + xa_init_flags(&qdev->ctx_xa, XA_FLAGS_ALLOC1);
> + atomic64_set(&qdev->ctx_seq, 0);
>
> return qdev;
> }
> @@ -122,6 +124,7 @@ int qda_init_device(struct qda_dev *qdev, int num_cbs)
> void qda_deinit_device(struct qda_dev *qdev)
> {
> qda_memory_manager_exit(qdev->iommu_mgr);
> + xa_destroy(&qdev->ctx_xa);
> mutex_destroy(&qdev->import_lock);
> }
[Severity: High]
Can calling xa_destroy(&qdev->ctx_xa) in qda_deinit_device() in
drivers/accel/qda/qda_drv.c race with outstanding invocation contexts that
have not yet dropped their final reference?
In qda_fastrpc_context_alloc() in drivers/accel/qda/qda_fastrpc.c, each
struct qda_fastrpc_invoke_ctx is inserted into qdev->ctx_xa with an initial
caller reference (refcount = 1) and stores a raw pointer ctx->qdev = qdev
without holding a reference on qdev->drm_dev. By design, the entry is only
erased from qdev->ctx_xa in qda_fastrpc_context_free() when the last
reference is released.
When invocations are wired up in the subsequent commits ("accel/qda: Add
RPMsg send and response dispatch" and "accel/qda: Add the invocation ioctl
and teardown on unplug"), qda_rpmsg_send_msg() takes a second reference for
the response path and the caller sleeps in qda_rpmsg_wait_for_rsp() outside
any drm_dev_enter() critical section.
If the rpmsg device is removed while callers are waiting (for example, on a
DSP crash or remoteproc restart), qda_rpmsg_remove() runs drm_dev_unplug(),
qda_fastrpc_flush_pending(qdev), and then immediately qda_deinit_device(qdev).
Because qda_fastrpc_flush_pending() only wakes the waiters and drops the
response reference, the callers still hold their reference (and if
qda_rpmsg_cb() already ran and queued ctx->put_work, ctx is still in
qdev->ctx_xa while put_work is pending, causing qda_fastrpc_flush_pending()
to drop a reference that put_work will also drop).
When qda_deinit_device() immediately calls xa_destroy(&qdev->ctx_xa), the
internal XArray nodes are freed while live contexts remain in the table. When
those woken callers or pending put_work items later run
kref_put(&ctx->refcount, qda_fastrpc_context_free), won't
qda_fastrpc_context_free() call xa_erase(&ctx->qdev->ctx_xa, ...) on an
already-destroyed XArray and dereference ctx->qdev after device teardown?
> diff --git a/drivers/accel/qda/qda_fastrpc.c b/drivers/accel/qda/qda_fastrpc.c
> new file mode 100644
> index 0000000000000..14d9da8c20b3f
> --- /dev/null
> +++ b/drivers/accel/qda/qda_fastrpc.c
> @@ -0,0 +1,63 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> +#include <linux/bitfield.h>
> +#include <linux/slab.h>
> +#include "qda_drv.h"
> +#include "qda_fastrpc.h"
> +
> +/**
> + * qda_fastrpc_context_free() - Release an invocation
> + * @ref: Reference counter embedded in the invocation
> + *
> + * Runs when the last reference goes. The invocation leaves the lookup table
> + * here and not earlier, so that its ID cannot be handed to a new invocation
> + * while this one can still be found and completed.
> + */
> +void qda_fastrpc_context_free(struct kref *ref)
> +{
> + struct qda_fastrpc_invoke_ctx *ctx =
> + container_of(ref, struct qda_fastrpc_invoke_ctx, refcount);
> +
> + xa_erase(&ctx->qdev->ctx_xa, FIELD_GET(QDA_FASTRPC_CTXID_MASK, ctx->ctxid));
> + kfree(ctx);
> +}
> +
> +/**
> + * qda_fastrpc_context_alloc() - Allocate an invocation and give it an ID
> + * @qdev: Device the invocation is issued on
> + *
> + * The caller holds the initial reference and drops it with
> + * qda_fastrpc_context_free().
> + *
> + * Return: The new invocation, or ERR_PTR on failure
> + */
> +struct qda_fastrpc_invoke_ctx *qda_fastrpc_context_alloc(struct qda_dev *qdev)
> +{
> + struct qda_fastrpc_invoke_ctx *ctx;
> + u32 id;
> + int ret;
> +
> + ctx = kzalloc_obj(*ctx);
> + if (!ctx)
> + return ERR_PTR(-ENOMEM);
> +
> + init_completion(&ctx->work);
> + kref_init(&ctx->refcount);
> + ctx->qdev = qdev;
> + /* Anything but a status the DSP could send, until it answers */
> + ctx->retval = -1;
> +
> + /* ID 0 is never used, so a zeroed context in a response matches nothing */
> + ret = xa_alloc(&qdev->ctx_xa, &id, ctx, XA_LIMIT(1, QDA_FASTRPC_CTXID_MAX),
> + GFP_KERNEL);
> + if (ret) {
> + kfree(ctx);
> + return ERR_PTR(ret);
> + }
> +
> + ctx->ctxid = FIELD_PREP(QDA_FASTRPC_CTXID_MASK, id) |
> + FIELD_PREP(QDA_FASTRPC_CTXID_SEQ_MASK,
> + (u64)atomic64_inc_return(&qdev->ctx_seq));
[Severity: High]
In qda_fastrpc_context_alloc() in drivers/accel/qda/qda_fastrpc.c, does
calling xa_alloc(&qdev->ctx_xa, &id, ctx, ...) publish ctx into qdev->ctx_xa
and drop xa_lock before ctx->ctxid is initialized?
Because the 8-bit context IDs (1..255) are reused as soon as a prior
invocation is freed, a concurrent lookup on qdev->ctx_xa for that recycled id
(such as qda_rpmsg_cb() handling a late, duplicate, or malformed DSP response,
or qda_fastrpc_flush_pending() during device unplug) can observe ctx while
ctx->ctxid is still 0 or is being written without locking:
1. If a late or malformed response carries sequence number 0 in bits [63:16]
for slot id, FIELD_GET(QDA_FASTRPC_CTXID_SEQ_MASK, ctx->ctxid) evaluates to
0 and matches the uninitialized ctx->ctxid, completing ctx->work early and
scheduling ctx->put_work to drop a reference that qda_rpmsg_send_msg() has
not yet taken.
2. If qda_fastrpc_context_free() runs while ctx->ctxid is still 0,
xa_erase(&ctx->qdev->ctx_xa, FIELD_GET(QDA_FASTRPC_CTXID_MASK, ctx->ctxid))
erases index 0 instead of index id and frees ctx, leaving a dangling
pointer in qdev->ctx_xa[id].
Should qda_fastrpc_context_alloc() either hold xa_lock(&qdev->ctx_xa) across
__xa_alloc() and the ctx->ctxid assignment, or reserve the slot with NULL
first and store ctx only after ctx->ctxid is initialized?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261102-v4-v4-0-88f2f24a5f0b@qti.qualcomm.com?part=10
next prev parent reply other threads:[~2026-11-01 22:44 UTC|newest]
Thread overview: 61+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-01 22:21 [PATCH v4 00/25] accel/qda: Qualcomm DSP Accelerator driver Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 01/25] accel/qda: Add QDA driver documentation Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 02/25] accel/qda: Add initial QDA DRM accelerator driver Ekansh Gupta
2026-11-01 22:39 ` sashiko-bot
2026-11-02 8:42 ` Krzysztof Kozlowski
2026-11-01 22:21 ` [PATCH v4 03/25] accel/qda: Add compute context bank devices Ekansh Gupta
2026-11-01 22:52 ` sashiko-bot
2026-11-02 8:43 ` Krzysztof Kozlowski
2026-11-01 22:21 ` [PATCH v4 04/25] accel/qda: Assign a context bank to each session Ekansh Gupta
2026-11-01 22:39 ` sashiko-bot
2026-11-02 8:45 ` Krzysztof Kozlowski
2026-11-01 22:21 ` [PATCH v4 05/25] accel/qda: Add UAPI header and DSP query ioctl Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 06/25] accel/qda: Add buffer allocation for the DSP Ekansh Gupta
2026-11-01 22:51 ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 07/25] accel/qda: Add DMA-BUF import Ekansh Gupta
2026-11-01 22:51 ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 08/25] accel/qda: Add legacy ops base and auxiliary device Ekansh Gupta
2026-11-01 22:43 ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 09/25] accel/qda: Add legacy FastRPC shim skeleton Ekansh Gupta
2026-11-01 22:42 ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 10/25] accel/qda: Add FastRPC invocation contexts Ekansh Gupta
2026-11-01 22:44 ` sashiko-bot [this message]
2026-11-01 22:21 ` [PATCH v4 11/25] accel/qda: Add RPMsg send and response dispatch Ekansh Gupta
2026-11-01 22:39 ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 12/25] accel/qda: Add invocation argument validation and packing Ekansh Gupta
2026-11-01 22:44 ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 13/25] accel/qda: Add the invocation ioctl and teardown on unplug Ekansh Gupta
2026-11-01 22:41 ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 14/25] accel/qda: Add invocation through the legacy FastRPC shim Ekansh Gupta
2026-11-01 22:47 ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 15/25] accel/qda: Add DSP process creation and release Ekansh Gupta
2026-11-01 22:50 ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 16/25] accel/qda: Add DSP process creation and release to the legacy shim Ekansh Gupta
2026-11-01 22:48 ` sashiko-bot
2026-11-02 8:47 ` Krzysztof Kozlowski
2026-11-01 22:21 ` [PATCH v4 17/25] accel/qda: Add remote memory mapping to the DSP address space Ekansh Gupta
2026-11-01 22:54 ` sashiko-bot
2026-11-02 9:24 ` Konrad Dybcio
2026-11-01 22:21 ` [PATCH v4 18/25] accel/qda: Add remote memory unmapping from " Ekansh Gupta
2026-11-01 22:49 ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 19/25] accel/qda: Add remote memory map and unmap to the legacy shim Ekansh Gupta
2026-11-01 22:57 ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 20/25] accel/qda: Add remote attach to root and sensors protection domains Ekansh Gupta
2026-11-01 22:49 ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 21/25] accel/qda: Add Audio protection domain attach and its remote heap Ekansh Gupta
2026-11-01 23:00 ` sashiko-bot
2026-11-02 8:43 ` Arnd Bergmann
2026-11-02 8:50 ` Krzysztof Kozlowski
2026-11-01 22:21 ` [PATCH v4 22/25] accel/qda: Add remote session attach to the legacy shim Ekansh Gupta
2026-11-01 23:00 ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 23/25] accel/qda: Add DSP capability query Ekansh Gupta
2026-11-01 23:03 ` sashiko-bot
2026-11-02 8:46 ` Arnd Bergmann
2026-11-01 22:21 ` [PATCH v4 24/25] accel/qda: Add legacy shim support for " Ekansh Gupta
2026-11-01 23:05 ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 25/25] accel/qda: Add poll mode for invocation completion Ekansh Gupta
2026-11-01 23:02 ` sashiko-bot
2026-11-02 8:53 ` [PATCH v4 00/25] accel/qda: Qualcomm DSP Accelerator driver Krzysztof Kozlowski
2026-11-02 10:08 ` Ekansh Gupta
2026-11-02 10:12 ` Krzysztof Kozlowski
2026-11-02 10:52 ` Ekansh Gupta
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=sashiko-outbox-192731@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=ekansh.gupta@oss.qualcomm.com \
--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.