2021-03-11 14:05:59

by Arnaud Pouliquen

[permalink] [raw]
Subject: [PATCH 0/6] rpmsg: enable the use of the rpmsg_char device for the Virtio backend

This series is the first step in the division of the series:
"Introduce a generic IOCTL interface for RPMsg channels management"[1]

The main goal here is to enable the RPMsg char interface for
the virtio RPMsg backend.

In addition some patches have been includes in order to document the
interface and rename the rpmsg_char_init function.

It also includes Mathieu Poirier's comments made on [1]

Patchsets that should be the next steps:
- Extract the control part of the char dev and create the rpmsg_ctrl.c
file
- Introduce the RPMSG_CREATE_DEV_IOCTL IOCTL to instantiate RPMsg devices


[1]: https://patchwork.kernel.org/project/linux-remoteproc/list/?series=435523

Arnaud Pouliquen (6):
rpmsg: char: Rename rpmsg_char_init to rpmsg_chrdev_init
rpmsg: Move RPMSG_ADDR_ANY in user API
rpmsg: Add short description of the IOCTL defined in UAPI.
rpmsg: char: Use rpmsg_sendto to specify the message destination
address
rpmsg: virtio: Register the rpmsg_char device
rpmsg: char: Return an error if device already open

drivers/rpmsg/qcom_glink_native.c | 16 ++++++++
drivers/rpmsg/qcom_smd.c | 16 ++++++++
drivers/rpmsg/rpmsg_char.c | 11 ++++--
drivers/rpmsg/virtio_rpmsg_bus.c | 62 ++++++++++++++++++++++++++++---
include/linux/rpmsg.h | 3 +-
include/uapi/linux/rpmsg.h | 13 ++++++-
6 files changed, 108 insertions(+), 13 deletions(-)

--
2.17.1


2021-03-11 14:06:03

by Arnaud Pouliquen

[permalink] [raw]
Subject: [PATCH 1/6] rpmsg: char: Rename rpmsg_char_init to rpmsg_chrdev_init

To be coherent with the other functions which are prefixed by
rpmsg_chrdev, rename the rpmsg_char_init function.

Signed-off-by: Arnaud Pouliquen <[email protected]>
---
drivers/rpmsg/rpmsg_char.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/rpmsg/rpmsg_char.c b/drivers/rpmsg/rpmsg_char.c
index 4bbbacdbf3bb..9e33b53bbf56 100644
--- a/drivers/rpmsg/rpmsg_char.c
+++ b/drivers/rpmsg/rpmsg_char.c
@@ -543,7 +543,7 @@ static struct rpmsg_driver rpmsg_chrdev_driver = {
},
};

-static int rpmsg_char_init(void)
+static int rpmsg_chrdev_init(void)
{
int ret;

@@ -569,7 +569,7 @@ static int rpmsg_char_init(void)

return ret;
}
-postcore_initcall(rpmsg_char_init);
+postcore_initcall(rpmsg_chrdev_init);

static void rpmsg_chrdev_exit(void)
{
--
2.17.1

2021-03-11 14:06:07

by Arnaud Pouliquen

[permalink] [raw]
Subject: [PATCH 3/6] rpmsg: Add short description of the IOCTL defined in UAPI.

Add a description of the IOCTLs and provide information on the default
value of the source and destination addresses.

Signed-off-by: Arnaud Pouliquen <[email protected]>
---
include/uapi/linux/rpmsg.h | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/include/uapi/linux/rpmsg.h b/include/uapi/linux/rpmsg.h
index 5e00748da319..f5ca8740f3fb 100644
--- a/include/uapi/linux/rpmsg.h
+++ b/include/uapi/linux/rpmsg.h
@@ -14,8 +14,8 @@
/**
* struct rpmsg_endpoint_info - endpoint info representation
* @name: name of service
- * @src: local address
- * @dst: destination address
+ * @src: local address. To set to RPMSG_ADDR_ANY if not used.
+ * @dst: destination address. To set to RPMSG_ADDR_ANY if not used.
*/
struct rpmsg_endpoint_info {
char name[32];
@@ -23,7 +23,14 @@ struct rpmsg_endpoint_info {
__u32 dst;
};

+/**
+ * Instantiate a new rmpsg char device endpoint.
+ */
#define RPMSG_CREATE_EPT_IOCTL _IOW(0xb5, 0x1, struct rpmsg_endpoint_info)
+
+/**
+ * Destroy a rpmsg char device endpoint created by the RPMSG_CREATE_EPT_IOCTL.
+ */
#define RPMSG_DESTROY_EPT_IOCTL _IO(0xb5, 0x2)

#endif
--
2.17.1

2021-03-11 14:06:10

by Arnaud Pouliquen

[permalink] [raw]
Subject: [PATCH 5/6] rpmsg: virtio: Register the rpmsg_char device

Instantiate the rpmsg_char device on virtio RPMsg bus creation.
This provides the capability, with the RPMSG_CREATE_EPT_IOCTL ioctl,
to create RPMsg char device endpoints relying on the
rpmsg_chrdev_create_eptdev API.

Notice that the created endpoints are attached to the rpmsg_ctldev
device, but not associated to a channel.
As consequence, the endpoint source and destination addresses have to
been specified and there is no channel creation and no name service
announcement to inform the remote side.

Signed-off-by: Arnaud Pouliquen <[email protected]>
---

update vs [1]
- rework the changelog
- remove useless rpdev_ns pointer initialisation.

[1]: https://patchwork.kernel.org/project/linux-remoteproc/patch/[email protected]/

---
drivers/rpmsg/virtio_rpmsg_bus.c | 62 +++++++++++++++++++++++++++++---
1 file changed, 57 insertions(+), 5 deletions(-)

diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c
index e87d4cf926eb..8e49a3bacfc7 100644
--- a/drivers/rpmsg/virtio_rpmsg_bus.c
+++ b/drivers/rpmsg/virtio_rpmsg_bus.c
@@ -813,14 +813,57 @@ static void rpmsg_xmit_done(struct virtqueue *svq)
wake_up_interruptible(&vrp->sendq);
}

+/*
+ * Called to expose to user a /dev/rpmsg_ctrlX interface allowing to
+ * create endpoint-to-endpoint communication without associated RPMsg channel.
+ * The endpoints are rattached to the ctrldev RPMsg device.
+ */
+static struct rpmsg_device *rpmsg_virtio_add_ctrl_dev(struct virtio_device *vdev)
+{
+ struct virtproc_info *vrp = vdev->priv;
+ struct virtio_rpmsg_channel *vch;
+ struct rpmsg_device *rpdev_ctrl;
+ int err = 0;
+
+ vch = kzalloc(sizeof(*vch), GFP_KERNEL);
+ if (!vch)
+ return ERR_PTR(-ENOMEM);
+
+ /* Link the channel to the vrp */
+ vch->vrp = vrp;
+
+ /* Assign public information to the rpmsg_device */
+ rpdev_ctrl = &vch->rpdev;
+ rpdev_ctrl->ops = &virtio_rpmsg_ops;
+
+ rpdev_ctrl->dev.parent = &vrp->vdev->dev;
+ rpdev_ctrl->dev.release = virtio_rpmsg_release_device;
+ rpdev_ctrl->little_endian = virtio_is_little_endian(vrp->vdev);
+
+ err = rpmsg_chrdev_register_device(rpdev_ctrl);
+ if (err) {
+ kfree(vch);
+ return ERR_PTR(err);
+ }
+
+ return rpdev_ctrl;
+}
+
+static void rpmsg_virtio_del_ctrl_dev(struct rpmsg_device *rpdev_ctrl)
+{
+ if (!rpdev_ctrl)
+ return;
+ kfree(to_virtio_rpmsg_channel(rpdev_ctrl));
+}
+
static int rpmsg_probe(struct virtio_device *vdev)
{
vq_callback_t *vq_cbs[] = { rpmsg_recv_done, rpmsg_xmit_done };
static const char * const names[] = { "input", "output" };
struct virtqueue *vqs[2];
struct virtproc_info *vrp;
- struct virtio_rpmsg_channel *vch;
- struct rpmsg_device *rpdev_ns;
+ struct virtio_rpmsg_channel *vch = NULL;
+ struct rpmsg_device *rpdev_ns, *rpdev_ctrl;
void *bufs_va;
int err = 0, i;
size_t total_buf_space;
@@ -894,12 +937,18 @@ static int rpmsg_probe(struct virtio_device *vdev)

vdev->priv = vrp;

+ rpdev_ctrl = rpmsg_virtio_add_ctrl_dev(vdev);
+ if (IS_ERR(rpdev_ctrl)) {
+ err = PTR_ERR(rpdev_ctrl);
+ goto free_coherent;
+ }
+
/* if supported by the remote processor, enable the name service */
if (virtio_has_feature(vdev, VIRTIO_RPMSG_F_NS)) {
vch = kzalloc(sizeof(*vch), GFP_KERNEL);
if (!vch) {
err = -ENOMEM;
- goto free_coherent;
+ goto free_ctrldev;
}

/* Link the channel to our vrp */
@@ -915,7 +964,7 @@ static int rpmsg_probe(struct virtio_device *vdev)

err = rpmsg_ns_register_device(rpdev_ns);
if (err)
- goto free_coherent;
+ goto free_vch;
}

/*
@@ -939,8 +988,11 @@ static int rpmsg_probe(struct virtio_device *vdev)

return 0;

-free_coherent:
+free_vch:
kfree(vch);
+free_ctrldev:
+ rpmsg_virtio_del_ctrl_dev(rpdev_ctrl);
+free_coherent:
dma_free_coherent(vdev->dev.parent, total_buf_space,
bufs_va, vrp->bufs_dma);
vqs_del:
--
2.17.1

2021-03-11 14:06:31

by Arnaud Pouliquen

[permalink] [raw]
Subject: [PATCH 6/6] rpmsg: char: Return an error if device already open

The rpmsg_create_ept function is invoked when the device is opened.
As only one endpoint must be created per device. It is not possible to
open the same device twice. But there is nothing to prevent multi open.
Return -EBUSY when device is already opened to have a generic error
instead of relying on the back-end to potentially detect the error.

Without this patch for instance the GLINK driver return -EBUSY while
the virtio bus return -ENOSPC.

Signed-off-by: Arnaud Pouliquen <[email protected]>
---
drivers/rpmsg/rpmsg_char.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/rpmsg/rpmsg_char.c b/drivers/rpmsg/rpmsg_char.c
index 95a65f7a9d8d..2bebc9b2d163 100644
--- a/drivers/rpmsg/rpmsg_char.c
+++ b/drivers/rpmsg/rpmsg_char.c
@@ -127,6 +127,9 @@ static int rpmsg_eptdev_open(struct inode *inode, struct file *filp)
struct rpmsg_device *rpdev = eptdev->rpdev;
struct device *dev = &eptdev->dev;

+ if (eptdev->ept)
+ return -EBUSY;
+
get_device(dev);

ept = rpmsg_create_ept(rpdev, rpmsg_ept_cb, eptdev, eptdev->chinfo);
--
2.17.1

2021-03-11 14:07:24

by Arnaud Pouliquen

[permalink] [raw]
Subject: [PATCH 4/6] rpmsg: char: Use rpmsg_sendto to specify the message destination address

When the endpoint device is created by the application, a destination
address is specified in the rpmsg_channel_info structure. Since the
rpmsg_endpoint structure does not store the destination address,
this destination address must be specified when sending a message.

Replaces rpmsg_send with rpmsg_sendto to allow to specify the
destination address. This implementation is requested for compatibly with
some rpmsg backends like the virtio backend.

For this, the GLINK an SMD drivers have been updated to support the
rpmsg_sendto, even if the destination address is ignored for these
backends. For these drivers, the rpmsg_send and rpmsg_trysend ops are
preserved to avoid breaking the legacy.

Signed-off-by: Arnaud Pouliquen <[email protected]>

---
update vs [1]
squash following patches in one:
rpmsg: glink: add sendto and trysendto ops
rpmsg: smd: add sendto and trysendto ops
rpmsg: char: use sendto to specify the message destination address

[1]: https://patchwork.kernel.org/project/linux-remoteproc/list/?series=435523

---
drivers/rpmsg/qcom_glink_native.c | 16 ++++++++++++++++
drivers/rpmsg/qcom_smd.c | 16 ++++++++++++++++
drivers/rpmsg/rpmsg_char.c | 4 ++--
3 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c
index 27a05167c18c..edae0c9a8236 100644
--- a/drivers/rpmsg/qcom_glink_native.c
+++ b/drivers/rpmsg/qcom_glink_native.c
@@ -1332,6 +1332,20 @@ static int qcom_glink_trysend(struct rpmsg_endpoint *ept, void *data, int len)
return __qcom_glink_send(channel, data, len, false);
}

+static int qcom_glink_sendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst)
+{
+ struct glink_channel *channel = to_glink_channel(ept);
+
+ return __qcom_glink_send(channel, data, len, true);
+}
+
+static int qcom_glink_trysendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst)
+{
+ struct glink_channel *channel = to_glink_channel(ept);
+
+ return __qcom_glink_send(channel, data, len, false);
+}
+
/*
* Finds the device_node for the glink child interested in this channel.
*/
@@ -1364,7 +1378,9 @@ static const struct rpmsg_device_ops glink_device_ops = {
static const struct rpmsg_endpoint_ops glink_endpoint_ops = {
.destroy_ept = qcom_glink_destroy_ept,
.send = qcom_glink_send,
+ .sendto = qcom_glink_sendto,
.trysend = qcom_glink_trysend,
+ .trysendto = qcom_glink_trysendto,
};

static void qcom_glink_rpdev_release(struct device *dev)
diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c
index 19903de6268d..8da1b5cb31b3 100644
--- a/drivers/rpmsg/qcom_smd.c
+++ b/drivers/rpmsg/qcom_smd.c
@@ -974,6 +974,20 @@ static int qcom_smd_trysend(struct rpmsg_endpoint *ept, void *data, int len)
return __qcom_smd_send(qsept->qsch, data, len, false);
}

+static int qcom_smd_sendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst)
+{
+ struct qcom_smd_endpoint *qsept = to_smd_endpoint(ept);
+
+ return __qcom_smd_send(qsept->qsch, data, len, true);
+}
+
+static int qcom_smd_trysendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst)
+{
+ struct qcom_smd_endpoint *qsept = to_smd_endpoint(ept);
+
+ return __qcom_smd_send(qsept->qsch, data, len, false);
+}
+
static __poll_t qcom_smd_poll(struct rpmsg_endpoint *ept,
struct file *filp, poll_table *wait)
{
@@ -1038,7 +1052,9 @@ static const struct rpmsg_device_ops qcom_smd_device_ops = {
static const struct rpmsg_endpoint_ops qcom_smd_endpoint_ops = {
.destroy_ept = qcom_smd_destroy_ept,
.send = qcom_smd_send,
+ .sendto = qcom_smd_sendto,
.trysend = qcom_smd_trysend,
+ .trysendto = qcom_smd_trysendto,
.poll = qcom_smd_poll,
};

diff --git a/drivers/rpmsg/rpmsg_char.c b/drivers/rpmsg/rpmsg_char.c
index 9e33b53bbf56..95a65f7a9d8d 100644
--- a/drivers/rpmsg/rpmsg_char.c
+++ b/drivers/rpmsg/rpmsg_char.c
@@ -239,9 +239,9 @@ static ssize_t rpmsg_eptdev_write_iter(struct kiocb *iocb,
}

if (filp->f_flags & O_NONBLOCK)
- ret = rpmsg_trysend(eptdev->ept, kbuf, len);
+ ret = rpmsg_trysendto(eptdev->ept, kbuf, len, eptdev->chinfo.dst);
else
- ret = rpmsg_send(eptdev->ept, kbuf, len);
+ ret = rpmsg_sendto(eptdev->ept, kbuf, len, eptdev->chinfo.dst);

unlock_eptdev:
mutex_unlock(&eptdev->ept_lock);
--
2.17.1

2021-03-11 14:08:34

by Arnaud Pouliquen

[permalink] [raw]
Subject: [PATCH 2/6] rpmsg: Move RPMSG_ADDR_ANY in user API

As the RPMSG_ADDR_ANY is a valid src or dst address that can be set by
user applications, migrate its definition in user API.

Signed-off-by: Arnaud Pouliquen <[email protected]>
---
include/linux/rpmsg.h | 3 +--
include/uapi/linux/rpmsg.h | 2 ++
2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/linux/rpmsg.h b/include/linux/rpmsg.h
index a5db828b2420..d97dcd049f18 100644
--- a/include/linux/rpmsg.h
+++ b/include/linux/rpmsg.h
@@ -18,8 +18,7 @@
#include <linux/mutex.h>
#include <linux/poll.h>
#include <linux/rpmsg/byteorder.h>
-
-#define RPMSG_ADDR_ANY 0xFFFFFFFF
+#include <uapi/linux/rpmsg.h>

struct rpmsg_device;
struct rpmsg_endpoint;
diff --git a/include/uapi/linux/rpmsg.h b/include/uapi/linux/rpmsg.h
index e14c6dab4223..5e00748da319 100644
--- a/include/uapi/linux/rpmsg.h
+++ b/include/uapi/linux/rpmsg.h
@@ -9,6 +9,8 @@
#include <linux/ioctl.h>
#include <linux/types.h>

+#define RPMSG_ADDR_ANY 0xFFFFFFFF
+
/**
* struct rpmsg_endpoint_info - endpoint info representation
* @name: name of service
--
2.17.1

2021-03-11 23:41:39

by Bjorn Andersson

[permalink] [raw]
Subject: Re: [PATCH 0/6] rpmsg: enable the use of the rpmsg_char device for the Virtio backend

On Thu 11 Mar 08:04 CST 2021, Arnaud Pouliquen wrote:

> This series is the first step in the division of the series:
> "Introduce a generic IOCTL interface for RPMsg channels management"[1]
>
> The main goal here is to enable the RPMsg char interface for
> the virtio RPMsg backend.
>
> In addition some patches have been includes in order to document the
> interface and rename the rpmsg_char_init function.
>
> It also includes Mathieu Poirier's comments made on [1]
>
> Patchsets that should be the next steps:
> - Extract the control part of the char dev and create the rpmsg_ctrl.c
> file
> - Introduce the RPMSG_CREATE_DEV_IOCTL IOCTL to instantiate RPMsg devices
>
>
> [1]: https://patchwork.kernel.org/project/linux-remoteproc/list/?series=435523
>

Reviewed-by: Bjorn Andersson <[email protected]>

Regards,
Bjorn

> Arnaud Pouliquen (6):
> rpmsg: char: Rename rpmsg_char_init to rpmsg_chrdev_init
> rpmsg: Move RPMSG_ADDR_ANY in user API
> rpmsg: Add short description of the IOCTL defined in UAPI.
> rpmsg: char: Use rpmsg_sendto to specify the message destination
> address
> rpmsg: virtio: Register the rpmsg_char device
> rpmsg: char: Return an error if device already open
>
> drivers/rpmsg/qcom_glink_native.c | 16 ++++++++
> drivers/rpmsg/qcom_smd.c | 16 ++++++++
> drivers/rpmsg/rpmsg_char.c | 11 ++++--
> drivers/rpmsg/virtio_rpmsg_bus.c | 62 ++++++++++++++++++++++++++++---
> include/linux/rpmsg.h | 3 +-
> include/uapi/linux/rpmsg.h | 13 ++++++-
> 6 files changed, 108 insertions(+), 13 deletions(-)
>
> --
> 2.17.1
>

2021-03-15 16:19:13

by Mathieu Poirier

[permalink] [raw]
Subject: Re: [PATCH 0/6] rpmsg: enable the use of the rpmsg_char device for the Virtio backend

On Thu, Mar 11, 2021 at 03:04:07PM +0100, Arnaud Pouliquen wrote:
> This series is the first step in the division of the series:
> "Introduce a generic IOCTL interface for RPMsg channels management"[1]
>
> The main goal here is to enable the RPMsg char interface for
> the virtio RPMsg backend.
>
> In addition some patches have been includes in order to document the
> interface and rename the rpmsg_char_init function.
>
> It also includes Mathieu Poirier's comments made on [1]
>
> Patchsets that should be the next steps:
> - Extract the control part of the char dev and create the rpmsg_ctrl.c
> file
> - Introduce the RPMSG_CREATE_DEV_IOCTL IOCTL to instantiate RPMsg devices
>
>
> [1]: https://patchwork.kernel.org/project/linux-remoteproc/list/?series=435523
>
> Arnaud Pouliquen (6):
> rpmsg: char: Rename rpmsg_char_init to rpmsg_chrdev_init
> rpmsg: Move RPMSG_ADDR_ANY in user API
> rpmsg: Add short description of the IOCTL defined in UAPI.
> rpmsg: char: Use rpmsg_sendto to specify the message destination
> address
> rpmsg: virtio: Register the rpmsg_char device
> rpmsg: char: Return an error if device already open
>
> drivers/rpmsg/qcom_glink_native.c | 16 ++++++++
> drivers/rpmsg/qcom_smd.c | 16 ++++++++
> drivers/rpmsg/rpmsg_char.c | 11 ++++--
> drivers/rpmsg/virtio_rpmsg_bus.c | 62 ++++++++++++++++++++++++++++---
> include/linux/rpmsg.h | 3 +-
> include/uapi/linux/rpmsg.h | 13 ++++++-
> 6 files changed, 108 insertions(+), 13 deletions(-)

Reviewed-by: Mathieu Poirier <[email protected]>

>
> --
> 2.17.1
>