Re: [PATCH V7 3/3] rpmsg: char: Add RPMSG GET/SET FLOWCONTROL IOCTL support

From: Bjorn Andersson
Date: Wed Jun 14 2023 - 11:38:26 EST


On Sat, Apr 22, 2023 at 04:12:07PM +0530, Sarannya S wrote:
> From: Chris Lew <quic_clew@xxxxxxxxxxx>
>
> Add RPMSG_GET_OUTGOING_FLOWCONTROL and RPMSG_SET_INCOMING_FLOWCONTROL
> IOCTL support for rpmsg char device nodes to get/set the low level
> transport signals.
>
> Signed-off-by: Chris Lew <quic_clew@xxxxxxxxxxx>
> Signed-off-by: Deepak Kumar Singh <quic_deesin@xxxxxxxxxxx>
> Signed-off-by: Sarannya S <quic_sarannya@xxxxxxxxxxx>
> ---
> drivers/rpmsg/rpmsg_char.c | 49 ++++++++++++++++++++++++++++++++++++++++------
> include/uapi/linux/rpmsg.h | 11 ++++++++++-
> 2 files changed, 53 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/rpmsg/rpmsg_char.c b/drivers/rpmsg/rpmsg_char.c
> index a271fce..d50908f 100644
> --- a/drivers/rpmsg/rpmsg_char.c
> +++ b/drivers/rpmsg/rpmsg_char.c
> @@ -23,6 +23,7 @@
> #include <linux/rpmsg.h>
> #include <linux/skbuff.h>
> #include <linux/slab.h>
> +#include <linux/termios.h>
> #include <linux/uaccess.h>
> #include <uapi/linux/rpmsg.h>
>
> @@ -68,6 +69,8 @@ struct rpmsg_eptdev {
> struct sk_buff_head queue;
> wait_queue_head_t readq;
>
> + bool remote_flow;

I was about to agree with Arnaud, that this needs to be defaulted to
true. But the flag means "has the remote asked for flow to be limited".

As such, the name of this variable is misleading. Please rename it
"remote_flow_restricted" or something like that.

And please update the kerneldoc for this struct.

Regards,
Bjorn

> + bool remote_flow_updated;
> };
>
> int rpmsg_chrdev_eptdev_destroy(struct device *dev, void *data)
> @@ -116,6 +119,18 @@ static int rpmsg_ept_cb(struct rpmsg_device *rpdev, void *buf, int len,
> return 0;
> }
>
> +static int rpmsg_ept_flow_cb(struct rpmsg_device *rpdev, void *priv, bool enable)
> +{
> + struct rpmsg_eptdev *eptdev = priv;
> +
> + eptdev->remote_flow = enable;
> + eptdev->remote_flow_updated = true;
> +
> + wake_up_interruptible(&eptdev->readq);
> +
> + return 0;
> +}
> +
> static int rpmsg_eptdev_open(struct inode *inode, struct file *filp)
> {
> struct rpmsg_eptdev *eptdev = cdev_to_eptdev(inode->i_cdev);
> @@ -152,6 +167,7 @@ static int rpmsg_eptdev_open(struct inode *inode, struct file *filp)
> return -EINVAL;
> }
>
> + ept->flow_cb = rpmsg_ept_flow_cb;
> eptdev->ept = ept;
> filp->private_data = eptdev;
> mutex_unlock(&eptdev->ept_lock);
> @@ -172,6 +188,7 @@ static int rpmsg_eptdev_release(struct inode *inode, struct file *filp)
> eptdev->ept = NULL;
> }
> mutex_unlock(&eptdev->ept_lock);
> + eptdev->remote_flow_updated = false;
>
> /* Discard all SKBs */
> skb_queue_purge(&eptdev->queue);
> @@ -285,6 +302,9 @@ static __poll_t rpmsg_eptdev_poll(struct file *filp, poll_table *wait)
> if (!skb_queue_empty(&eptdev->queue))
> mask |= EPOLLIN | EPOLLRDNORM;
>
> + if (eptdev->remote_flow_updated)
> + mask |= EPOLLPRI;
> +
> mutex_lock(&eptdev->ept_lock);
> mask |= rpmsg_poll(eptdev->ept, filp, wait);
> mutex_unlock(&eptdev->ept_lock);
> @@ -297,14 +317,31 @@ static long rpmsg_eptdev_ioctl(struct file *fp, unsigned int cmd,
> {
> struct rpmsg_eptdev *eptdev = fp->private_data;
>
> - if (cmd != RPMSG_DESTROY_EPT_IOCTL)
> - return -EINVAL;
> + bool set;
> + int ret;
>
> - /* Don't allow to destroy a default endpoint. */
> - if (eptdev->default_ept)
> - return -EINVAL;
> + switch (cmd) {
> + case RPMSG_GET_OUTGOING_FLOWCONTROL:
> + eptdev->remote_flow_updated = false;
> + ret = put_user(eptdev->remote_flow, (int __user *)arg);
> + break;
> + case RPMSG_SET_INCOMING_FLOWCONTROL:
> + set = !!arg;
> + ret = rpmsg_set_flow_control(eptdev->ept, set, eptdev->chinfo.dst);
> + break;
> + case RPMSG_DESTROY_EPT_IOCTL:
> + /* Don't allow to destroy a default endpoint. */
> + if (eptdev->default_ept) {
> + ret = -EINVAL;
> + break;
> + }
> + ret = rpmsg_chrdev_eptdev_destroy(&eptdev->dev, NULL);
> + break;
> + default:
> + ret = -EINVAL;
> + }
>
> - return rpmsg_chrdev_eptdev_destroy(&eptdev->dev, NULL);
> + return ret;
> }
>
> static const struct file_operations rpmsg_eptdev_fops = {
> diff --git a/include/uapi/linux/rpmsg.h b/include/uapi/linux/rpmsg.h
> index 1637e68..c955e27 100644
> --- a/include/uapi/linux/rpmsg.h
> +++ b/include/uapi/linux/rpmsg.h
> @@ -10,7 +10,6 @@
> #include <linux/types.h>
>
> #define RPMSG_ADDR_ANY 0xFFFFFFFF
> -
> /**
> * struct rpmsg_endpoint_info - endpoint info representation
> * @name: name of service
> @@ -43,4 +42,14 @@ struct rpmsg_endpoint_info {
> */
> #define RPMSG_RELEASE_DEV_IOCTL _IOW(0xb5, 0x4, struct rpmsg_endpoint_info)
>
> +/**
> + * Set the flow control for the remote rpmsg char device.
> + */
> +#define RPMSG_GET_OUTGOING_FLOWCONTROL _IOW(0xb5, 0x5, struct rpmsg_endpoint_info)
> +
> +/**
> + * Set the flow control for the local rpmsg char device.
> + */
> +#define RPMSG_SET_INCOMING_FLOWCONTROL _IOW(0xb5, 0x6, struct rpmsg_endpoint_info)
> +
> #endif
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
>