Skip to content

Commit 6d5f26f

Browse files
arndbmchehab
authored andcommitted
media: staging/intel-ipu3-v4l: reduce kernel stack usage
The v4l2_pix_format_mplane structure is too large to be put on the kernel stack, as we can see in 32-bit builds: drivers/staging/media/ipu3/ipu3-v4l2.c: In function 'imgu_fmt': drivers/staging/media/ipu3/ipu3-v4l2.c:753:1: error: the frame size of 1028 bytes is larger than 1024 bytes [-Werror=frame-larger-than=] By dynamically allocating this array, the stack usage goes down to an acceptable 272 bytes for the same x86-32 configuration. Fixes: a0ca162 ("media: staging/intel-ipu3: Add v4l2 driver based on media framework") Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
1 parent 76eb24f commit 6d5f26f

File tree

1 file changed

+25
-15
lines changed

1 file changed

+25
-15
lines changed

drivers/staging/media/ipu3/ipu3-v4l2.c

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -664,12 +664,11 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node,
664664
struct v4l2_format *f, bool try)
665665
{
666666
struct device *dev = &imgu->pci_dev->dev;
667-
struct v4l2_pix_format_mplane try_fmts[IPU3_CSS_QUEUES];
668667
struct v4l2_pix_format_mplane *fmts[IPU3_CSS_QUEUES] = { NULL };
669668
struct v4l2_rect *rects[IPU3_CSS_RECTS] = { NULL };
670669
struct v4l2_mbus_framefmt pad_fmt;
671670
unsigned int i, css_q;
672-
int r;
671+
int ret;
673672
struct imgu_css_pipe *css_pipe = &imgu->css.pipes[pipe];
674673
struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe];
675674
struct imgu_v4l2_subdev *imgu_sd = &imgu_pipe->imgu_sd;
@@ -698,9 +697,13 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node,
698697
continue;
699698

700699
if (try) {
701-
try_fmts[i] =
702-
imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp;
703-
fmts[i] = &try_fmts[i];
700+
fmts[i] = kmemdup(&imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp,
701+
sizeof(struct v4l2_pix_format_mplane),
702+
GFP_KERNEL);
703+
if (!fmts[i]) {
704+
ret = -ENOMEM;
705+
goto out;
706+
}
704707
} else {
705708
fmts[i] = &imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp;
706709
}
@@ -730,26 +733,33 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node,
730733
* before we return success from this function, so set it here.
731734
*/
732735
css_q = imgu_node_to_queue(node);
733-
if (fmts[css_q])
734-
*fmts[css_q] = f->fmt.pix_mp;
735-
else
736-
return -EINVAL;
736+
if (!fmts[css_q]) {
737+
ret = -EINVAL;
738+
goto out;
739+
}
740+
*fmts[css_q] = f->fmt.pix_mp;
737741

738742
if (try)
739-
r = imgu_css_fmt_try(&imgu->css, fmts, rects, pipe);
743+
ret = imgu_css_fmt_try(&imgu->css, fmts, rects, pipe);
740744
else
741-
r = imgu_css_fmt_set(&imgu->css, fmts, rects, pipe);
745+
ret = imgu_css_fmt_set(&imgu->css, fmts, rects, pipe);
742746

743-
/* r is the binary number in the firmware blob */
744-
if (r < 0)
745-
return r;
747+
/* ret is the binary number in the firmware blob */
748+
if (ret < 0)
749+
goto out;
746750

747751
if (try)
748752
f->fmt.pix_mp = *fmts[css_q];
749753
else
750754
f->fmt = imgu_pipe->nodes[node].vdev_fmt.fmt;
751755

752-
return 0;
756+
out:
757+
if (try) {
758+
for (i = 0; i < IPU3_CSS_QUEUES; i++)
759+
kfree(fmts[i]);
760+
}
761+
762+
return ret;
753763
}
754764

755765
static int imgu_try_fmt(struct file *file, void *fh, struct v4l2_format *f)

0 commit comments

Comments
 (0)