[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:
Родитель
3425382288
Коммит
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_video *video = vb2_get_drv_priv(vq);
|
||||||
struct vsp1_pipeline *pipe = video->rwpf->pipe;
|
struct vsp1_pipeline *pipe = video->rwpf->pipe;
|
||||||
|
bool start_pipeline = false;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -807,11 +808,23 @@ static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count)
|
||||||
mutex_unlock(&pipe->lock);
|
mutex_unlock(&pipe->lock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
start_pipeline = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pipe->stream_count++;
|
pipe->stream_count++;
|
||||||
mutex_unlock(&pipe->lock);
|
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);
|
spin_lock_irqsave(&pipe->irqlock, flags);
|
||||||
if (vsp1_pipeline_ready(pipe))
|
if (vsp1_pipeline_ready(pipe))
|
||||||
vsp1_video_pipeline_run(pipe);
|
vsp1_video_pipeline_run(pipe);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче