dmaengine: shdma: Allocate cyclic sg list dynamically
The sg list used to prepare cyclic DMA descriptors is currently allocated statically on the stack as an array of 32 elements. This makes the shdma_prep_dma_cyclic() function consume a lot of stack space, as reported by the compiler: drivers/dma/sh/shdma-base.c: In function ‘shdma_prep_dma_cyclic’: drivers/dma/sh/shdma-base.c:715:1: warning: the frame size of 1056 bytes is larger than 1024 bytes [-Wframe-larger-than=] Given the limited Linux kernel stack size, this could lead to stack overflows. Fix the problem by allocating the sg list dynamically. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Signed-off-by: Simon Horman <horms+renesas@verge.net.au> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
This commit is contained in:
parent
c091ff51b4
commit
4415b03abb
|
@ -672,11 +672,12 @@ static struct dma_async_tx_descriptor *shdma_prep_dma_cyclic(
|
|||
{
|
||||
struct shdma_chan *schan = to_shdma_chan(chan);
|
||||
struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device);
|
||||
struct dma_async_tx_descriptor *desc;
|
||||
const struct shdma_ops *ops = sdev->ops;
|
||||
unsigned int sg_len = buf_len / period_len;
|
||||
int slave_id = schan->slave_id;
|
||||
dma_addr_t slave_addr;
|
||||
struct scatterlist sgl[SHDMA_MAX_SG_LEN];
|
||||
struct scatterlist *sgl;
|
||||
int i;
|
||||
|
||||
if (!chan)
|
||||
|
@ -700,7 +701,16 @@ static struct dma_async_tx_descriptor *shdma_prep_dma_cyclic(
|
|||
|
||||
slave_addr = ops->slave_addr(schan);
|
||||
|
||||
/*
|
||||
* Allocate the sg list dynamically as it would consumer too much stack
|
||||
* space.
|
||||
*/
|
||||
sgl = kcalloc(sg_len, sizeof(*sgl), GFP_KERNEL);
|
||||
if (!sgl)
|
||||
return NULL;
|
||||
|
||||
sg_init_table(sgl, sg_len);
|
||||
|
||||
for (i = 0; i < sg_len; i++) {
|
||||
dma_addr_t src = buf_addr + (period_len * i);
|
||||
|
||||
|
@ -710,8 +720,11 @@ static struct dma_async_tx_descriptor *shdma_prep_dma_cyclic(
|
|||
sg_dma_len(&sgl[i]) = period_len;
|
||||
}
|
||||
|
||||
return shdma_prep_sg(schan, sgl, sg_len, &slave_addr,
|
||||
desc = shdma_prep_sg(schan, sgl, sg_len, &slave_addr,
|
||||
direction, flags, true);
|
||||
|
||||
kfree(sgl);
|
||||
return desc;
|
||||
}
|
||||
|
||||
static int shdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
|
||||
|
|
Loading…
Reference in New Issue