diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-13 12:07:56 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-13 12:07:56 -0300 |
commit | 94cf06dade425c25f3d5b798177ff81dc9ca1713 (patch) | |
tree | d90e8432dd7490c08f0067889377318a30e52b39 /linux/drivers | |
parent | 97d73f901ce2d7930f127373845d07107e747525 (diff) | |
download | mediapointer-dvb-s2-94cf06dade425c25f3d5b798177ff81dc9ca1713.tar.gz mediapointer-dvb-s2-94cf06dade425c25f3d5b798177ff81dc9ca1713.tar.bz2 |
videobuf-vmalloc: stop streaming before unmap
From: Mauro Carvalho Chehab <mchehab@infradead.org>
Before the patch, there were a risk of freeing and unmapping userspace memory,
while there were pending requests.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'linux/drivers')
-rw-r--r-- | linux/drivers/media/video/videobuf-core.c | 1 | ||||
-rw-r--r-- | linux/drivers/media/video/videobuf-vmalloc.c | 23 |
2 files changed, 19 insertions, 5 deletions
diff --git a/linux/drivers/media/video/videobuf-core.c b/linux/drivers/media/video/videobuf-core.c index 660d28972..7d420a119 100644 --- a/linux/drivers/media/video/videobuf-core.c +++ b/linux/drivers/media/video/videobuf-core.c @@ -902,7 +902,6 @@ static void __videobuf_read_stop(struct videobuf_queue *q) { int i; - videobuf_queue_cancel(q); __videobuf_mmap_free(q); INIT_LIST_HEAD(&q->stream); diff --git a/linux/drivers/media/video/videobuf-vmalloc.c b/linux/drivers/media/video/videobuf-vmalloc.c index b031c822f..c5f04b4c1 100644 --- a/linux/drivers/media/video/videobuf-vmalloc.c +++ b/linux/drivers/media/video/videobuf-vmalloc.c @@ -73,6 +73,11 @@ static void videobuf_vm_close(struct vm_area_struct *vma) dprintk(1, "munmap %p q=%p\n", map, q); mutex_lock(&q->vb_lock); + + /* We need first to cancel streams, before unmapping */ + if (q->streaming) + videobuf_queue_cancel(q); + for (i = 0; i < VIDEO_MAX_FRAME; i++) { if (NULL == q->bufs[i]) continue; @@ -87,7 +92,15 @@ static void videobuf_vm_close(struct vm_area_struct *vma) In this case, memory should be freed, in order to do memory unmap. */ + MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM); + + /* vfree is not atomic - can't be + called with IRQ's disabled + */ + dprintk(1, "%s: buf[%d] freeing (%p)\n", + __func__, i, mem->vmalloc); + vfree(mem->vmalloc); mem->vmalloc = NULL; } @@ -95,9 +108,12 @@ static void videobuf_vm_close(struct vm_area_struct *vma) q->bufs[i]->map = NULL; q->bufs[i]->baddr = 0; } - mutex_unlock(&q->vb_lock); + kfree(map); + + mutex_unlock(&q->vb_lock); } + return; } @@ -139,6 +155,7 @@ static int __videobuf_iolock (struct videobuf_queue* q, struct v4l2_framebuffer *fbuf) { struct videobuf_vmalloc_memory *mem = vb->priv; + int pages; BUG_ON(!mem); @@ -155,8 +172,7 @@ static int __videobuf_iolock (struct videobuf_queue* q, } break; case V4L2_MEMORY_USERPTR: - { - int pages = PAGE_ALIGN(vb->size); + pages = PAGE_ALIGN(vb->size); dprintk(1, "%s memory method USERPTR\n", __func__); @@ -199,7 +215,6 @@ static int __videobuf_iolock (struct videobuf_queue* q, #endif break; - } case V4L2_MEMORY_OVERLAY: default: dprintk(1, "%s memory method OVERLAY/unknown\n", __func__); |