em38xx locking question
Mauro,
Function drivers/media/usb/em28xx/em28xx-video.c:get_next_buf (copy pasted below for reference) does not take the list spinlock, yet it modifies the list. Is that correct?
static inline struct em28xx_buffer *get_next_buf(struct em28xx *dev,
struct em28xx_dmaqueue *dma_q)
{
struct em28xx_buffer *buf;
if (list_empty(&dma_q->active)) {
em28xx_isocdbg("No active queue to serve\n");
return NULL;
}
/* Get the next buffer */
buf = list_entry(dma_q->active.next, struct em28xx_buffer, list);
/* Cleans up buffer - Useful for testing for frame/URB loss */
list_del(&buf->list);
buf->pos = 0;
buf->vb_buf = buf->mem;
return buf;
}Thanks!
Signature · 2 lines
Ezequiel Garcia, VanguardiaSur www.vanguardiasur.com.ar
Quoted 5 lines · Ezequiel Garcia
Mauro,
Function drivers/media/usb/em28xx/em28xx-video.c:get_next_buf (copy pasted below for reference) does not take the list spinlock, yet it modifies the list. Is that correct?
That looks wrong to me. You really need spinlocks here.
Regards,
Hans
Quoted 23 lines
static inline struct
em28xx_buffer*get_next_buf(struct em28xx *dev,
structem28xx_dmaqueue*dma_q){ struct em28xx_buffer *buf; if (list_empty(&dma_q->active)) { em28xx_isocdbg("No active queue to serve\n"); return NULL; } /* Get the next buffer */ buf = list_entry(dma_q->active.next, struct em28xx_buffer, list); /* Cleans up buffer - Useful for testing for frame/URB loss */ list_del(&buf->list); buf->pos = 0; buf->vb_buf = buf->mem; return buf; }Thanks!
Quoted 9 lines · Hans Verkuil
Quoted 5 lines · Ezequiel Garcia
Mauro,
Function drivers/media/usb/em28xx/em28xx-video.c:get_next_buf (copy pasted below for reference) does not take the list spinlock, yet it modifies the list. Is that correct?
That looks wrong to me. You really need spinlocks here.
OK, second question then. Is there any way to guarantee the URBs irq handler is *not* running, when vb2_ops are called (e.g. stop_streaming)?
Otherwise, given stop_streaming will return the current buffer to vb2 (dev->usb_ctl.vid_buf), I believe that will race against the irq handler, which is processing it.
It seems that's currently racy as well.
Signature · 2 lines
Ezequiel Garcia, VanguardiaSur www.vanguardiasur.com.ar
Quoted 10 lines · Ezequiel Garcia
Quoted 7 lines · Hans Verkuil
Quoted 5 lines · Ezequiel Garcia
Mauro,
Function drivers/media/usb/em28xx/em28xx-video.c:get_next_buf (copy pasted below for reference) does not take the list spinlock, yet it modifies the list. Is that correct?
Quoted 5 lines
Quoted 2 lines
That looks wrong to me. You really need spinlocks here.
OK, second question then. Is there any way to guarantee the URBs irq handler is *not* running, when
vb2_opsare called (e.g.stop_streaming)?
That depends on the op. But stop_streaming is the op that is supposed to turn off the streaming (and thus the irq), so it depends on the order of how things are done in that function.
Quoted 5 lines
Otherwise, given
stop_streamingwill return the current buffer to vb2 (dev->usb_ctl.vid_buf), I believe that will race against the irq handler, which is processing it.It seems that's currently racy as well.
Hmm, the stop_streaming code looks fine at first sight, but I think there is a race if you start streaming both video and vbi, and then stop streaming one of the two. I think the code might keep calling get_next_buf() in that case, even if for that stream the streaming was stopped.
This is a problem anyway: get_next_buf() should do this check at the beginning:
if (!vb2_start_streaming_called(vb2_queue)) return NULL;
to prevent it from using buffer before start_streaming was actually called.
Regards,
Hans
Quoted 14 lines · Hans Verkuil
Quoted 13 lines · Ezequiel Garcia
Quoted 9 lines · Hans Verkuil
Quoted 5 lines · Ezequiel Garcia
Mauro,
Function drivers/media/usb/em28xx/em28xx-video.c:get_next_buf (copy pasted below for reference) does not take the list spinlock, yet it modifies the list. Is that correct?
That looks wrong to me. You really need spinlocks here.
Quoted 7 lines
Quoted 2 lines
OK, second question then. Is there any way to guarantee the URBs irq handler is *not* running, when
vb2_opsare called (e.g.stop_streaming)?That depends on the op. But
stop_streamingis the op that is supposed to turn off the streaming (and thus the irq), so it depends on the order of how things are done in that function.
Ah, right. As long as you kill the urbs before you try to access the current buffer, everything is OK.
Quoted 12 lines
Quoted 6 lines
Otherwise, given
stop_streamingwill return the current buffer to vb2 (dev->usb_ctl.vid_buf), I believe that will race against the irq handler, which is processing it.It seems that's currently racy as well.
Hmm, the
stop_streamingcode looks fine at first sight, but I think there is a race if you start streaming both video and vbi, and then stop streaming one of the two. I think the code might keep callingget_next_buf()in that case, even if for that stream the streaming was stopped.
Quoted 7 lines
This is a problem anyway:
get_next_buf()should do this check at the beginning:if (!vb2_start_streaming_called(vb2_queue)) return NULL;to prevent it from using buffer before
start_streamingwas actually called.
I'd say get_next_buf() is called only in the URB complete handler path, and hence only after start_streaming. However, maybe there's a subtle issue here: URB complete handler can be called _while_ start_streaming is still running.
Signature · 2 lines
Ezequiel Garcia, VanguardiaSur www.vanguardiasur.com.ar
Quoted 42 lines · Ezequiel Garcia
Quoted 14 lines · Hans Verkuil
Quoted 13 lines · Ezequiel Garcia
Quoted 9 lines · Hans Verkuil
Quoted 5 lines · Ezequiel Garcia
Mauro,
Function drivers/media/usb/em28xx/em28xx-video.c:get_next_buf (copy pasted below for reference) does not take the list spinlock, yet it modifies the list. Is that correct?
That looks wrong to me. You really need spinlocks here.
Quoted 7 lines
Quoted 2 lines
OK, second question then. Is there any way to guarantee the URBs irq handler is *not* running, when
vb2_opsare called (e.g.stop_streaming)?That depends on the op. But
stop_streamingis the op that is supposed to turn off the streaming (and thus the irq), so it depends on the order of how things are done in that function.Ah, right. As long as you kill the urbs before you try to access the current buffer, everything is OK.
Quoted 14 lines
Quoted 6 lines
Otherwise, given
stop_streamingwill return the current buffer to vb2 (dev->usb_ctl.vid_buf), I believe that will race against the irq handler, which is processing it.It seems that's currently racy as well.
Hmm, the
stop_streamingcode looks fine at first sight, but I think there is a race if you start streaming both video and vbi, and then stop streaming one of the two. I think the code might keep callingget_next_buf()in that case, even if for that stream the streaming was stopped.This is a problem anyway:
get_next_buf()should do this check at the beginning:
Quoted 8 lines
Quoted 5 lines
if (!vb2_start_streaming_called(vb2_queue)) return NULL;to prevent it from using buffer before
start_streamingwas actually called.I'd say
get_next_buf()is called only in the URB complete handler path, and hence only afterstart_streaming.
Well, no. If you are streaming just video and then start streaming vbi in addition to the video, then I think get_next_buf() can be called for the VBI stream before start_streaming is called for that VBI stream.
Hans
Quoted 4 lines
However, maybe there's a subtle
issue here: URB complete handler can be called _while_start_streamingis still running.