mirror of https://gitee.com/openkylin/linux.git
V4L/DVB: gspca - main: Possible race condition in queue management
The problem may occur with SMP: - a frame is completed at interrupt level (in gspca_frame_add with packet_type == LAST_PACKET, - just after clearing the bit V4L2_BUF_FLAG_QUEUED and before setting the bit V4L2_BUF_FLAG_DONE, on the other processor, the application tries to requeue the same frame buffer, - then, the qbuf function succeeds because ALL_FLAGS are not set. The fix sets and resets the two flags in one instruction. Reported-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Jean-François Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
9059cd4440
commit
02bbcb9d86
|
@ -466,8 +466,9 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
|
|||
j = gspca_dev->fr_queue[i];
|
||||
frame = &gspca_dev->frame[j];
|
||||
frame->v4l2_buf.bytesused = gspca_dev->image_len;
|
||||
frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED;
|
||||
frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE;
|
||||
frame->v4l2_buf.flags = (frame->v4l2_buf.flags
|
||||
| V4L2_BUF_FLAG_DONE)
|
||||
& ~V4L2_BUF_FLAG_QUEUED;
|
||||
wake_up_interruptible(&gspca_dev->wq); /* event = new frame */
|
||||
i = (i + 1) % gspca_dev->nframes;
|
||||
gspca_dev->fr_i = i;
|
||||
|
|
Loading…
Reference in New Issue