[media] v4l: vsp1: Prevent multiple streamon race commencing pipeline early
With multiple inputs through the BRU it is feasible for the streams to race each other at stream-on. Multiple VIDIOC_STREAMON calls racing each other could have process N-1 skipping over the pipeline setup section and then start the pipeline early, if videobuf2 has already enqueued buffers to the driver for process N but not called the .start_streaming() operation yet 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 Repair this issue, by ensuring that only the stream which configures the pipeline is able to start it. Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
This commit is contained in:
parent
3425382288
commit
4461c84b52
|
@ -797,6 +797,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;
|
||||
bool start_pipeline = false;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
|
@ -807,11 +808,23 @@ static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count)
|
|||
mutex_unlock(&pipe->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
start_pipeline = true;
|
||||
}
|
||||
|
||||
pipe->stream_count++;
|
||||
mutex_unlock(&pipe->lock);
|
||||
|
||||
/*
|
||||
* vsp1_pipeline_ready() is not sufficient to establish that all streams
|
||||
* are prepared and the pipeline is configured, as multiple streams
|
||||
* can race through streamon with buffers already queued; Therefore we
|
||||
* don't even attempt to start the pipeline until the last stream has
|
||||
* called through here.
|
||||
*/
|
||||
if (!start_pipeline)
|
||||
return 0;
|
||||
|
||||
spin_lock_irqsave(&pipe->irqlock, flags);
|
||||
if (vsp1_pipeline_ready(pipe))
|
||||
vsp1_video_pipeline_run(pipe);
|
||||
|
|
Loading…
Reference in New Issue