Commit aa9479ed authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

V4L/DVB (7561): videobuf-vmalloc: stop streaming before unmap

Before the patch, there were a risk of freeing and unmapping userspace memory,
while there were pending requests.
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent d6849652
...@@ -901,7 +901,6 @@ static void __videobuf_read_stop(struct videobuf_queue *q) ...@@ -901,7 +901,6 @@ static void __videobuf_read_stop(struct videobuf_queue *q)
{ {
int i; int i;
videobuf_queue_cancel(q); videobuf_queue_cancel(q);
__videobuf_mmap_free(q); __videobuf_mmap_free(q);
INIT_LIST_HEAD(&q->stream); INIT_LIST_HEAD(&q->stream);
......
...@@ -72,6 +72,11 @@ static void videobuf_vm_close(struct vm_area_struct *vma) ...@@ -72,6 +72,11 @@ static void videobuf_vm_close(struct vm_area_struct *vma)
dprintk(1, "munmap %p q=%p\n", map, q); dprintk(1, "munmap %p q=%p\n", map, q);
mutex_lock(&q->vb_lock); 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++) { for (i = 0; i < VIDEO_MAX_FRAME; i++) {
if (NULL == q->bufs[i]) if (NULL == q->bufs[i])
continue; continue;
...@@ -86,7 +91,15 @@ static void videobuf_vm_close(struct vm_area_struct *vma) ...@@ -86,7 +91,15 @@ static void videobuf_vm_close(struct vm_area_struct *vma)
In this case, memory should be freed, In this case, memory should be freed,
in order to do memory unmap. in order to do memory unmap.
*/ */
MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM); 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); vfree(mem->vmalloc);
mem->vmalloc = NULL; mem->vmalloc = NULL;
} }
...@@ -94,9 +107,12 @@ static void videobuf_vm_close(struct vm_area_struct *vma) ...@@ -94,9 +107,12 @@ static void videobuf_vm_close(struct vm_area_struct *vma)
q->bufs[i]->map = NULL; q->bufs[i]->map = NULL;
q->bufs[i]->baddr = 0; q->bufs[i]->baddr = 0;
} }
mutex_unlock(&q->vb_lock);
kfree(map); kfree(map);
mutex_unlock(&q->vb_lock);
} }
return; return;
} }
...@@ -138,6 +154,7 @@ static int __videobuf_iolock (struct videobuf_queue* q, ...@@ -138,6 +154,7 @@ static int __videobuf_iolock (struct videobuf_queue* q,
struct v4l2_framebuffer *fbuf) struct v4l2_framebuffer *fbuf)
{ {
struct videobuf_vmalloc_memory *mem = vb->priv; struct videobuf_vmalloc_memory *mem = vb->priv;
int pages;
BUG_ON(!mem); BUG_ON(!mem);
...@@ -154,8 +171,7 @@ static int __videobuf_iolock (struct videobuf_queue* q, ...@@ -154,8 +171,7 @@ static int __videobuf_iolock (struct videobuf_queue* q,
} }
break; break;
case V4L2_MEMORY_USERPTR: case V4L2_MEMORY_USERPTR:
{ pages = PAGE_ALIGN(vb->size);
int pages = PAGE_ALIGN(vb->size);
dprintk(1, "%s memory method USERPTR\n", __func__); dprintk(1, "%s memory method USERPTR\n", __func__);
...@@ -198,7 +214,6 @@ static int __videobuf_iolock (struct videobuf_queue* q, ...@@ -198,7 +214,6 @@ static int __videobuf_iolock (struct videobuf_queue* q,
#endif #endif
break; break;
}
case V4L2_MEMORY_OVERLAY: case V4L2_MEMORY_OVERLAY:
default: default:
dprintk(1, "%s memory method OVERLAY/unknown\n", __func__); dprintk(1, "%s memory method OVERLAY/unknown\n", __func__);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment