Message ID | 20201121030156.22857-2-s-anna@ti.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | remoteproc sysfs fixes/improvements | expand |
On Fri, Nov 20, 2020 at 09:01:54PM -0600, Suman Anna wrote: > The remoteproc core performs automatic boot and shutdown of a remote > processor during rproc_add() and rproc_del() for remote processors > supporting 'auto-boot'. The remoteproc devices not using 'auto-boot' > require either a remoteproc client driver or a userspace client to > use the sysfs 'state' variable to perform the boot and shutdown. The > in-kernel client drivers hold the corresponding remoteproc driver > module's reference count when they acquire a rproc handle through > the rproc_get_by_phandle() API, but there is no such support for > userspace applications performing the boot through sysfs interface. > > The shutdown of a remoteproc upon removing a remoteproc platform > driver is automatic only with 'auto-boot' and this can cause a > remoteproc with no auto-boot to stay powered on and never freed > up if booted using the sysfs interface without a matching stop, > and when the remoteproc driver module is removed or unbound from > the device. This will result in a memory leak as well as the > corresponding remoteproc ida being never deallocated. Fix this > by holding a module reference count for the remoteproc's driver > during a sysfs 'start' and releasing it during the sysfs 'stop' > operation. > > Signed-off-by: Suman Anna <s-anna@ti.com> > Acked-by: Arnaud Pouliquen <arnaud.pouliquen@st.com> > --- > v2: rebased version, no changes > v1: https://patchwork.kernel.org/project/linux-remoteproc/patch/20180915003725.17549-2-s-anna@ti.com/ > > drivers/remoteproc/remoteproc_sysfs.c | 16 +++++++++++++++- > 1 file changed, 15 insertions(+), 1 deletion(-) > > diff --git a/drivers/remoteproc/remoteproc_sysfs.c b/drivers/remoteproc/remoteproc_sysfs.c > index d1cf7bf277c4..bd2950a246c9 100644 > --- a/drivers/remoteproc/remoteproc_sysfs.c > +++ b/drivers/remoteproc/remoteproc_sysfs.c > @@ -3,6 +3,7 @@ > * Remote Processor Framework > */ > > +#include <linux/module.h> > #include <linux/remoteproc.h> > #include <linux/slab.h> > > @@ -228,14 +229,27 @@ static ssize_t state_store(struct device *dev, > if (rproc->state == RPROC_RUNNING) > return -EBUSY; > > + /* > + * prevent underlying implementation from being removed > + * when remoteproc does not support auto-boot > + */ > + if (!rproc->auto_boot && > + !try_module_get(dev->parent->driver->owner)) > + return -EINVAL; > + > ret = rproc_boot(rproc); > - if (ret) > + if (ret) { > dev_err(&rproc->dev, "Boot failed: %d\n", ret); > + if (!rproc->auto_boot) > + module_put(dev->parent->driver->owner); > + } > } else if (sysfs_streq(buf, "stop")) { > if (rproc->state != RPROC_RUNNING) > return -EINVAL; > > rproc_shutdown(rproc); > + if (!rproc->auto_boot) > + module_put(dev->parent->driver->owner); I tackled the same problem by fixing another problem we had in the core. Patch 2 [1] and 3 [2] of this set [3] get rid of the problem related to the auto_boot check without having to deal with module counters. Please see if that covers the use case you are dealing with. Thanks, Mathieu [1]. https://patchwork.kernel.org/project/linux-remoteproc/patch/20201126210642.897302-3-mathieu.poirier@linaro.org/ [2]. https://patchwork.kernel.org/project/linux-remoteproc/patch/20201126210642.897302-4-mathieu.poirier@linaro.org/ [3]. https://patchwork.kernel.org/project/linux-remoteproc/list/?series=391789 > } else { > dev_err(&rproc->dev, "Unrecognised option: %s\n", buf); > ret = -EINVAL; > -- > 2.28.0 >
diff --git a/drivers/remoteproc/remoteproc_sysfs.c b/drivers/remoteproc/remoteproc_sysfs.c index d1cf7bf277c4..bd2950a246c9 100644 --- a/drivers/remoteproc/remoteproc_sysfs.c +++ b/drivers/remoteproc/remoteproc_sysfs.c @@ -3,6 +3,7 @@ * Remote Processor Framework */ +#include <linux/module.h> #include <linux/remoteproc.h> #include <linux/slab.h> @@ -228,14 +229,27 @@ static ssize_t state_store(struct device *dev, if (rproc->state == RPROC_RUNNING) return -EBUSY; + /* + * prevent underlying implementation from being removed + * when remoteproc does not support auto-boot + */ + if (!rproc->auto_boot && + !try_module_get(dev->parent->driver->owner)) + return -EINVAL; + ret = rproc_boot(rproc); - if (ret) + if (ret) { dev_err(&rproc->dev, "Boot failed: %d\n", ret); + if (!rproc->auto_boot) + module_put(dev->parent->driver->owner); + } } else if (sysfs_streq(buf, "stop")) { if (rproc->state != RPROC_RUNNING) return -EINVAL; rproc_shutdown(rproc); + if (!rproc->auto_boot) + module_put(dev->parent->driver->owner); } else { dev_err(&rproc->dev, "Unrecognised option: %s\n", buf); ret = -EINVAL;