aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/v4l1-compat.c
diff options
context:
space:
mode:
authorMarcin Slusarz <marcin.slusarz@gmail.com>2008-04-22 13:45:57 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-24 13:07:50 -0400
commit76e41e4851e0c8b642e348d8489d7645b8dae21e (patch)
tree63479aebf183b45c9e80f892b3c6e32999ed4341 /drivers/media/video/v4l1-compat.c
parentb524f7b02d70204444441e4805fb3a71981e9018 (diff)
V4L/DVB (7365): reduce stack usage of v4l1_compat_sync
poll_one allocated on stack struct poll_wqueues which is pretty big structure (>500 bytes on x86_64). v4l1_compat_sync invokes poll_one in a loop, so allocate struct poll_wqueues in v4l1_compat_sync (with kmalloc) and pass it to poll_one. Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/v4l1-compat.c')
-rw-r--r--drivers/media/video/v4l1-compat.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index e42cea987964..a0f6c60279ec 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -199,14 +199,13 @@ pixelformat_to_palette(unsigned int pixelformat)
199 199
200/* ----------------------------------------------------------------- */ 200/* ----------------------------------------------------------------- */
201 201
202static int poll_one(struct file *file) 202static int poll_one(struct file *file, struct poll_wqueues *pwq)
203{ 203{
204 int retval = 1; 204 int retval = 1;
205 poll_table *table; 205 poll_table *table;
206 struct poll_wqueues pwq; /*TODO: allocate dynamically*/
207 206
208 poll_initwait(&pwq); 207 poll_initwait(pwq);
209 table = &pwq.pt; 208 table = &pwq->pt;
210 for (;;) { 209 for (;;) {
211 int mask; 210 int mask;
212 set_current_state(TASK_INTERRUPTIBLE); 211 set_current_state(TASK_INTERRUPTIBLE);
@@ -221,7 +220,7 @@ static int poll_one(struct file *file)
221 schedule(); 220 schedule();
222 } 221 }
223 set_current_state(TASK_RUNNING); 222 set_current_state(TASK_RUNNING);
224 poll_freewait(&pwq); 223 poll_freewait(pwq);
225 return retval; 224 return retval;
226} 225}
227 226
@@ -1068,6 +1067,7 @@ static noinline int v4l1_compat_sync(
1068 int err; 1067 int err;
1069 enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1068 enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1070 struct v4l2_buffer buf; 1069 struct v4l2_buffer buf;
1070 struct poll_wqueues *pwq;
1071 1071
1072 memset(&buf, 0, sizeof(buf)); 1072 memset(&buf, 0, sizeof(buf));
1073 buf.index = *i; 1073 buf.index = *i;
@@ -1091,10 +1091,11 @@ static noinline int v4l1_compat_sync(
1091 goto done; 1091 goto done;
1092 } 1092 }
1093 1093
1094 pwq = kmalloc(sizeof(*pwq), GFP_KERNEL);
1094 /* Loop as long as the buffer is queued, but not done */ 1095 /* Loop as long as the buffer is queued, but not done */
1095 while ((buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE)) 1096 while ((buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE))
1096 == V4L2_BUF_FLAG_QUEUED) { 1097 == V4L2_BUF_FLAG_QUEUED) {
1097 err = poll_one(file); 1098 err = poll_one(file, pwq);
1098 if (err < 0 || /* error or sleep was interrupted */ 1099 if (err < 0 || /* error or sleep was interrupted */
1099 err == 0) /* timeout? Shouldn't occur. */ 1100 err == 0) /* timeout? Shouldn't occur. */
1100 break; 1101 break;
@@ -1102,6 +1103,7 @@ static noinline int v4l1_compat_sync(
1102 if (err < 0) 1103 if (err < 0)
1103 dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n", err); 1104 dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n", err);
1104 } 1105 }
1106 kfree(pwq);
1105 if (!(buf.flags & V4L2_BUF_FLAG_DONE)) /* not done */ 1107 if (!(buf.flags & V4L2_BUF_FLAG_DONE)) /* not done */
1106 goto done; 1108 goto done;
1107 do { 1109 do {