diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-13 14:07:56 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-24 13:08:58 -0400 |
commit | aa9479ed508d78dcd06479dc6274c9b02d1398df (patch) | |
tree | fcf7f2002ca3494ebe6dfeed8962ca0879776a0d | |
parent | d6849652628d3479859ca10bdd4b21024466df5f (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.c | 1 | ||||
-rw-r--r-- | drivers/media/video/videobuf-vmalloc.c | 23 |
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__); |