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: a0ca1627b4
("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>
This commit is contained in:
parent
76eb24fc23
commit
6d5f26f2e0
@ -664,12 +664,11 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node,
|
|||||||
struct v4l2_format *f, bool try)
|
struct v4l2_format *f, bool try)
|
||||||
{
|
{
|
||||||
struct device *dev = &imgu->pci_dev->dev;
|
struct device *dev = &imgu->pci_dev->dev;
|
||||||
struct v4l2_pix_format_mplane try_fmts[IPU3_CSS_QUEUES];
|
|
||||||
struct v4l2_pix_format_mplane *fmts[IPU3_CSS_QUEUES] = { NULL };
|
struct v4l2_pix_format_mplane *fmts[IPU3_CSS_QUEUES] = { NULL };
|
||||||
struct v4l2_rect *rects[IPU3_CSS_RECTS] = { NULL };
|
struct v4l2_rect *rects[IPU3_CSS_RECTS] = { NULL };
|
||||||
struct v4l2_mbus_framefmt pad_fmt;
|
struct v4l2_mbus_framefmt pad_fmt;
|
||||||
unsigned int i, css_q;
|
unsigned int i, css_q;
|
||||||
int r;
|
int ret;
|
||||||
struct imgu_css_pipe *css_pipe = &imgu->css.pipes[pipe];
|
struct imgu_css_pipe *css_pipe = &imgu->css.pipes[pipe];
|
||||||
struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe];
|
struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe];
|
||||||
struct imgu_v4l2_subdev *imgu_sd = &imgu_pipe->imgu_sd;
|
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,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (try) {
|
if (try) {
|
||||||
try_fmts[i] =
|
fmts[i] = kmemdup(&imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp,
|
||||||
imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp;
|
sizeof(struct v4l2_pix_format_mplane),
|
||||||
fmts[i] = &try_fmts[i];
|
GFP_KERNEL);
|
||||||
|
if (!fmts[i]) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
fmts[i] = &imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp;
|
fmts[i] = &imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp;
|
||||||
}
|
}
|
||||||
@ -730,26 +733,33 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node,
|
|||||||
* before we return success from this function, so set it here.
|
* before we return success from this function, so set it here.
|
||||||
*/
|
*/
|
||||||
css_q = imgu_node_to_queue(node);
|
css_q = imgu_node_to_queue(node);
|
||||||
if (fmts[css_q])
|
if (!fmts[css_q]) {
|
||||||
*fmts[css_q] = f->fmt.pix_mp;
|
ret = -EINVAL;
|
||||||
else
|
goto out;
|
||||||
return -EINVAL;
|
}
|
||||||
|
*fmts[css_q] = f->fmt.pix_mp;
|
||||||
|
|
||||||
if (try)
|
if (try)
|
||||||
r = imgu_css_fmt_try(&imgu->css, fmts, rects, pipe);
|
ret = imgu_css_fmt_try(&imgu->css, fmts, rects, pipe);
|
||||||
else
|
else
|
||||||
r = imgu_css_fmt_set(&imgu->css, fmts, rects, pipe);
|
ret = imgu_css_fmt_set(&imgu->css, fmts, rects, pipe);
|
||||||
|
|
||||||
/* r is the binary number in the firmware blob */
|
/* ret is the binary number in the firmware blob */
|
||||||
if (r < 0)
|
if (ret < 0)
|
||||||
return r;
|
goto out;
|
||||||
|
|
||||||
if (try)
|
if (try)
|
||||||
f->fmt.pix_mp = *fmts[css_q];
|
f->fmt.pix_mp = *fmts[css_q];
|
||||||
else
|
else
|
||||||
f->fmt = imgu_pipe->nodes[node].vdev_fmt.fmt;
|
f->fmt = imgu_pipe->nodes[node].vdev_fmt.fmt;
|
||||||
|
|
||||||
return 0;
|
out:
|
||||||
|
if (try) {
|
||||||
|
for (i = 0; i < IPU3_CSS_QUEUES; i++)
|
||||||
|
kfree(fmts[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int imgu_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
|
static int imgu_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
|
||||||
|
Loading…
Reference in New Issue
Block a user