All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: Karl Mehltretter <kmehltretter@gmail.com>
Cc: "Jason Wang" <jasowangio@gmail.com>,
	"Gerd Hoffmann" <kraxel@redhat.com>,
	"Xuan Zhuo" <xuanzhuo@linux.alibaba.com>,
	"Eugenio Pérez" <eperezma@redhat.com>,
	"Dmitry Torokhov" <dmitry.torokhov@gmail.com>,
	"Rusty Russell" <rusty@rustcorp.com.au>,
	"Pawel Moll" <pawel.moll@arm.com>,
	"Cornelia Huck" <cohuck@redhat.com>,
	"Halil Pasic" <pasic@linux.ibm.com>,
	"Eric Farman" <farman@linux.ibm.com>,
	"Richard Weinberger" <richard@nod.at>,
	"Anton Ivanov" <anton.ivanov@cambridgegreys.com>,
	"Johannes Berg" <johannes@sipsolutions.net>,
	"Hans de Goede" <hansg@kernel.org>,
	"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
	"Vadim Pasternak" <vadimp@nvidia.com>,
	"Bjorn Andersson" <andersson@kernel.org>,
	"Mathieu Poirier" <mathieu.poirier@linaro.org>,
	virtualization@lists.linux.dev, linux-input@vger.kernel.org,
	linux-s390@vger.kernel.org, kvm@vger.kernel.org,
	linux-um@lists.infradead.org,
	platform-driver-x86@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2 3/3] virtio: implement synchronize_cbs for remaining transports
Date: Sun, 6 Sep 2026 14:59:26 -0400	[thread overview]
Message-ID: <20260906145728-mutt-send-email-mst@kernel.org> (raw)
In-Reply-To: <20260905152059.89560-4-kmehltretter@gmail.com>

On Sat, Sep 05, 2026 at 05:20:59PM +0200, Karl Mehltretter wrote:
> virtio_reset_device() now calls synchronize_cbs to wait for running
> callbacks. Its synchronize_rcu() fallback does not cover workqueue or
> sleepable callbacks.
> 
> Add the missing hooks. UML waits for its shared IRQ; TmFIFO takes the
> existing per-direction locks held around vring_interrupt(). Virtio-vdpa
> uses a per-device rwlock around its callbacks, which must already be
> hard-IRQ safe.
> 
> Remoteproc callbacks can run in hard-IRQ or process context, and rpmsg
> callbacks can sleep, so use one SRCU domain per rproc. Enter it before
> looking up the queue. Initialize it in rproc_alloc(), returning NULL if
> that fails, and clean it up at final release. cleanup_srcu_struct() can
> sleep, so document that rproc_put() and rproc_free() may sleep when
> dropping the last reference.
> 
> These hooks wait for callbacks already running. UML, TmFIFO and
> remoteproc still allow new callbacks after reset.
> 
> Suggested-by: Michael S. Tsirkin <mst@redhat.com>
> Assisted-by: LLM
> Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>


sounds like sashiko sees some issues here.
they seem legit.
I would also maybe split, 1 patch per transport.


> ---
>  arch/um/drivers/virtio_uml.c             | 10 ++++++++++
>  drivers/platform/mellanox/mlxbf-tmfifo.c | 14 ++++++++++++++
>  drivers/remoteproc/remoteproc_core.c     | 10 ++++++++++
>  drivers/remoteproc/remoteproc_virtio.c   | 20 +++++++++++++++++---
>  drivers/virtio/virtio_vdpa.c             | 21 ++++++++++++++++++++-
>  include/linux/remoteproc.h               |  3 +++
>  6 files changed, 74 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c
> index 7425a8548141..baca6b09e9ac 100644
> --- a/arch/um/drivers/virtio_uml.c
> +++ b/arch/um/drivers/virtio_uml.c
> @@ -20,6 +20,7 @@
>   *
>   * Based on Virtio MMIO driver by Pawel Moll, copyright 2011-2014, ARM Ltd.
>   */
> +#include <linux/interrupt.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/platform_device.h>
> @@ -869,6 +870,14 @@ static void vu_reset(struct virtio_device *vdev)
>  	vu_dev->status = 0;
>  }
>  
> +static void vu_synchronize_cbs(struct virtio_device *vdev)
> +{
> +	struct virtio_uml_device *vu_dev = to_virtio_uml_device(vdev);
> +
> +	if (vu_dev->irq >= 0)
> +		synchronize_irq(vu_dev->irq);
> +}
> +
>  static void vu_del_vq(struct virtqueue *vq)
>  {
>  	struct virtio_uml_vq_info *info = vq->priv;
> @@ -1121,6 +1130,7 @@ static const struct virtio_config_ops virtio_uml_config_ops = {
>  	.reset = vu_reset,
>  	.find_vqs = vu_find_vqs,
>  	.del_vqs = vu_del_vqs,
> +	.synchronize_cbs = vu_synchronize_cbs,
>  	.get_features = vu_get_features,
>  	.finalize_features = vu_finalize_features,
>  	.bus_name = vu_bus_name,
> diff --git a/drivers/platform/mellanox/mlxbf-tmfifo.c b/drivers/platform/mellanox/mlxbf-tmfifo.c
> index 3c6408581373..c260e3a1544e 100644
> --- a/drivers/platform/mellanox/mlxbf-tmfifo.c
> +++ b/drivers/platform/mellanox/mlxbf-tmfifo.c
> @@ -1135,6 +1135,19 @@ static void mlxbf_tmfifo_virtio_reset(struct virtio_device *vdev)
>  	tm_vdev->status = 0;
>  }
>  
> +static void mlxbf_tmfifo_virtio_synchronize_cbs(struct virtio_device *vdev)
> +{
> +	struct mlxbf_tmfifo_vdev *tm_vdev = mlxbf_vdev_to_tmfifo(vdev);
> +	struct mlxbf_tmfifo *fifo = tm_vdev->vrings[0].fifo;
> +	unsigned long flags;
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(fifo->spin_lock); i++) {
> +		spin_lock_irqsave(&fifo->spin_lock[i], flags);
> +		spin_unlock_irqrestore(&fifo->spin_lock[i], flags);
> +	}
> +}
> +
>  /* Read the value of a configuration field. */
>  static void mlxbf_tmfifo_virtio_get(struct virtio_device *vdev,
>  				    unsigned int offset,
> @@ -1179,6 +1192,7 @@ static const struct virtio_config_ops mlxbf_tmfifo_virtio_config_ops = {
>  	.find_vqs = mlxbf_tmfifo_virtio_find_vqs,
>  	.del_vqs = mlxbf_tmfifo_virtio_del_vqs,
>  	.reset = mlxbf_tmfifo_virtio_reset,
> +	.synchronize_cbs = mlxbf_tmfifo_virtio_synchronize_cbs,
>  	.set_status = mlxbf_tmfifo_virtio_set_status,
>  	.get_status = mlxbf_tmfifo_virtio_get_status,
>  	.get = mlxbf_tmfifo_virtio_get,
> diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
> index 1ed406714849..1b139d25ab2b 100644
> --- a/drivers/remoteproc/remoteproc_core.c
> +++ b/drivers/remoteproc/remoteproc_core.c
> @@ -2410,6 +2410,7 @@ static void rproc_type_release(struct device *dev)
>  
>  	dev_info(&rproc->dev, "releasing %s\n", rproc->name);
>  
> +	cleanup_srcu_struct(&rproc->vq_srcu);
>  	idr_destroy(&rproc->notifyids);
>  
>  	if (rproc->index >= 0)
> @@ -2507,6 +2508,11 @@ struct rproc *rproc_alloc(struct device *dev, const char *name,
>  	if (!rproc)
>  		return NULL;
>  
> +	if (init_srcu_struct(&rproc->vq_srcu)) {
> +		kfree(rproc);
> +		return NULL;
> +	}
> +
>  	rproc->priv = &rproc[1];
>  	rproc->auto_boot = true;
>  	rproc->elf_class = ELFCLASSNONE;
> @@ -2571,6 +2577,8 @@ EXPORT_SYMBOL(rproc_alloc);
>   *
>   * If no one holds any reference to rproc anymore, then its refcount would
>   * now drop to zero, and it would be freed.
> + *
> + * Context: May sleep if this drops the last reference.
>   */
>  void rproc_free(struct rproc *rproc)
>  {
> @@ -2586,6 +2594,8 @@ EXPORT_SYMBOL(rproc_free);
>   *
>   * If no one holds any reference to rproc anymore, then its refcount would
>   * now drop to zero, and it would be freed.
> + *
> + * Context: May sleep if this drops the last reference.
>   */
>  void rproc_put(struct rproc *rproc)
>  {
> diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c
> index d5e9ff045a28..ecc022e354db 100644
> --- a/drivers/remoteproc/remoteproc_virtio.c
> +++ b/drivers/remoteproc/remoteproc_virtio.c
> @@ -23,6 +23,7 @@
>  #include <linux/err.h>
>  #include <linux/kref.h>
>  #include <linux/slab.h>
> +#include <linux/srcu.h>
>  
>  #include "remoteproc_internal.h"
>  
> @@ -89,14 +90,19 @@ static bool rproc_virtio_notify(struct virtqueue *vq)
>  irqreturn_t rproc_vq_interrupt(struct rproc *rproc, int notifyid)
>  {
>  	struct rproc_vring *rvring;
> +	int srcu_idx;
> +	irqreturn_t ret;
> +
> +	srcu_idx = srcu_read_lock(&rproc->vq_srcu);
>  
>  	dev_dbg(&rproc->dev, "vq index %d is interrupted\n", notifyid);
>  
>  	rvring = idr_find(&rproc->notifyids, notifyid);
> -	if (!rvring || !rvring->vq)
> -		return IRQ_NONE;
> +	ret = rvring && rvring->vq ? vring_interrupt(0, rvring->vq) : IRQ_NONE;
> +
> +	srcu_read_unlock(&rproc->vq_srcu, srcu_idx);
>  
> -	return vring_interrupt(0, rvring->vq);
> +	return ret;
>  }
>  EXPORT_SYMBOL(rproc_vq_interrupt);
>  
> @@ -242,6 +248,13 @@ static void rproc_virtio_reset(struct virtio_device *vdev)
>  	dev_dbg(&vdev->dev, "reset !\n");
>  }
>  
> +static void rproc_virtio_synchronize_cbs(struct virtio_device *vdev)
> +{
> +	struct rproc *rproc = vdev_to_rproc(vdev);
> +
> +	synchronize_srcu(&rproc->vq_srcu);
> +}
> +
>  /* provide the vdev features as retrieved from the firmware */
>  static u64 rproc_virtio_get_features(struct virtio_device *vdev)
>  {
> @@ -330,6 +343,7 @@ static const struct virtio_config_ops rproc_virtio_config_ops = {
>  	.find_vqs	= rproc_virtio_find_vqs,
>  	.del_vqs	= rproc_virtio_del_vqs,
>  	.reset		= rproc_virtio_reset,
> +	.synchronize_cbs = rproc_virtio_synchronize_cbs,
>  	.set_status	= rproc_virtio_set_status,
>  	.get_status	= rproc_virtio_get_status,
>  	.get		= rproc_virtio_get,
> diff --git a/drivers/virtio/virtio_vdpa.c b/drivers/virtio/virtio_vdpa.c
> index de2af696de6c..4f9e70c1332e 100644
> --- a/drivers/virtio/virtio_vdpa.c
> +++ b/drivers/virtio/virtio_vdpa.c
> @@ -27,6 +27,7 @@
>  struct virtio_vdpa_device {
>  	struct virtio_device vdev;
>  	struct vdpa_device *vdpa;
> +	rwlock_t callback_lock;
>  	u64 features;
>  };
>  
> @@ -123,8 +124,24 @@ static irqreturn_t virtio_vdpa_config_cb(void *private)
>  static irqreturn_t virtio_vdpa_virtqueue_cb(void *private)
>  {
>  	struct virtqueue *vq = private;
> +	struct virtio_vdpa_device *vd_dev;
> +	unsigned long flags;
> +	irqreturn_t ret;
>  
> -	return vring_interrupt(0, vq);
> +	vd_dev = to_virtio_vdpa_device(vq->vdev);
> +	read_lock_irqsave(&vd_dev->callback_lock, flags);
> +	ret = vring_interrupt(0, vq);
> +	read_unlock_irqrestore(&vd_dev->callback_lock, flags);
> +
> +	return ret;
> +}
> +
> +static void virtio_vdpa_synchronize_cbs(struct virtio_device *vdev)
> +{
> +	struct virtio_vdpa_device *vd_dev = to_virtio_vdpa_device(vdev);
> +
> +	write_lock_irq(&vd_dev->callback_lock);
> +	write_unlock_irq(&vd_dev->callback_lock);
>  }
>  
>  static struct virtqueue *
> @@ -439,6 +456,7 @@ static const struct virtio_config_ops virtio_vdpa_config_ops = {
>  	.reset		= virtio_vdpa_reset,
>  	.find_vqs	= virtio_vdpa_find_vqs,
>  	.del_vqs	= virtio_vdpa_del_vqs,
> +	.synchronize_cbs = virtio_vdpa_synchronize_cbs,
>  	.get_features	= virtio_vdpa_get_features,
>  	.finalize_features = virtio_vdpa_finalize_features,
>  	.bus_name	= virtio_vdpa_bus_name,
> @@ -472,6 +490,7 @@ static int virtio_vdpa_probe(struct vdpa_device *vdpa)
>  	vd_dev->vdev.config = &virtio_vdpa_config_ops;
>  	vd_dev->vdev.map = vdpa->map;
>  	vd_dev->vdpa = vdpa;
> +	rwlock_init(&vd_dev->callback_lock);
>  
>  	vd_dev->vdev.id.device = ops->get_device_id(vdpa);
>  	if (vd_dev->vdev.id.device == 0)
> diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
> index a44368737b39..ad6bccbdfabc 100644
> --- a/include/linux/remoteproc.h
> +++ b/include/linux/remoteproc.h
> @@ -11,6 +11,7 @@
>  #include <linux/types.h>
>  #include <linux/mutex.h>
>  #include <linux/spinlock.h>
> +#include <linux/srcu.h>
>  #include <linux/virtio.h>
>  #include <linux/cdev.h>
>  #include <linux/completion.h>
> @@ -230,6 +231,7 @@ enum rproc_features {
>   * @rvdevs: list of remote virtio devices
>   * @subdevs: list of subdevices, to following the running state
>   * @notifyids: idr for dynamically assigning rproc-wide unique notify ids
> + * @vq_srcu: SRCU domain for virtqueue callbacks
>   * @index: index of this rproc device
>   * @attach_work: workqueue for attaching rproc
>   * @crash_handler: workqueue for handling a crash
> @@ -276,6 +278,7 @@ struct rproc {
>  	struct list_head rvdevs;
>  	struct list_head subdevs;
>  	struct idr notifyids;
> +	struct srcu_struct vq_srcu;
>  	int index;
>  	struct work_struct attach_work;
>  	struct work_struct crash_handler;
> -- 
> 2.39.5 (Apple Git-154)


  parent reply	other threads:[~2026-09-06 18:59 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-05 15:20 [PATCH v2 0/3] virtio: synchronize callbacks during device reset Karl Mehltretter
2026-09-05 15:20 ` [PATCH v2 1/3] " Karl Mehltretter
2026-09-05 15:35   ` sashiko-bot
2026-09-06  6:49   ` Michael S. Tsirkin
2026-09-07 21:36   ` Michael S. Tsirkin
2026-09-05 15:20 ` [PATCH v2 2/3] virtio_input: stop callbacks before unregistering input device Karl Mehltretter
2026-09-05 15:33   ` sashiko-bot
2026-09-07 21:19     ` Michael S. Tsirkin
2026-09-06  6:51   ` Michael S. Tsirkin
2026-09-07 21:46   ` Michael S. Tsirkin
2026-09-07 22:15     ` Karl Mehltretter
2026-09-07 22:22       ` Michael S. Tsirkin
2026-09-07 22:32         ` Karl Mehltretter
2026-09-05 15:20 ` [PATCH v2 3/3] virtio: implement synchronize_cbs for remaining transports Karl Mehltretter
2026-09-05 15:35   ` sashiko-bot
2026-09-06 18:59   ` Michael S. Tsirkin [this message]
2026-09-06  6:43 ` [PATCH v2 0/3] virtio: synchronize callbacks during device reset Michael S. Tsirkin
2026-09-06  6:53 ` Michael S. Tsirkin
2026-09-06 16:32   ` Karl Mehltretter
2026-09-06 18:56     ` Michael S. Tsirkin
2026-09-07 13:13 ` Michael S. Tsirkin
2026-09-07 21:23   ` Karl Mehltretter
2026-09-07 21:41     ` Michael S. Tsirkin
2026-09-11 12:39 ` Michael S. Tsirkin

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=20260906145728-mutt-send-email-mst@kernel.org \
    --to=mst@redhat.com \
    --cc=andersson@kernel.org \
    --cc=anton.ivanov@cambridgegreys.com \
    --cc=cohuck@redhat.com \
    --cc=dmitry.torokhov@gmail.com \
    --cc=eperezma@redhat.com \
    --cc=farman@linux.ibm.com \
    --cc=hansg@kernel.org \
    --cc=ilpo.jarvinen@linux.intel.com \
    --cc=jasowangio@gmail.com \
    --cc=johannes@sipsolutions.net \
    --cc=kmehltretter@gmail.com \
    --cc=kraxel@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-remoteproc@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=linux-um@lists.infradead.org \
    --cc=mathieu.poirier@linaro.org \
    --cc=pasic@linux.ibm.com \
    --cc=pawel.moll@arm.com \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=richard@nod.at \
    --cc=rusty@rustcorp.com.au \
    --cc=vadimp@nvidia.com \
    --cc=virtualization@lists.linux.dev \
    --cc=xuanzhuo@linux.alibaba.com \
    /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.