From patchwork Tue Feb 12 11:49:51 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: sjur.brandeland@stericsson.com X-Patchwork-Id: 219830 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 556F92C032D for ; Tue, 12 Feb 2013 22:51:00 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933096Ab3BLLu2 (ORCPT ); Tue, 12 Feb 2013 06:50:28 -0500 Received: from mail-wi0-f173.google.com ([209.85.212.173]:55730 "EHLO mail-wi0-f173.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933090Ab3BLLu0 (ORCPT ); Tue, 12 Feb 2013 06:50:26 -0500 Received: by mail-wi0-f173.google.com with SMTP id hq4so4300339wib.0 for ; Tue, 12 Feb 2013 03:50:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:sender:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references:mime-version:content-type :content-transfer-encoding; bh=UHma16hIfvR4VwWVVdqvF3TmTsXEhtbZUvxNE8cy5gU=; b=gOrcIOHffVhWfYYLmPfXQ6wb2xcDMGtoYrqE4h6bMAfewZYtuePxHpSZ0HieBABBlI dGzD9AZqY90BGQo6tQlHvjflIFxoboLvFPsuVNrNB9VPzE8ICxxljC6gatGWZPhhQ0Xm W6L+LYRJoroLIakGzOJa3udBrs5uol8SaY/99fMkCbIDYWJHNPJvlIBJ8pJ6RKJOahSs lpzcC5uzBDuH0oVk+SISIEw2kU+1wYRmvd6O/geJGj57swf5fyBSWwzPrbCV5anpZ0vh SfNh5ncjdYrNa9beTBy2/D4uYQmOOiJncfSNPg7w7iStuB9JfO68aWMLYg08sYLS/K9j MkKw== X-Received: by 10.180.99.227 with SMTP id et3mr2676146wib.6.1360669825115; Tue, 12 Feb 2013 03:50:25 -0800 (PST) Received: from localhost.localdomain ([188.151.50.237]) by mx.google.com with ESMTPS id l3sm39169095wiy.8.2013.02.12.03.50.18 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 12 Feb 2013 03:50:24 -0800 (PST) From: sjur.brandeland@stericsson.com To: Rusty Russell , "David S. Miller" , Ohad Ben-Cohen Cc: sjur@brendeland.net, netdev@vger.kernel.org, virtualization@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Dmitry Tarnyagin , Linus Walleij , Erwan Yvin , =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= , Ido Yariv Subject: [PATCHv2 vringh 1/3] remoteproc: Add support for vringh (Host vrings) Date: Tue, 12 Feb 2013 12:49:51 +0100 Message-Id: <1360669793-6921-2-git-send-email-sjur.brandeland@stericsson.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1360669793-6921-1-git-send-email-sjur.brandeland@stericsson.com> References: <1360669793-6921-1-git-send-email-sjur.brandeland@stericsson.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Sjur Brændeland Add functions for creating, deleting and kicking host-side virtio rings. The host ring is not integrated with virtiqueues and cannot be managed through virtio-config. Remoteproc must export functions for handling the host-side virtio rings. The functions rproc_virtio_get_vringh(), rproc_virtio_del_vringh(), rproc_virtio_kick_vringh() are added to remoteproc_virtio.c. The existing functions rproc_vq_interrupt() and rproc_virtio_find_vqs() are updated to handle the new vhost rings. Signed-off-by: Sjur Brændeland cc: Ohad Ben-Cohen cc: Rusty Russell cc: Ido Yariv cc: Erwan Yvin --- drivers/remoteproc/Kconfig | 3 + drivers/remoteproc/remoteproc_virtio.c | 127 ++++++++++++++++++++++++++++++-- include/linux/remoteproc.h | 14 ++++ 3 files changed, 137 insertions(+), 7 deletions(-) diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig index 96ce101..c7d1d36 100644 --- a/drivers/remoteproc/Kconfig +++ b/drivers/remoteproc/Kconfig @@ -7,6 +7,9 @@ config REMOTEPROC depends on HAS_DMA select FW_CONFIG select VIRTIO + select VHOST_RING + +source drivers/vhost/Kconfig config OMAP_REMOTEPROC tristate "OMAP remoteproc support" diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c index 9e198e5..fa7bf7b 100644 --- a/drivers/remoteproc/remoteproc_virtio.c +++ b/drivers/remoteproc/remoteproc_virtio.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -60,10 +61,15 @@ irqreturn_t rproc_vq_interrupt(struct rproc *rproc, int notifyid) dev_dbg(&rproc->dev, "vq index %d is interrupted\n", notifyid); rvring = idr_find(&rproc->notifyids, notifyid); - if (!rvring || !rvring->vq) + if (!rvring) return IRQ_NONE; - return vring_interrupt(0, rvring->vq); + if (rvring->vringh && rvring->vringh_cb) + return rvring->vringh_cb(&rvring->rvdev->vdev, rvring->vringh); + else if (rvring->vq) + return vring_interrupt(0, rvring->vq); + else + return IRQ_NONE; } EXPORT_SYMBOL(rproc_vq_interrupt); @@ -149,14 +155,21 @@ static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs, const char *names[]) { struct rproc *rproc = vdev_to_rproc(vdev); - int i, ret; + struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); + int rng, id, ret, nrings = ARRAY_SIZE(rvdev->vring); + + for (id = 0, rng = 0; rng < nrings; ++rng) { + struct rproc_vring *rvring = &rvdev->vring[rng]; + /* Skip the host side rings */ + if (rvring->vringh) + continue; - for (i = 0; i < nvqs; ++i) { - vqs[i] = rp_find_vq(vdev, i, callbacks[i], names[i]); - if (IS_ERR(vqs[i])) { - ret = PTR_ERR(vqs[i]); + vqs[id] = rp_find_vq(vdev, rng, callbacks[id], names[id]); + if (IS_ERR(vqs[id])) { + ret = PTR_ERR(vqs[id]); goto error; } + ++id; } /* now that the vqs are all set, boot the remote processor */ @@ -173,6 +186,106 @@ error: return ret; } +/** + * rproc_virtio_new_vringh() - create a reversed virtio ring. + * @vdev: the virtio device + * @index: the virtio ring index + * @cb: callback for the reversed virtio ring + * + * This function should be called by the virtio-driver + * before calling find_vqs(). It returns a struct vringh for + * accessing the virtio ring. + * + * Return: struct vhost, or NULL upon error. + */ +struct vringh * +rproc_virtio_new_vringh(struct virtio_device *vdev, unsigned index, + irqreturn_t (*cb)(struct virtio_device *vdev, + struct vringh *vring)) +{ + struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); + struct rproc_vring *rvring; + struct vringh *vrh; + int err; + + if (index > ARRAY_SIZE(rvdev->vring)) { + dev_err(&rvdev->vdev.dev, "bad vring index: %d\n", index); + return NULL; + } + + vrh = kzalloc(sizeof(*vrh), GFP_KERNEL); + if (!vrh) + return NULL; + + err = rproc_alloc_vring(rvdev, index); + if (err) + goto free_vring; + + + rvring = &rvdev->vring[index]; + /* zero vring */ + memset(rvring->va, 0, vring_size(rvring->len, rvring->align)); + vring_init(&vrh->vring, rvring->len, rvring->va, rvring->align); + + rvring->vringh_cb = cb; + rvring->vringh = vrh; + + err = vringh_init_kern(vrh, + rvdev->dfeatures, + rvring->len, + false, + vrh->vring.desc, + vrh->vring.avail, + vrh->vring.used); + if (!err) + return vrh; + + dev_err(&vdev->dev, "failed to create vhost: %d\n", err); + rproc_free_vring(rvring); +free_vring: + kfree(vrh); + return NULL; +} +EXPORT_SYMBOL(rproc_virtio_new_vringh); + +/** + * rproc_virtio_del_vringh() - release a reversed virtio ring. + * @vdev: the virtio device + * @index: the virtio ring index + * + * This function release the reversed virtio ring. + */ +void rproc_virtio_del_vringh(struct virtio_device *vdev, unsigned index) +{ + struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); + struct rproc_vring *rvring = &rvdev->vring[index]; + kfree(rvring->vringh); + rproc_free_vring(rvring); + rvring->vringh_cb = NULL; + rvring->vringh = NULL; +} +EXPORT_SYMBOL(rproc_virtio_del_vringh); + +/** + * rproc_virtio_kick_vringh() - kick the remote processor. + * @vdev: the virtio device + * @index: the virtio ring index + * + * kick the remote processor, and let it know which vring to poke at + */ +void rproc_virtio_kick_vringh(struct virtio_device *vdev, unsigned index) +{ + struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); + struct rproc_vring *rvring = &rvdev->vring[index]; + struct rproc *rproc = rvring->rvdev->rproc; + int notifyid = rvring->notifyid; + + dev_dbg(&rproc->dev, "kicking vq index: %d\n", notifyid); + + rproc->ops->kick(rproc, notifyid); +} +EXPORT_SYMBOL(rproc_virtio_kick_vringh); + /* * We don't support yet real virtio status semantics. * diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index faf3332..414a1fd 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -39,7 +39,9 @@ #include #include #include +#include #include +#include #include /** @@ -444,6 +446,8 @@ struct rproc { * @notifyid: rproc-specific unique vring index * @rvdev: remote vdev * @vq: the virtqueue of this vring + * @vringh_cb: callback used when device has kicked + * @vringh: the reversed host-side vring */ struct rproc_vring { void *va; @@ -454,6 +458,9 @@ struct rproc_vring { int notifyid; struct rproc_vdev *rvdev; struct virtqueue *vq; + irqreturn_t (*vringh_cb)(struct virtio_device *vdev, + struct vringh *vring); + struct vringh *vringh; }; /** @@ -485,6 +492,13 @@ int rproc_boot(struct rproc *rproc); void rproc_shutdown(struct rproc *rproc); void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type); +struct vringh * +rproc_virtio_new_vringh(struct virtio_device *vdev, unsigned index, + irqreturn_t (*cb)(struct virtio_device *vdev, + struct vringh *vring)); +void rproc_virtio_del_vringh(struct virtio_device *vdev, unsigned index); +void rproc_virtio_kick_vringh(struct virtio_device *vdev, unsigned index); + static inline struct rproc_vdev *vdev_to_rvdev(struct virtio_device *vdev) { return container_of(vdev, struct rproc_vdev, vdev);