aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/remoteproc/remoteproc_virtio.c
diff options
context:
space:
mode:
authorOhad Ben-Cohen <ohad@wizery.com>2012-05-17 07:23:59 -0400
committerOhad Ben-Cohen <ohad@wizery.com>2012-07-04 06:27:04 -0400
commit6db20ea8d85064175c7ef594c433c6c2e6bbab83 (patch)
tree6087ffde8501059bdfd578758fb05c53aba3d620 /drivers/remoteproc/remoteproc_virtio.c
parent485802a6c524e62b5924849dd727ddbb1497cc71 (diff)
remoteproc: allocate vrings on demand, free when not needed
Dynamically allocate the vrings' DMA when the remote processor is about to be powered on (i.e. when ->find_vqs() is invoked), and release them as soon as it is powered off (i.e. when ->del_vqs() is invoked). The obvious and immediate benefit is better memory utilization, since memory for the vrings is now only allocated when the relevant remote processor is used. Additionally, this approach also makes recovery of a (crashing) remote processor easier: one just needs to remove the relevant vdevs, and the entire vrings cleanup takes place automagically. Tested-by: Fernando Guzman Lugo <fernando.lugo@ti.com> Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
Diffstat (limited to 'drivers/remoteproc/remoteproc_virtio.c')
-rw-r--r--drivers/remoteproc/remoteproc_virtio.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c
index ecf612130750..26a7144e7f3b 100644
--- a/drivers/remoteproc/remoteproc_virtio.c
+++ b/drivers/remoteproc/remoteproc_virtio.c
@@ -77,14 +77,17 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
77 struct rproc_vring *rvring; 77 struct rproc_vring *rvring;
78 struct virtqueue *vq; 78 struct virtqueue *vq;
79 void *addr; 79 void *addr;
80 int len, size; 80 int len, size, ret;
81 81
82 /* we're temporarily limited to two virtqueues per rvdev */ 82 /* we're temporarily limited to two virtqueues per rvdev */
83 if (id >= ARRAY_SIZE(rvdev->vring)) 83 if (id >= ARRAY_SIZE(rvdev->vring))
84 return ERR_PTR(-EINVAL); 84 return ERR_PTR(-EINVAL);
85 85
86 rvring = &rvdev->vring[id]; 86 ret = rproc_alloc_vring(rvdev, id);
87 if (ret)
88 return ERR_PTR(ret);
87 89
90 rvring = &rvdev->vring[id];
88 addr = rvring->va; 91 addr = rvring->va;
89 len = rvring->len; 92 len = rvring->len;
90 93
@@ -103,6 +106,7 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
103 rproc_virtio_notify, callback, name); 106 rproc_virtio_notify, callback, name);
104 if (!vq) { 107 if (!vq) {
105 dev_err(rproc->dev, "vring_new_virtqueue %s failed\n", name); 108 dev_err(rproc->dev, "vring_new_virtqueue %s failed\n", name);
109 rproc_free_vring(rvring);
106 return ERR_PTR(-ENOMEM); 110 return ERR_PTR(-ENOMEM);
107 } 111 }
108 112
@@ -125,6 +129,7 @@ static void rproc_virtio_del_vqs(struct virtio_device *vdev)
125 rvring = vq->priv; 129 rvring = vq->priv;
126 rvring->vq = NULL; 130 rvring->vq = NULL;
127 vring_del_virtqueue(vq); 131 vring_del_virtqueue(vq);
132 rproc_free_vring(rvring);
128 } 133 }
129} 134}
130 135
@@ -228,8 +233,12 @@ static struct virtio_config_ops rproc_virtio_config_ops = {
228static void rproc_vdev_release(struct device *dev) 233static void rproc_vdev_release(struct device *dev)
229{ 234{
230 struct virtio_device *vdev = dev_to_virtio(dev); 235 struct virtio_device *vdev = dev_to_virtio(dev);
236 struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
231 struct rproc *rproc = vdev_to_rproc(vdev); 237 struct rproc *rproc = vdev_to_rproc(vdev);
232 238
239 list_del(&rvdev->node);
240 kfree(rvdev);
241
233 kref_put(&rproc->refcount, rproc_release); 242 kref_put(&rproc->refcount, rproc_release);
234} 243}
235 244