aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2008-04-13 14:07:56 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-24 13:08:58 -0400
commitaa9479ed508d78dcd06479dc6274c9b02d1398df (patch)
treefcf7f2002ca3494ebe6dfeed8962ca0879776a0d
parentd6849652628d3479859ca10bdd4b21024466df5f (diff)
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: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--drivers/media/video/videobuf-core.c1
-rw-r--r--drivers/media/video/videobuf-vmalloc.c23
2 files changed, 19 insertions, 5 deletions
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c
index 5613e0882b5c..45a8cbdf417d 100644
--- a/drivers/media/video/videobuf-core.c
+++ b/drivers/media/video/videobuf-core.c
@@ -901,7 +901,6 @@ static void __videobuf_read_stop(struct videobuf_queue *q)
901{ 901{
902 int i; 902 int i;
903 903
904
905 videobuf_queue_cancel(q); 904 videobuf_queue_cancel(q);
906 __videobuf_mmap_free(q); 905 __videobuf_mmap_free(q);
907 INIT_LIST_HEAD(&q->stream); 906 INIT_LIST_HEAD(&q->stream);
diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c
index 73627d380f07..d68d0273807b 100644
--- a/drivers/media/video/videobuf-vmalloc.c
+++ b/drivers/media/video/videobuf-vmalloc.c
@@ -72,6 +72,11 @@ static void videobuf_vm_close(struct vm_area_struct *vma)
72 72
73 dprintk(1, "munmap %p q=%p\n", map, q); 73 dprintk(1, "munmap %p q=%p\n", map, q);
74 mutex_lock(&q->vb_lock); 74 mutex_lock(&q->vb_lock);
75
76 /* We need first to cancel streams, before unmapping */
77 if (q->streaming)
78 videobuf_queue_cancel(q);
79
75 for (i = 0; i < VIDEO_MAX_FRAME; i++) { 80 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
76 if (NULL == q->bufs[i]) 81 if (NULL == q->bufs[i])
77 continue; 82 continue;
@@ -86,7 +91,15 @@ static void videobuf_vm_close(struct vm_area_struct *vma)
86 In this case, memory should be freed, 91 In this case, memory should be freed,
87 in order to do memory unmap. 92 in order to do memory unmap.
88 */ 93 */
94
89 MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM); 95 MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
96
97 /* vfree is not atomic - can't be
98 called with IRQ's disabled
99 */
100 dprintk(1, "%s: buf[%d] freeing (%p)\n",
101 __func__, i, mem->vmalloc);
102
90 vfree(mem->vmalloc); 103 vfree(mem->vmalloc);
91 mem->vmalloc = NULL; 104 mem->vmalloc = NULL;
92 } 105 }
@@ -94,9 +107,12 @@ static void videobuf_vm_close(struct vm_area_struct *vma)
94 q->bufs[i]->map = NULL; 107 q->bufs[i]->map = NULL;
95 q->bufs[i]->baddr = 0; 108 q->bufs[i]->baddr = 0;
96 } 109 }
97 mutex_unlock(&q->vb_lock); 110
98 kfree(map); 111 kfree(map);
112
113 mutex_unlock(&q->vb_lock);
99 } 114 }
115
100 return; 116 return;
101} 117}
102 118
@@ -138,6 +154,7 @@ static int __videobuf_iolock (struct videobuf_queue* q,
138 struct v4l2_framebuffer *fbuf) 154 struct v4l2_framebuffer *fbuf)
139{ 155{
140 struct videobuf_vmalloc_memory *mem = vb->priv; 156 struct videobuf_vmalloc_memory *mem = vb->priv;
157 int pages;
141 158
142 BUG_ON(!mem); 159 BUG_ON(!mem);
143 160
@@ -154,8 +171,7 @@ static int __videobuf_iolock (struct videobuf_queue* q,
154 } 171 }
155 break; 172 break;
156 case V4L2_MEMORY_USERPTR: 173 case V4L2_MEMORY_USERPTR:
157 { 174 pages = PAGE_ALIGN(vb->size);
158 int pages = PAGE_ALIGN(vb->size);
159 175
160 dprintk(1, "%s memory method USERPTR\n", __func__); 176 dprintk(1, "%s memory method USERPTR\n", __func__);
161 177
@@ -198,7 +214,6 @@ static int __videobuf_iolock (struct videobuf_queue* q,
198#endif 214#endif
199 215
200 break; 216 break;
201 }
202 case V4L2_MEMORY_OVERLAY: 217 case V4L2_MEMORY_OVERLAY:
203 default: 218 default:
204 dprintk(1, "%s memory method OVERLAY/unknown\n", __func__); 219 dprintk(1, "%s memory method OVERLAY/unknown\n", __func__);