| From ddc209c9475a2822ffe5d18441bd01718acdbc11 Mon Sep 17 00:00:00 2001 |
| From: ligd <liguiding1@xiaomi.com> |
| Date: Fri, 29 Jul 2022 22:57:23 +0800 |
| Subject: [PATCH 04/10] openamp: add new ops notify_wait() support |
| |
| This can avoid looping check tx buffer |
| |
| Change-Id: Ie340ed06c306ce978ff165aacaf5b830e3645af8 |
| Signed-off-by: ligd <liguiding1@xiaomi.com> |
| --- |
| lib/include/openamp/remoteproc.h | 12 ++++++++++++ |
| lib/include/openamp/remoteproc_virtio.h | 2 ++ |
| lib/include/openamp/rpmsg.h | 1 + |
| lib/include/openamp/rpmsg_virtio.h | 9 +++++++++ |
| lib/include/openamp/virtio.h | 1 + |
| lib/remoteproc/remoteproc.c | 11 +++++++++++ |
| lib/remoteproc/remoteproc_virtio.c | 14 ++++++++++++++ |
| lib/rpmsg/rpmsg_virtio.c | 7 +++++++ |
| 8 files changed, 57 insertions(+) |
| |
| diff --git a/lib/include/openamp/remoteproc.h open-amp/lib/include/openamp/remoteproc.h |
| index d1efab85..f6554404 100644 |
| --- a/lib/include/openamp/remoteproc.h |
| +++ open-amp/lib/include/openamp/remoteproc.h |
| @@ -428,6 +428,18 @@ struct remoteproc_ops { |
| int (*stop)(struct remoteproc *rproc); |
| int (*shutdown)(struct remoteproc *rproc); |
| int (*notify)(struct remoteproc *rproc, uint32_t id); |
| + /** |
| + * notify_wait |
| + * |
| + * Wait for remote notified, when there is no TX buffer anymore. |
| + * Set to NULL means use usleep to wait TX buffer available. |
| + * |
| + * @rproc - pointer to remoteproc instance |
| + * @id - the notifyid |
| + * |
| + * return 0 means there is notify available, otherwise negative value. |
| + */ |
| + int (*notify_wait)(struct remoteproc *rproc, uint32_t id); |
| /** |
| * get_mem |
| * |
| diff --git a/lib/include/openamp/remoteproc_virtio.h open-amp/lib/include/openamp/remoteproc_virtio.h |
| index 6609a1fd..e65488d5 100644 |
| --- a/lib/include/openamp/remoteproc_virtio.h |
| +++ open-amp/lib/include/openamp/remoteproc_virtio.h |
| @@ -25,6 +25,7 @@ extern "C" { |
| |
| /* define vdev notification function user should implement */ |
| typedef int (*rpvdev_notify_func)(void *priv, uint32_t id); |
| +typedef int (*rpvdev_notify_wait)(void *priv, uint32_t id); |
| |
| /** |
| * struct remoteproc_virtio |
| @@ -40,6 +41,7 @@ struct remoteproc_virtio { |
| void *vdev_rsc; |
| struct metal_io_region *vdev_rsc_io; |
| rpvdev_notify_func notify; |
| + rpvdev_notify_wait notify_wait; |
| struct virtio_device vdev; |
| struct metal_list node; |
| }; |
| diff --git a/lib/include/openamp/rpmsg.h open-amp/lib/include/openamp/rpmsg.h |
| index dbe42ea6..14440e20 100644 |
| --- a/lib/include/openamp/rpmsg.h |
| +++ open-amp/lib/include/openamp/rpmsg.h |
| @@ -50,6 +50,7 @@ extern "C" { |
| #define RPMSG_ERR_INIT (RPMSG_ERROR_BASE - 6) |
| #define RPMSG_ERR_ADDR (RPMSG_ERROR_BASE - 7) |
| #define RPMSG_ERR_PERM (RPMSG_ERROR_BASE - 8) |
| +#define RPMSG_ERR_NXIO (RPMSG_ERROR_BASE - 9) |
| |
| struct rpmsg_endpoint; |
| struct rpmsg_device; |
| diff --git a/lib/include/openamp/rpmsg_virtio.h open-amp/lib/include/openamp/rpmsg_virtio.h |
| index 0b22e840..11cb6df9 100644 |
| --- a/lib/include/openamp/rpmsg_virtio.h |
| +++ open-amp/lib/include/openamp/rpmsg_virtio.h |
| @@ -148,6 +148,15 @@ rpmsg_virtio_create_virtqueues(struct rpmsg_virtio_device *rvdev, |
| callbacks); |
| } |
| |
| +static inline int |
| +rpmsg_virtio_notify_wait(struct rpmsg_virtio_device *rvdev, |
| + struct virtqueue *vq) |
| +{ |
| + return rvdev->vdev->func->notify_wait ? |
| + rvdev->vdev->func->notify_wait(rvdev->vdev, vq) : |
| + RPMSG_ERR_NXIO; |
| +} |
| + |
| /** |
| * rpmsg_virtio_get_buffer_size - get rpmsg virtio buffer size |
| * |
| diff --git a/lib/include/openamp/virtio.h open-amp/lib/include/openamp/virtio.h |
| index 916132b4..0303a5b3 100644 |
| --- a/lib/include/openamp/virtio.h |
| +++ open-amp/lib/include/openamp/virtio.h |
| @@ -162,6 +162,7 @@ struct virtio_dispatch { |
| void *src, int length); |
| void (*reset_device)(struct virtio_device *dev); |
| void (*notify)(struct virtqueue *vq); |
| + int (*notify_wait)(struct virtio_device *dev, struct virtqueue *vq); |
| }; |
| |
| int virtio_create_virtqueues(struct virtio_device *vdev, unsigned int flags, |
| diff --git a/lib/remoteproc/remoteproc.c open-amp/lib/remoteproc/remoteproc.c |
| index f7f9f2df..001b11bf 100644 |
| --- a/lib/remoteproc/remoteproc.c |
| +++ open-amp/lib/remoteproc/remoteproc.c |
| @@ -899,6 +899,16 @@ static int remoteproc_virtio_notify(void *priv, uint32_t id) |
| return 0; |
| } |
| |
| +static int remoteproc_virtio_notify_wait(void *priv, uint32_t id) |
| +{ |
| + struct remoteproc *rproc = priv; |
| + |
| + if (rproc->ops->notify_wait) |
| + return rproc->ops->notify_wait(rproc, id); |
| + |
| + return 0; |
| +} |
| + |
| struct virtio_device * |
| remoteproc_create_virtio(struct remoteproc *rproc, |
| int vdev_id, unsigned int role, |
| @@ -957,6 +967,7 @@ remoteproc_create_virtio(struct remoteproc *rproc, |
| rproc_virtio_wait_remote_ready(vdev); |
| |
| rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev); |
| + rpvdev->notify_wait = remoteproc_virtio_notify_wait; |
| metal_list_add_tail(&rproc->vdevs, &rpvdev->node); |
| num_vrings = vdev_rsc->num_of_vrings; |
| |
| diff --git a/lib/remoteproc/remoteproc_virtio.c open-amp/lib/remoteproc/remoteproc_virtio.c |
| index 169e5b5f..4375c4c3 100644 |
| --- a/lib/remoteproc/remoteproc_virtio.c |
| +++ open-amp/lib/remoteproc/remoteproc_virtio.c |
| @@ -30,6 +30,19 @@ static void rproc_virtio_virtqueue_notify(struct virtqueue *vq) |
| rpvdev->notify(rpvdev->priv, vring_info->notifyid); |
| } |
| |
| +static int rproc_virtio_notify_wait(struct virtio_device *vdev, |
| + struct virtqueue *vq) |
| +{ |
| + struct remoteproc_virtio *rpvdev; |
| + struct virtio_vring_info *vring_info; |
| + unsigned int vq_id = vq->vq_queue_index; |
| + |
| + rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev); |
| + vring_info = &vdev->vrings_info[vq_id]; |
| + |
| + return rpvdev->notify_wait(rpvdev->priv, vring_info->notifyid); |
| +} |
| + |
| static unsigned char rproc_virtio_get_status(struct virtio_device *vdev) |
| { |
| struct remoteproc_virtio *rpvdev; |
| @@ -179,6 +192,7 @@ static const struct virtio_dispatch remoteproc_virtio_dispatch_funcs = { |
| .get_features = rproc_virtio_get_features, |
| .read_config = rproc_virtio_read_config, |
| .notify = rproc_virtio_virtqueue_notify, |
| + .notify_wait = rproc_virtio_notify_wait, |
| #ifndef VIRTIO_DEVICE_ONLY |
| /* |
| * We suppose here that the vdev is in a shared memory so that can |
| diff --git a/lib/rpmsg/rpmsg_virtio.c open-amp/lib/rpmsg/rpmsg_virtio.c |
| index c56e0cea..4960aa8a 100644 |
| --- a/lib/rpmsg/rpmsg_virtio.c |
| +++ open-amp/lib/rpmsg/rpmsg_virtio.c |
| @@ -373,6 +373,13 @@ static void *rpmsg_virtio_get_tx_payload_buffer(struct rpmsg_device *rdev, |
| metal_mutex_release(&rdev->lock); |
| if (rp_hdr || !tick_count) |
| break; |
| + |
| + status = rpmsg_virtio_notify_wait(rvdev, rvdev->rvq); |
| + if (status == RPMSG_SUCCESS) |
| + continue; |
| + else if (status != RPMSG_ERR_NXIO) |
| + break; |
| + |
| metal_sleep_usec(RPMSG_TICKS_PER_INTERVAL); |
| tick_count--; |
| } |
| -- |
| 2.25.1 |
| |