Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

V4L/DVB: videobuf: add queue argument to videobuf_waiton()

videobuf_waiton() must unlock and relock ext_lock if it has to wait.
For that to happen it needs the videobuf_queue pointer.

Don't attempt to unlock/relock q->ext_lock unless it was locked in the
first place.

vb->state has to be protected by a spinlock to be safe.

This patch is based on code from Mauro Carvalho Chehab <mchehab@redhat.com>.

[mchehab@redhat.com: add extra argument to a few missing places]
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

authored by

Hans Verkuil and committed by
Mauro Carvalho Chehab
0e0809a5 08bff03e

+60 -38
+1 -1
drivers/media/common/saa7146_fops.c
··· 56 56 57 57 BUG_ON(in_interrupt()); 58 58 59 - videobuf_waiton(&buf->vb,0,0); 59 + videobuf_waiton(q, &buf->vb, 0, 0); 60 60 videobuf_dma_unmap(q->dev, dma); 61 61 videobuf_dma_free(dma); 62 62 buf->vb.state = VIDEOBUF_NEEDS_INIT;
+1 -1
drivers/media/video/bt8xx/bttv-risc.c
··· 582 582 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); 583 583 584 584 BUG_ON(in_interrupt()); 585 - videobuf_waiton(&buf->vb,0,0); 585 + videobuf_waiton(q, &buf->vb, 0, 0); 586 586 videobuf_dma_unmap(q->dev, dma); 587 587 videobuf_dma_free(dma); 588 588 btcx_riscmem_free(btv->c.pci,&buf->bottom);
+1 -1
drivers/media/video/cx23885/cx23885-core.c
··· 1221 1221 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); 1222 1222 1223 1223 BUG_ON(in_interrupt()); 1224 - videobuf_waiton(&buf->vb, 0, 0); 1224 + videobuf_waiton(q, &buf->vb, 0, 0); 1225 1225 videobuf_dma_unmap(q->dev, dma); 1226 1226 videobuf_dma_free(dma); 1227 1227 btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc);
+1 -1
drivers/media/video/cx88/cx88-core.c
··· 217 217 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); 218 218 219 219 BUG_ON(in_interrupt()); 220 - videobuf_waiton(&buf->vb,0,0); 220 + videobuf_waiton(q, &buf->vb, 0, 0); 221 221 videobuf_dma_unmap(q->dev, dma); 222 222 videobuf_dma_free(dma); 223 223 btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc);
+1 -1
drivers/media/video/fsl-viu.c
··· 426 426 427 427 BUG_ON(in_interrupt()); 428 428 429 - videobuf_waiton(&buf->vb, 0, 0); 429 + videobuf_waiton(vq, &buf->vb, 0, 0); 430 430 431 431 if (vq->int_ops && vq->int_ops->vaddr) 432 432 vaddr = vq->int_ops->vaddr(vb);
+1 -1
drivers/media/video/mem2mem_testdev.c
··· 848 848 849 849 videobuf_queue_vmalloc_init(vq, &m2mtest_qops, ctx->dev->v4l2_dev.dev, 850 850 &ctx->dev->irqlock, type, V4L2_FIELD_NONE, 851 - sizeof(struct m2mtest_buffer), priv); 851 + sizeof(struct m2mtest_buffer), priv, NULL); 852 852 } 853 853 854 854
+1 -1
drivers/media/video/mx1_camera.c
··· 161 161 * This waits until this buffer is out of danger, i.e., until it is no 162 162 * longer in STATE_QUEUED or STATE_ACTIVE 163 163 */ 164 - videobuf_waiton(vb, 0, 0); 164 + videobuf_waiton(vq, vb, 0, 0); 165 165 videobuf_dma_contig_free(vq, vb); 166 166 167 167 vb->state = VIDEOBUF_NEEDS_INIT;
+1 -1
drivers/media/video/mx2_camera.c
··· 463 463 * This waits until this buffer is out of danger, i.e., until it is no 464 464 * longer in STATE_QUEUED or STATE_ACTIVE 465 465 */ 466 - videobuf_waiton(vb, 0, 0); 466 + videobuf_waiton(vq, vb, 0, 0); 467 467 468 468 videobuf_dma_contig_free(vq, vb); 469 469 dev_dbg(&icd->dev, "%s freed\n", __func__);
+1 -1
drivers/media/video/mx3_camera.c
··· 185 185 * This waits until this buffer is out of danger, i.e., until it is no 186 186 * longer in STATE_QUEUED or STATE_ACTIVE 187 187 */ 188 - videobuf_waiton(vb, 0, 0); 188 + videobuf_waiton(vq, vb, 0, 0); 189 189 if (txd) { 190 190 ichan = to_idmac_chan(txd->chan); 191 191 async_tx_ack(txd);
+1 -1
drivers/media/video/omap24xxcam.c
··· 420 420 struct videobuf_dmabuf *dma = videobuf_to_dma(vb); 421 421 422 422 /* wait for buffer, especially to get out of the sgdma queue */ 423 - videobuf_waiton(vb, 0, 0); 423 + videobuf_waiton(vbq, vb, 0, 0); 424 424 if (vb->memory == V4L2_MEMORY_MMAP) { 425 425 dma_unmap_sg(vbq->dev, dma->sglist, dma->sglen, 426 426 dma->direction);
+1 -1
drivers/media/video/pxa_camera.c
··· 275 275 * This waits until this buffer is out of danger, i.e., until it is no 276 276 * longer in STATE_QUEUED or STATE_ACTIVE 277 277 */ 278 - videobuf_waiton(&buf->vb, 0, 0); 278 + videobuf_waiton(vq, &buf->vb, 0, 0); 279 279 videobuf_dma_unmap(vq->dev, dma); 280 280 videobuf_dma_free(dma); 281 281
+1 -1
drivers/media/video/saa7134/saa7134-core.c
··· 255 255 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); 256 256 BUG_ON(in_interrupt()); 257 257 258 - videobuf_waiton(&buf->vb,0,0); 258 + videobuf_waiton(q, &buf->vb, 0, 0); 259 259 videobuf_dma_unmap(q->dev, dma); 260 260 videobuf_dma_free(dma); 261 261 buf->vb.state = VIDEOBUF_NEEDS_INIT;
+1 -1
drivers/media/video/sh_mobile_ceu_camera.c
··· 245 245 if (in_interrupt()) 246 246 BUG(); 247 247 248 - videobuf_waiton(&buf->vb, 0, 0); 248 + videobuf_waiton(vq, &buf->vb, 0, 0); 249 249 videobuf_dma_contig_free(vq, &buf->vb); 250 250 dev_dbg(dev, "%s freed\n", __func__); 251 251 buf->vb.state = VIDEOBUF_NEEDS_INIT;
+1 -1
drivers/media/video/sh_vou.c
··· 230 230 BUG_ON(in_interrupt()); 231 231 232 232 /* Wait until this buffer is no longer in STATE_QUEUED or STATE_ACTIVE */ 233 - videobuf_waiton(vb, 0, 0); 233 + videobuf_waiton(vq, vb, 0, 0); 234 234 videobuf_dma_contig_free(vq, vb); 235 235 vb->state = VIDEOBUF_NEEDS_INIT; 236 236 }
+2 -2
drivers/media/video/tlg2300/pd-video.c
··· 1434 1434 V4L2_BUF_TYPE_VIDEO_CAPTURE, 1435 1435 V4L2_FIELD_INTERLACED,/* video is interlacd */ 1436 1436 sizeof(struct videobuf_buffer),/*it's enough*/ 1437 - front); 1437 + front, NULL); 1438 1438 } else if (vfd->vfl_type == VFL_TYPE_VBI 1439 1439 && !(pd->state & POSEIDON_STATE_VBI)) { 1440 1440 front = kzalloc(sizeof(struct front_face), GFP_KERNEL); ··· 1451 1451 V4L2_BUF_TYPE_VBI_CAPTURE, 1452 1452 V4L2_FIELD_NONE, /* vbi is NONE mode */ 1453 1453 sizeof(struct videobuf_buffer), 1454 - front); 1454 + front, NULL); 1455 1455 } else { 1456 1456 /* maybe add FM support here */ 1457 1457 log("other ");
+36 -15
drivers/media/video/videobuf-core.c
··· 73 73 } 74 74 EXPORT_SYMBOL_GPL(videobuf_alloc_vb); 75 75 76 - #define WAITON_CONDITION (vb->state != VIDEOBUF_ACTIVE &&\ 77 - vb->state != VIDEOBUF_QUEUED) 78 - int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr) 76 + static int is_state_active_or_queued(struct videobuf_queue *q, struct videobuf_buffer *vb) 79 77 { 78 + unsigned long flags; 79 + bool rc; 80 + 81 + spin_lock_irqsave(q->irqlock, flags); 82 + rc = vb->state != VIDEOBUF_ACTIVE && vb->state != VIDEOBUF_QUEUED; 83 + spin_unlock_irqrestore(q->irqlock, flags); 84 + return rc; 85 + }; 86 + 87 + int videobuf_waiton(struct videobuf_queue *q, struct videobuf_buffer *vb, 88 + int non_blocking, int intr) 89 + { 90 + bool is_ext_locked; 91 + int ret = 0; 92 + 80 93 MAGIC_CHECK(vb->magic, MAGIC_BUFFER); 81 94 82 95 if (non_blocking) { 83 - if (WAITON_CONDITION) 96 + if (is_state_active_or_queued(q, vb)) 84 97 return 0; 85 - else 86 - return -EAGAIN; 98 + return -EAGAIN; 87 99 } 88 100 89 - if (intr) 90 - return wait_event_interruptible(vb->done, WAITON_CONDITION); 91 - else 92 - wait_event(vb->done, WAITON_CONDITION); 101 + is_ext_locked = q->ext_lock && mutex_is_locked(q->ext_lock); 93 102 94 - return 0; 103 + /* Release vdev lock to prevent this wait from blocking outside access to 104 + the device. */ 105 + if (is_ext_locked) 106 + mutex_unlock(q->ext_lock); 107 + if (intr) 108 + ret = wait_event_interruptible(vb->done, is_state_active_or_queued(q, vb)); 109 + else 110 + wait_event(vb->done, is_state_active_or_queued(q, vb)); 111 + /* Relock */ 112 + if (is_ext_locked) 113 + mutex_lock(q->ext_lock); 114 + 115 + return ret; 95 116 } 96 117 EXPORT_SYMBOL_GPL(videobuf_waiton); 97 118 ··· 692 671 goto done; 693 672 694 673 buf = list_entry(q->stream.next, struct videobuf_buffer, stream); 695 - retval = videobuf_waiton(buf, nonblocking, 1); 674 + retval = videobuf_waiton(q, buf, nonblocking, 1); 696 675 if (retval < 0) 697 676 goto done; 698 677 ··· 820 799 spin_lock_irqsave(q->irqlock, flags); 821 800 q->ops->buf_queue(q, q->read_buf); 822 801 spin_unlock_irqrestore(q->irqlock, flags); 823 - retval = videobuf_waiton(q->read_buf, 0, 0); 802 + retval = videobuf_waiton(q, q->read_buf, 0, 0); 824 803 if (0 == retval) { 825 804 CALL(q, sync, q, q->read_buf); 826 805 if (VIDEOBUF_ERROR == q->read_buf->state) ··· 932 911 } 933 912 934 913 /* wait until capture is done */ 935 - retval = videobuf_waiton(q->read_buf, nonblocking, 1); 914 + retval = videobuf_waiton(q, q->read_buf, nonblocking, 1); 936 915 if (0 != retval) 937 916 goto done; 938 917 ··· 1082 1061 list_del(&q->read_buf->stream); 1083 1062 q->read_off = 0; 1084 1063 } 1085 - rc = videobuf_waiton(q->read_buf, nonblocking, 1); 1064 + rc = videobuf_waiton(q, q->read_buf, nonblocking, 1); 1086 1065 if (rc < 0) { 1087 1066 if (0 == retval) 1088 1067 retval = rc;
+1 -1
drivers/media/video/videobuf-dvb.c
··· 57 57 buf = list_entry(dvb->dvbq.stream.next, 58 58 struct videobuf_buffer, stream); 59 59 list_del(&buf->stream); 60 - err = videobuf_waiton(buf,0,1); 60 + err = videobuf_waiton(&dvb->dvbq, buf, 0, 1); 61 61 62 62 /* no more feeds left or stop_feed() asked us to quit */ 63 63 if (0 == dvb->nfeeds)
+1 -1
drivers/staging/cx25821/cx25821-core.c
··· 1319 1319 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); 1320 1320 1321 1321 BUG_ON(in_interrupt()); 1322 - videobuf_waiton(&buf->vb, 0, 0); 1322 + videobuf_waiton(q, &buf->vb, 0, 0); 1323 1323 videobuf_dma_unmap(q->dev, dma); 1324 1324 videobuf_dma_free(dma); 1325 1325 btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc);
+4 -4
drivers/staging/dt3155v4l/dt3155v4l.c
··· 293 293 dt3155_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb) 294 294 { 295 295 if (vb->state == VIDEOBUF_ACTIVE) 296 - videobuf_waiton(vb, 0, 0); /* FIXME: cannot be interrupted */ 296 + videobuf_waiton(q, vb, 0, 0); /* FIXME: cannot be interrupted */ 297 297 videobuf_dma_contig_free(q, vb); 298 298 vb->state = VIDEOBUF_NEEDS_INIT; 299 299 } ··· 440 440 videobuf_queue_dma_contig_init(pd->vidq, &vbq_ops, 441 441 &pd->pdev->dev, &pd->lock, 442 442 V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, 443 - sizeof(struct videobuf_buffer), pd); 443 + sizeof(struct videobuf_buffer), pd, NULL); 444 444 /* disable all irqs, clear all irq flags */ 445 445 iowrite32(FLD_START | FLD_END_EVEN | FLD_END_ODD, 446 446 pd->regs + INT_CSR); ··· 494 494 tmp = pd->curr_buf; 495 495 spin_unlock_irqrestore(&pd->lock, flags); 496 496 if (tmp) 497 - videobuf_waiton(tmp, 0, 1); /* block, interruptible */ 497 + videobuf_waiton(pd->vidq, tmp, 0, 1); /* block, interruptible */ 498 498 dt3155_stop_acq(pd); 499 499 videobuf_stop(pd->vidq); 500 500 pd->acq_fp = NULL; ··· 603 603 tmp = pd->curr_buf; 604 604 spin_unlock_irqrestore(&pd->lock, flags); 605 605 if (tmp) 606 - videobuf_waiton(tmp, 0, 1); /* block, interruptible */ 606 + videobuf_waiton(pd->vidq, tmp, 0, 1); /* block, interruptible */ 607 607 return ret; 608 608 } 609 609
+2 -1
include/media/videobuf-core.h
··· 180 180 mutex_unlock(&q->vb_lock); 181 181 } 182 182 183 - int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr); 183 + int videobuf_waiton(struct videobuf_queue *q, struct videobuf_buffer *vb, 184 + int non_blocking, int intr); 184 185 int videobuf_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb, 185 186 struct v4l2_framebuffer *fbuf); 186 187