Skip to content

Commit

Permalink
dmaengine: rcar-dmac: Handle hardware descriptor allocation failure
Browse files Browse the repository at this point in the history
If the atomic DMA coherent pool is too small, disable use of hardware
descriptor lists instead of crashing the system:

ERROR: 256 KiB atomic DMA coherent pool is too small!
Please increase it with coherent_pool= kernel parameter!

Unable to handle kernel NULL pointer dereference at virtual address 00000004
Internal error: Oops: a07 [#1] PREEMPT SMP ARM

PC is at rcar_dmac_chan_reinit+0x3c/0x160
LR is at _raw_spin_lock_irqsave+0x18/0x5c

[<802132c0>] (rcar_dmac_chan_reinit) from [<80214818>] (rcar_dmac_isr_error+0x84/0xa0)
[<80214818>] (rcar_dmac_isr_error) from [<80060484>] (handle_irq_event_percpu+0x50/0x150)
[<80060484>] (handle_irq_event_percpu) from [<800605c0>] (handle_irq_event+0x3c/0x5c)
[<800605c0>] (handle_irq_event) from [<8006350c>] (handle_fasteoi_irq+0xb8/0x198)
[<8006350c>] (handle_fasteoi_irq) from [<8005fdb0>] (generic_handle_irq+0x20/0x30)
[<8005fdb0>] (generic_handle_irq) from [<8000fcd0>] (handle_IRQ+0x50/0xc4)
[<8000fcd0>] (handle_IRQ) from [<800092cc>] (gic_handle_irq+0x28/0x5c)
[<800092cc>] (gic_handle_irq) from [<80012700>] (__irq_svc+0x40/0x70)

Kernel panic - not syncing: Fatal exception in interrupt

Signed-off-by: Jürg Billeter <j@bitron.ch>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
  • Loading branch information
Jürg Billeter authored and Laurent Pinchart committed Dec 23, 2014
1 parent 1ed1315 commit ee4b876
Showing 1 changed file with 9 additions and 5 deletions.
14 changes: 9 additions & 5 deletions drivers/dma/sh/rcar-dmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -679,8 +679,8 @@ static void rcar_dmac_realloc_hwdesc(struct rcar_dmac_chan *chan,
desc->hwdescs.size = size;
}

static void rcar_dmac_fill_hwdesc(struct rcar_dmac_chan *chan,
struct rcar_dmac_desc *desc)
static int rcar_dmac_fill_hwdesc(struct rcar_dmac_chan *chan,
struct rcar_dmac_desc *desc)
{
struct rcar_dmac_xfer_chunk *chunk;
struct rcar_dmac_hw_desc *hwdesc;
Expand All @@ -689,14 +689,16 @@ static void rcar_dmac_fill_hwdesc(struct rcar_dmac_chan *chan,

hwdesc = desc->hwdescs.mem;
if (!hwdesc)
return;
return -ENOMEM;

list_for_each_entry(chunk, &desc->chunks, node) {
hwdesc->sar = chunk->src_addr;
hwdesc->dar = chunk->dst_addr;
hwdesc->tcr = chunk->size >> desc->xfer_shift;
hwdesc++;
}

return 0;
}

/* -----------------------------------------------------------------------------
Expand Down Expand Up @@ -917,8 +919,10 @@ rcar_dmac_chan_prep_sg(struct rcar_dmac_chan *chan, struct scatterlist *sgl,
* additional complexity remains to be investigated.
*/
desc->hwdescs.use = !highmem && nchunks > 1;
if (desc->hwdescs.use)
rcar_dmac_fill_hwdesc(chan, desc);
if (desc->hwdescs.use) {
if (rcar_dmac_fill_hwdesc(chan, desc) < 0)
desc->hwdescs.use = false;
}

return &desc->async_tx;
}
Expand Down

0 comments on commit ee4b876

Please sign in to comment.