diff options
| author | Karl Mehltretter <kmehltretter@gmail.com> | 2026-09-08 07:38:14 +0200 |
|---|---|---|
| committer | Michael S. Tsirkin <mst@redhat.com> | 2026-09-08 04:23:49 -0400 |
| commit | ffe14d610cb0169f607e95f994c49d089c507952 (patch) | |
| tree | b6db106a4732633fa2651a8b6a003c599a8e15d1 /include/linux | |
| parent | 48a355cf5b382570975e60857450ff3d42f268e9 (diff) | |
| download | linux-next-ffe14d610cb0169f607e95f994c49d089c507952.tar.gz linux-next-ffe14d610cb0169f607e95f994c49d089c507952.zip | |
remoteproc: implement synchronize_cbs() for virtio devices
Platform drivers invoke rproc_vq_interrupt() from hard-IRQ handlers,
threaded handlers, and work items. Because rpmsg callbacks may sleep,
the virtio core's synchronize_rcu() fallback does not synchronize with
callbacks across all these contexts. A device reset can therefore
complete while a callback is still running.
Add an SRCU domain per rproc. Protect both the queue lookup and
vring_interrupt() with it, and synchronize the domain in the new hook.
__rproc_virtio_del_vqs() can race with rproc_vq_interrupt() too. Clear
all queue pointers and synchronize the SRCU domain before freeing the
queues, so callers that already found a queue can finish using it.
Read rvring->vq once to avoid a second load after deletion starts.
The SRCU domain has the same lifetime as struct rproc. Its cleanup can
sleep, so document that rproc_free() and rproc_put() must not drop the
last reference from atomic context.
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260908053817.26065-4-kmehltretter@gmail.com>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/remoteproc.h | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index a44368737b39..ff0ad1e12c01 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -15,6 +15,7 @@ #include <linux/cdev.h> #include <linux/completion.h> #include <linux/idr.h> +#include <linux/srcu.h> #include <linux/of.h> #include <linux/rsc_table.h> @@ -228,6 +229,7 @@ enum rproc_features { * @mappings: list of iommu mappings we initiated, needed on shutdown * @bootaddr: address of first instruction to boot rproc with (optional) * @rvdevs: list of remote virtio devices + * @vq_srcu: SRCU domain for the virtqueue callbacks of @rvdevs * @subdevs: list of subdevices, to following the running state * @notifyids: idr for dynamically assigning rproc-wide unique notify ids * @index: index of this rproc device @@ -274,6 +276,7 @@ struct rproc { struct list_head mappings; u64 bootaddr; struct list_head rvdevs; + struct srcu_struct vq_srcu; struct list_head subdevs; struct idr notifyids; int index; |
