Re: [PATCH 1/2] remoteproc: Add userspace char device driver
From: Mathieu Poirier
Date: Mon Mar 30 2020 - 18:12:52 EST
On Thu, Mar 26, 2020 at 09:50:39AM -0700, Rishabh Bhatnagar wrote:
> Add the driver for creating the character device interface for
> userspace applications. The character device interface can be used
> in order to boot up and shutdown the remote processor.
> This might be helpful for remote processors that are booted by
> userspace applications and need to shutdown when the application
> crahes/shutsdown.
>
> Change-Id: If23c8986272bb7c943eb76665f127ff706f12394
On my side checkpatch is complaining loudly that Change-Id tags should be
removed... I wonder how you didn't get it on your side.
> Signed-off-by: Rishabh Bhatnagar <rishabhb@xxxxxxxxxxxxxx>
> ---
> drivers/remoteproc/Makefile | 1 +
> drivers/remoteproc/remoteproc_internal.h | 6 +++
> drivers/remoteproc/remoteproc_userspace.c | 90 +++++++++++++++++++++++++++++++
> include/linux/remoteproc.h | 2 +
> 4 files changed, 99 insertions(+)
> create mode 100644 drivers/remoteproc/remoteproc_userspace.c
>
> diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
> index e30a1b1..facb3fa 100644
> --- a/drivers/remoteproc/Makefile
> +++ b/drivers/remoteproc/Makefile
> @@ -7,6 +7,7 @@ obj-$(CONFIG_REMOTEPROC) += remoteproc.o
> remoteproc-y := remoteproc_core.o
> remoteproc-y += remoteproc_debugfs.o
> remoteproc-y += remoteproc_sysfs.o
> +remoteproc-y += remoteproc_userspace.o
> remoteproc-y += remoteproc_virtio.o
> remoteproc-y += remoteproc_elf_loader.o
> obj-$(CONFIG_IMX_REMOTEPROC) += imx_rproc.o
> diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h
> index 493ef92..97513ba 100644
> --- a/drivers/remoteproc/remoteproc_internal.h
> +++ b/drivers/remoteproc/remoteproc_internal.h
> @@ -47,6 +47,9 @@ struct dentry *rproc_create_trace_file(const char *name, struct rproc *rproc,
> int rproc_init_sysfs(void);
> void rproc_exit_sysfs(void);
>
> +void rproc_init_cdev(void);
> +void rproc_exit_cdev(void);
> +
> void rproc_free_vring(struct rproc_vring *rvring);
> int rproc_alloc_vring(struct rproc_vdev *rvdev, int i);
>
> @@ -63,6 +66,9 @@ struct resource_table *rproc_elf_find_loaded_rsc_table(struct rproc *rproc,
> struct rproc_mem_entry *
> rproc_find_carveout_by_name(struct rproc *rproc, const char *name, ...);
>
> +/* from remoteproc_userspace.c */
> +int rproc_char_device_add(struct rproc *rproc);
> +
> static inline
> int rproc_fw_sanity_check(struct rproc *rproc, const struct firmware *fw)
> {
> diff --git a/drivers/remoteproc/remoteproc_userspace.c b/drivers/remoteproc/remoteproc_userspace.c
> new file mode 100644
> index 0000000..2ef7679
> --- /dev/null
> +++ b/drivers/remoteproc/remoteproc_userspace.c
> @@ -0,0 +1,90 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Character device interface driver for Remoteproc framework.
> + *
> + * Copyright (c) 2020, The Linux Foundation. All rights reserved.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/fs.h>
> +#include <linux/cdev.h>
> +#include <linux/mutex.h>
> +#include <linux/remoteproc.h>
Alphabetical oder.
> +
> +#include "remoteproc_internal.h"
> +
> +#define NUM_RPROC_DEVICES 64
> +static dev_t rproc_cdev;
> +static DEFINE_IDA(cdev_minor_ida);
> +
> +static int rproc_open(struct inode *inode, struct file *file)
> +{
> + struct rproc *rproc;
> +
> + rproc = container_of(inode->i_cdev, struct rproc, char_dev);
> + if (!rproc)
> + return -EINVAL;
> +
> + return rproc_boot(rproc);
> +}
> +
> +static int rproc_release(struct inode *inode, struct file *file)
> +{
This function declaration conflicts with the one already defined in
remoteproc_internal.h. Again, I wonder how you didn't hit that problem when you
compiled this patch.
> + struct rproc *rproc;
> +
> + rproc = container_of(inode->i_cdev, struct rproc, char_dev);
> + if (!rproc)
> + return -EINVAL;
> +
> + rproc_shutdown(rproc);
The scenario I see here is that a userspace program will call
open(/dev/rproc_xyz, SOME_OPTION) when it is launched. The file stays open
until either the application shuts down, in which case it calls close() or it
crashes. In that case the system will automatically close all file descriptors
that were open by the application, which will also call rproc_shutdown().
To me the same functionality can be achieved with the current functionality
provided by sysfs.
When the application starts it needs to read
"/sys/class/remoteproc/remoteprocX/state". If the state is "offline" then
"start" should be written to "/sys/.../state". If the state is "running" the
application just crashed and got restarted. In which case it needs to stop the
remote processor and start it again.
> +
> + return 0;
> +}
> +
> +static const struct file_operations rproc_fops = {
> + .open = rproc_open,
> + .release = rproc_release,
> +};
> +
> +int rproc_char_device_add(struct rproc *rproc)
> +{
> + int ret, minor;
> + dev_t cdevt;
> +
> + minor = ida_simple_get(&cdev_minor_ida, 0, NUM_RPROC_DEVICES,
> + GFP_KERNEL);
Indentation issue.
> + if (minor < 0) {
> + pr_err("%s: No more minor numbers left! rc:%d\n", __func__,
Here to...
> + minor);
And here.
> + return -ENODEV;
> + }
> +
> + cdev_init(&rproc->char_dev, &rproc_fops);
> + rproc->char_dev.owner = THIS_MODULE;
> +
> + cdevt = MKDEV(MAJOR(rproc_cdev), minor);
> + ret = cdev_add(&rproc->char_dev, cdevt, 1);
> + if (ret < 0)
> + ida_simple_remove(&cdev_minor_ida, minor);
If the module is removed unregister_chrdev_region() is called but I don't see
anywhere in there that cdev_del() is called.
> +
> + rproc->dev.devt = cdevt;
> +
> + return ret;
> +}
> +
> +void __init rproc_init_cdev(void)
> +{
> + int ret;
> +
> + ret = alloc_chrdev_region(&rproc_cdev, 0, NUM_RPROC_DEVICES, "rproc");
> + if (ret < 0) {
> + pr_err("Failed to alloc rproc_cdev region, err %d\n", ret);
> + return;
> + }
> +}
> +
> +void __exit rproc_exit_cdev(void)
> +{
> + unregister_chrdev_region(MKDEV(MAJOR(rproc_cdev), 0),
> + NUM_RPROC_DEVICES);
Indentation problem.
> +}
> diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
> index 16ad666..c4ca796 100644
> --- a/include/linux/remoteproc.h
> +++ b/include/linux/remoteproc.h
> @@ -37,6 +37,7 @@
>
> #include <linux/types.h>
> #include <linux/mutex.h>
> +#include <linux/cdev.h>
> #include <linux/virtio.h>
> #include <linux/completion.h>
> #include <linux/idr.h>
> @@ -514,6 +515,7 @@ struct rproc {
> bool auto_boot;
> struct list_head dump_segments;
> int nb_vdev;
> + struct cdev char_dev;
The next time you send a patchset, please compile it and run checkpatch on it.
Thanks,
Mathieu
> };
>
> /**
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project