linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Kieran Bingham <kieran.bingham@ideasonboard.com>
To: Kaaira Gupta <kgupta@es.iitr.ac.in>,
	Helen Koike <helen.koike@collabora.com>,
	Shuah Khan <skhan@linuxfoundation.org>,
	Mauro Carvalho Chehab <mchehab@kernel.org>,
	linux-media@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v3 5/9] media: vimc: Separate closing of stream and thread
Date: Wed, 2 Sep 2020 11:13:09 +0100	[thread overview]
Message-ID: <1614accb-dee5-1c0e-ece3-ecdd56f45253@ideasonboard.com> (raw)
In-Reply-To: <20200819180442.11630-6-kgupta@es.iitr.ac.in>

Hi Kaaira,

On 19/08/2020 19:04, Kaaira Gupta wrote:
> Make separate functions for stopping streaming of entities in path of a
> particular stream and stopping thread. This is needed to ensure that
> thread doesn't stop when one device stops streaming in case of multiple
> streams.
> 
> Signed-off-by: Kaaira Gupta <kgupta@es.iitr.ac.in>
> ---
>  .../media/test-drivers/vimc/vimc-streamer.c   | 82 ++++++++++++-------
>  1 file changed, 52 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/media/test-drivers/vimc/vimc-streamer.c b/drivers/media/test-drivers/vimc/vimc-streamer.c
> index cc40ecabe95a..6b5ea1537952 100644
> --- a/drivers/media/test-drivers/vimc/vimc-streamer.c
> +++ b/drivers/media/test-drivers/vimc/vimc-streamer.c
> @@ -13,29 +13,59 @@
>  #include "vimc-streamer.h"
>  
>  /**
> - * vimc_streamer_pipeline_terminate - Disable stream in all ved in stream
> + * vimc_streamer_pipeline_terminate - Terminate the thread
>   *
> - * @stream: the pointer to the stream structure with the pipeline to be
> - *	    disabled.
> + * @stream: the pointer to the stream structure
>   *
> - * Calls s_stream to disable the stream in each entity of the pipeline
> + * Erases values of stream struct and terminates the thread

It would help if the function brief described it's purpose rather than
'what it does'. "Erases values of stream struct" is not helpful here, as
that's just a direct read of what happens in the code.

I'm guessing here, but how about:

"Tear down all resources belonging to the pipeline when there are no
longer any active streams being used. This includes stopping the active
processing thread"


But reading my text makes me worry about the ordering that might take
place. The thread should be stopped as soon as the last stream using it
is stopped. Presumably as the 'first thing' that happens to make sure
there is no concurrent processing while the stream is being disabled.

Hopefully there's no race condition ...


>   *
>   */
>  static void vimc_streamer_pipeline_terminate(struct vimc_stream *stream)
>  {
>  	struct vimc_ent_device *ved;
> -	struct v4l2_subdev *sd;
>  
>  	while (stream->pipe_size) {
>  		stream->pipe_size--;
>  		ved = stream->ved_pipeline[stream->pipe_size];
>  		stream->ved_pipeline[stream->pipe_size] = NULL;
> +	}
>  
> -		if (!is_media_entity_v4l2_subdev(ved->ent))
> -			continue;
> +	kthread_stop(stream->kthread);
> +	stream->kthread = NULL;
> +}
>  
> -		sd = media_entity_to_v4l2_subdev(ved->ent);
> -		v4l2_subdev_call(sd, video, s_stream, 0);
> +/**
> + * vimc_streamer_stream_terminate - Disable stream in all ved in stream
> + *
> + * @ved: pointer to the ved for which stream needs to be disabled
> + *
> + * Calls s_stream to disable the stream in each entity of the stream
> + *
> + */
> +static void vimc_streamer_stream_terminate(struct vimc_ent_device *ved)

I would call this vimc_streamer_stream_stop to match
vimc_streamer_stream_start() rather than terminate...

> +{
> +	struct media_entity *entity = ved->ent;
> +	struct video_device *vdev;
> +	struct v4l2_subdev *sd;
> +
> +	while (entity) {
> +		if (is_media_entity_v4l2_subdev(ved->ent)) {
> +			sd = media_entity_to_v4l2_subdev(ved->ent);
> +			v4l2_subdev_call(sd, video, s_stream, 0);
> +		}
> +		entity = vimc_get_source_entity(ved->ent);
> +		if (!entity)
> +			break;
> +
> +		if (is_media_entity_v4l2_subdev(entity)) {
> +			sd = media_entity_to_v4l2_subdev(entity);
> +			ved = v4l2_get_subdevdata(sd);
> +		} else {
> +			vdev = container_of(entity,
> +					    struct video_device,
> +					    entity);
> +			ved = video_get_drvdata(vdev);
> +		}

It looks like this is walking back through the linked graph, calling
s_stream(0) right?

I wonder if struct vimc_ent_device should have a pointer to the entity
it's connected to, to simplify this. ... presumably this is done
elsewhere too?

Although then that's still walking 'backwards' rather than forwards...




>  	}
>  }
>  
> @@ -43,25 +73,25 @@ static void vimc_streamer_pipeline_terminate(struct vimc_stream *stream)
>   * vimc_streamer_stream_start - Starts streaming for all entities
>   * in a stream
>   *
> - * @ved:    the pointer to the vimc entity initializing the stream
> + * @cved:    the pointer to the vimc entity initializing the stream
>   *
>   * Walks through the entity graph to call vimc_streamer_s_stream()
>   * to enable stream in all entities in path of a stream.
>   *
>   * Return: 0 if success, error code otherwise.
>   */
> -static int vimc_streamer_stream_start(struct vimc_stream *stream,
> -				      struct vimc_ent_device *ved)
> +static int vimc_streamer_stream_start(struct vimc_ent_device *cved)
>  {
>  	struct media_entity *entity;
>  	struct video_device *vdev;
>  	struct v4l2_subdev *sd;
> +	struct vimc_ent_device *ved = cved;
>  	int stream_size = 0;
>  	int ret = 0;
>  
>  	while (stream_size < VIMC_STREAMER_PIPELINE_MAX_SIZE) {
>  		if (!ved) {
> -			vimc_streamer_pipeline_terminate(stream);
> +			vimc_streamer_stream_terminate(cved);
>  			return -EINVAL;
>  		}
>  
> @@ -71,7 +101,7 @@ static int vimc_streamer_stream_start(struct vimc_stream *stream,
>  			if (ret && ret != -ENOIOCTLCMD) {
>  				dev_err(ved->dev, "subdev_call error %s\n",
>  					ved->ent->name);
> -				vimc_streamer_pipeline_terminate(stream);
> +				vimc_streamer_stream_terminate(cved);
>  				return ret;
>  			}
>  		}
> @@ -84,7 +114,7 @@ static int vimc_streamer_stream_start(struct vimc_stream *stream,
>  				dev_err(ved->dev,
>  					"first entity in the pipe '%s' is not a source\n",
>  					ved->ent->name);
> -				vimc_streamer_pipeline_terminate(stream);
> +				vimc_streamer_stream_terminate(cved);
>  				pr_info ("first entry not source");
>  				return -EPIPE;
>  			}
> @@ -104,7 +134,7 @@ static int vimc_streamer_stream_start(struct vimc_stream *stream,
>  		stream_size++;
>  	}
>  
> -	vimc_streamer_pipeline_terminate(stream);
> +	vimc_streamer_stream_terminate(cved);
>  	return -EINVAL;
>  }
>  
> @@ -120,13 +150,14 @@ static int vimc_streamer_stream_start(struct vimc_stream *stream,
>   * Return: 0 if success, error code otherwise.
>   */
>  static int vimc_streamer_pipeline_init(struct vimc_stream *stream,
> -				       struct vimc_ent_device *ved)
> +				       struct vimc_ent_device *cved)
>  {
>  	struct media_entity *entity;
>  	struct media_device *mdev;
>  	struct media_graph graph;
>  	struct video_device *vdev;
>  	struct v4l2_subdev *sd;
> +	struct vimc_ent_device *ved = cved;
>  	int ret;
>  
>  	entity = ved->ent;
> @@ -170,6 +201,7 @@ static int vimc_streamer_pipeline_init(struct vimc_stream *stream,
>  		}
>  	}
>  
> +	vimc_streamer_stream_terminate(cved);
>  	vimc_streamer_pipeline_terminate(stream);
>  	return -EINVAL;
>  }
> @@ -246,7 +278,7 @@ int vimc_streamer_s_stream(struct vimc_stream *stream,
>  		if (stream->kthread)
>  			return 0;
>  
> -		ret = vimc_streamer_stream_start(stream, ved);
> +		ret = vimc_streamer_stream_start(ved);
>  		if (ret)
>  			return ret;
>  
> @@ -260,6 +292,7 @@ int vimc_streamer_s_stream(struct vimc_stream *stream,
>  		if (IS_ERR(stream->kthread)) {
>  			ret = PTR_ERR(stream->kthread);
>  			dev_err(ved->dev, "kthread_run failed with %d\n", ret);
> +			vimc_streamer_stream_terminate(ved);
>  			vimc_streamer_pipeline_terminate(stream);
>  			stream->kthread = NULL;

If vimc_streamer_pipeline_terminate() sets stream->kthread = NULL, it
doesn't need to be done again here.


>  			return ret;
> @@ -269,18 +302,7 @@ int vimc_streamer_s_stream(struct vimc_stream *stream,
>  		if (!stream->kthread)
>  			return 0;
>  
> -		ret = kthread_stop(stream->kthread);
> -		/*
> -		 * kthread_stop returns -EINTR in cases when streamon was
> -		 * immediately followed by streamoff, and the thread didn't had
> -		 * a chance to run. Ignore errors to stop the stream in the
> -		 * pipeline.
> -		 */

Do we need to retain that comment when stopping the thread?

> -		if (ret)
> -			dev_dbg(ved->dev, "kthread_stop returned '%d'\n", ret);
> -
> -		stream->kthread = NULL;
> -
> +		vimc_streamer_stream_terminate(ved);
>  		vimc_streamer_pipeline_terminate(stream);
>  	}
>  
> 

-- 
Regards
--
Kieran

  reply	other threads:[~2020-09-02 10:13 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-19 18:04 [PATCH v3 0/9] media: vimc: Multiple stream support in vimc Kaaira Gupta
2020-08-19 18:04 ` [PATCH v3 1/9] media: vimc: Move get_source_entity to vimc-common Kaaira Gupta
2020-08-20 15:32   ` Kieran Bingham
2020-08-19 18:04 ` [PATCH v3 2/9] media: vimc: Add get_frame callback Kaaira Gupta
2020-08-20 15:36   ` Kieran Bingham
2020-09-12 10:01     ` Kaaira Gupta
2020-10-02 11:08     ` Dafna Hirschfeld
2020-08-19 18:04 ` [PATCH v3 3/9] media: vimc: Add usage count to subdevices Kaaira Gupta
2020-10-02 11:13   ` Dafna Hirschfeld
2020-08-19 18:04 ` [PATCH v3 4/9] media: vimc: Separate starting stream from pipeline initialisation Kaaira Gupta
2020-08-21 15:11   ` Dafna Hirschfeld
2020-08-21 21:01     ` Kaaira Gupta
2020-08-28 20:37       ` Dafna Hirschfeld
2020-09-02  9:56         ` Kieran Bingham
2020-09-12 10:21           ` Kaaira Gupta
2020-09-12 10:16         ` Kaaira Gupta
2020-08-19 18:04 ` [PATCH v3 5/9] media: vimc: Separate closing of stream and thread Kaaira Gupta
2020-09-02 10:13   ` Kieran Bingham [this message]
2020-09-12 10:28     ` Kaaira Gupta
2020-08-19 18:04 ` [PATCH v3 6/9] media: vimc: Serialize vimc_streamer_s_stream() Kaaira Gupta
2020-08-19 18:04 ` [PATCH v3 7/9] media: vimc: Dynamically allocate stream struct Kaaira Gupta
2020-09-02 10:29   ` Kieran Bingham
2020-09-12 10:39     ` Kaaira Gupta
2020-08-19 18:04 ` [PATCH v3 8/9] media: vimc: Join pipeline if one already exists Kaaira Gupta
2020-09-02 10:40   ` Kieran Bingham
2020-08-19 18:04 ` [PATCH v3 9/9] media: vimc: Run multiple captures on same thread Kaaira Gupta
2020-09-02 10:46   ` Kieran Bingham
2020-09-12 10:45     ` Kaaira Gupta
2020-09-02 10:51 ` [PATCH v3 0/9] media: vimc: Multiple stream support in vimc Kieran Bingham
2020-09-12 10:49   ` Kaaira Gupta

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1614accb-dee5-1c0e-ece3-ecdd56f45253@ideasonboard.com \
    --to=kieran.bingham@ideasonboard.com \
    --cc=helen.koike@collabora.com \
    --cc=kgupta@es.iitr.ac.in \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=mchehab@kernel.org \
    --cc=skhan@linuxfoundation.org \
    --subject='Re: [PATCH v3 5/9] media: vimc: Separate closing of stream and thread' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).