Re: [PATCH v3 12/14] remoteproc: Introducing function rproc_set_state_machine()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Apr 29, 2020 at 11:22:28AM +0200, Arnaud POULIQUEN wrote:
> 
> 
> On 4/24/20 10:01 PM, Mathieu Poirier wrote:
> > Introducting function rproc_set_state_machine() to add
> > operations and a set of flags to use when synchronising with
> > a remote processor.
> > 
> > Signed-off-by: Mathieu Poirier <mathieu.poirier@xxxxxxxxxx>
> > ---
> >  drivers/remoteproc/remoteproc_core.c     | 54 ++++++++++++++++++++++++
> >  drivers/remoteproc/remoteproc_internal.h |  6 +++
> >  include/linux/remoteproc.h               |  3 ++
> >  3 files changed, 63 insertions(+)
> > 
> > diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
> > index 48afa1f80a8f..5c48714e8702 100644
> > --- a/drivers/remoteproc/remoteproc_core.c
> > +++ b/drivers/remoteproc/remoteproc_core.c
> > @@ -2065,6 +2065,59 @@ int devm_rproc_add(struct device *dev, struct rproc *rproc)
> >  }
> >  EXPORT_SYMBOL(devm_rproc_add);
> >  
> > +/**
> > + * rproc_set_state_machine() - Set a synchronisation ops and set of flags
> > + *			       to use with a remote processor
> > + * @rproc:	The remote processor to work with
> > + * @sync_ops:	The operations to use when synchronising with a remote
> > + *		processor
> > + * @sync_flags:	The flags to use when deciding if the remoteproc core
> > + *		should be synchronising with a remote processor
> > + *
> > + * Returns 0 on success, an error code otherwise.
> > + */
> > +int rproc_set_state_machine(struct rproc *rproc,
> > +			    const struct rproc_ops *sync_ops,
> > +			    struct rproc_sync_flags sync_flags)
> 
> So this API should be called by platform driver only in case of synchronization
> support, right?

Correct

> In this case i would rename it as there is also a state machine in "normal" boot
> proposal: rproc_set_sync_machine or rproc_set_sync_state_machine

That is a valid observation - rproc_set_sync_state_machine() sounds descriptive
enough for me.

> 
> > +{
> > +	if (!rproc || !sync_ops)
> > +		return -EINVAL;
> > +
> > +	/*
> > +	 * No point in going further if we never have to synchronise with
> > +	 * the remote processor.
> > +	 */
> > +	if (!sync_flags.on_init &&
> > +	    !sync_flags.after_stop && !sync_flags.after_crash)
> > +		return 0;
> > +
> > +	/*
> > +	 * Refuse to go further if remoteproc operations have been allocated
> > +	 * but they will never be used.
> > +	 */
> > +	if (rproc->ops && sync_flags.on_init &&
> > +	    sync_flags.after_stop && sync_flags.after_crash)
> > +		return -EINVAL;
> > +
> > +	/*
> > +	 * Don't allow users to set this more than once to avoid situations
> > +	 * where the remote processor can't be recovered.
> > +	 */
> > +	if (rproc->sync_ops)
> > +		return -EINVAL;
> > +
> > +	rproc->sync_ops = kmemdup(sync_ops, sizeof(*sync_ops), GFP_KERNEL);
> > +	if (!rproc->sync_ops)
> > +		return -ENOMEM;
> > +
> > +	rproc->sync_flags = sync_flags;
> > +	/* Tell the core what to do when initialising */
> > +	rproc_set_sync_flag(rproc, RPROC_SYNC_STATE_INIT);
> 
> Is there a use case where sync_flags.on_init is false and other flags are true?

I haven't seen one yet, which doesn't mean it doesn't exist or won't in the
future.  I wanted to make this as flexible as possible.  I started with the idea
of making synchronisation at initialisation time implicit if
rproc_set_state_machine() is called but I know it is only a matter of time
before people come up with some exotic use case where .on_init is false.

> 
> Look like on_init is useless and should not be exposed to the platform driver.
> Or comments are missing to explain the usage of it vs the other flags.

Comments added in remoteproc_internal.h and the new section in
Documentation/remoteproc.txt aren't sufficient?  Can you give me a hint as to
what you think is missing?

> 
> Regards,
> Arnaud
>  
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL(rproc_set_state_machine);
> > +
> >  /**
> >   * rproc_type_release() - release a remote processor instance
> >   * @dev: the rproc's device
> > @@ -2088,6 +2141,7 @@ static void rproc_type_release(struct device *dev)
> >  	kfree_const(rproc->firmware);
> >  	kfree_const(rproc->name);
> >  	kfree(rproc->ops);
> > +	kfree(rproc->sync_ops);
> >  	kfree(rproc);
> >  }
> >  
> > diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h
> > index 7dcc0a26892b..c1a293a37c78 100644
> > --- a/drivers/remoteproc/remoteproc_internal.h
> > +++ b/drivers/remoteproc/remoteproc_internal.h
> > @@ -27,6 +27,8 @@ struct rproc_debug_trace {
> >  /*
> >   * enum rproc_sync_states - remote processsor sync states
> >   *
> > + * @RPROC_SYNC_STATE_INIT	state to use when the remoteproc core
> > + *				is initialising.
> >   * @RPROC_SYNC_STATE_SHUTDOWN	state to use after the remoteproc core
> >   *				has shutdown (rproc_shutdown()) the
> >   *				remote processor.
> > @@ -39,6 +41,7 @@ struct rproc_debug_trace {
> >   * operation to use.
> >   */
> >  enum rproc_sync_states {
> > +	RPROC_SYNC_STATE_INIT,
> >  	RPROC_SYNC_STATE_SHUTDOWN,
> >  	RPROC_SYNC_STATE_CRASHED,
> >  };
> > @@ -47,6 +50,9 @@ static inline void rproc_set_sync_flag(struct rproc *rproc,
> >  				       enum rproc_sync_states state)
> >  {
> >  	switch (state) {
> > +	case RPROC_SYNC_STATE_INIT:
> > +		rproc->sync_with_rproc = rproc->sync_flags.on_init;
> > +		break;
> >  	case RPROC_SYNC_STATE_SHUTDOWN:
> >  		rproc->sync_with_rproc = rproc->sync_flags.after_stop;
> >  		break;
> > diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
> > index ceb3b2bba824..a75ed92b3de6 100644
> > --- a/include/linux/remoteproc.h
> > +++ b/include/linux/remoteproc.h
> > @@ -619,6 +619,9 @@ struct rproc *rproc_get_by_child(struct device *dev);
> >  struct rproc *rproc_alloc(struct device *dev, const char *name,
> >  			  const struct rproc_ops *ops,
> >  			  const char *firmware, int len);
> > +int rproc_set_state_machine(struct rproc *rproc,
> > +			    const struct rproc_ops *sync_ops,
> > +			    struct rproc_sync_flags sync_flags);
> >  void rproc_put(struct rproc *rproc);
> >  int rproc_add(struct rproc *rproc);
> >  int rproc_del(struct rproc *rproc);
> > 



[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux