With multiple inputs through the BRU it is feasible for the streams to race each other at stream-on. In the case of the video pipelines, this can present two serious issues.
1) A null-dereference if the pipe->dl is committed at the same time as the vsp1_video_setup_pipeline() is processing 2) A hardware hang, where a display list is committed without having called vsp1_video_setup_pipeline() first. To prevent these scenarios from occurring, we ensure that only the thread that calls the vsp1_video_setup_pipeline() is capable of committing and commencing the display list. Signed-off-by: Kieran Bingham <kieran.bingham+rene...@ideasonboard.com> --- I considered a few options to fix this issue. If anyone disagrees with my reasoning, and believes one of the below approaches should be used, let me know and I'll rework the patch. A) Moving the vsp1_video_pipeline_run() call into the upper if block. - This changes the locking, and brings in unneccessary nested locking B) Adapting vsp1_pipeline_ready() such that it checks for a configured pipeline event as well. - This was tempting - but this particular issue is local to this function only. Changing vsp1_pipeline_ready() to watch for a flag set by vsp1_video_setup_pipeline() would require adding unneccessary changes to the vsp1_drm objects to cater for this. To test this race, I have used the vsp-unit-test-0007.sh from Laurent's VSP-Tests [0] in iteration. Without this patch, failures can be seen be seen anywhere up to the 150 iterations mark. With this patch in place, tests have successfully iterated over 1500 loops. The function affected by this change appears to have been around since v4.6-rc2-105-g351bbf99f245 and thus may want inclusion in stable trees from that point forward. The issue may have been prevalent before that but the solution would need reworking for earlier version. [0] http://git.ideasonboard.com/renesas/vsp-tests.git drivers/media/platform/vsp1/vsp1_video.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index 94b428596c4f..cc44b27f3e47 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -813,6 +813,7 @@ static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count) struct vsp1_video *video = vb2_get_drv_priv(vq); struct vsp1_pipeline *pipe = video->rwpf->pipe; unsigned long flags; + bool configured = false; int ret; mutex_lock(&pipe->lock); @@ -822,13 +823,20 @@ static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count) mutex_unlock(&pipe->lock); return ret; } + + /* + * Multiple streams will execute this function in parallel. + * Only the thread which configures the pipeline is allowed to + * execute the vsp1_video_pipeline_run() call below + */ + configured = true; } pipe->stream_count++; mutex_unlock(&pipe->lock); spin_lock_irqsave(&pipe->irqlock, flags); - if (vsp1_pipeline_ready(pipe)) + if (vsp1_pipeline_ready(pipe) && configured) vsp1_video_pipeline_run(pipe); spin_unlock_irqrestore(&pipe->irqlock, flags); -- 2.7.4