From: Geert Uytterhoeven <geert+renesas@glider.be> To: Mark Brown <broonie@kernel.org>, Simon Horman <horms@verge.net.au> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>, linux-spi@vger.kernel.org, linux-sh@vger.kernel.org, dmaengine@vger.kernel.org, Geert Uytterhoeven <geert+renesas@glider.be> Subject: [PATCH 01/12] spi: rspi: Fix leaking of unused DMA descriptors Date: Wed, 06 Aug 2014 12:58:58 +0000 [thread overview] Message-ID: <1407329949-5695-2-git-send-email-geert+renesas@glider.be> (raw) In-Reply-To: <1407329949-5695-1-git-send-email-geert+renesas@glider.be> If dmaengine_prep_slave_sg() or dmaengine_submit() fail, we may leak unused DMA descriptors. As per Documentation/dmaengine.txt, once a DMA descriptor has been obtained, it must be submitted. Hence: - First prepare and submit all DMA descriptors, - Prepare the SPI controller for DMA, - Start DMA by calling dma_async_issue_pending(), - Make sure to call dmaengine_terminate_all() on all descriptors that haven't completed. Reported-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> --- drivers/spi/spi-rspi.c | 94 +++++++++++++++++++++++++++++++------------------- 1 file changed, 58 insertions(+), 36 deletions(-) diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index c850dfdfa9e3..ad87a98f8f68 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -472,25 +472,52 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx, dma_cookie_t cookie; int ret; - if (tx) { - desc_tx = dmaengine_prep_slave_sg(rspi->master->dma_tx, - tx->sgl, tx->nents, DMA_TO_DEVICE, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - if (!desc_tx) - goto no_dma; - - irq_mask |= SPCR_SPTIE; - } + /* First prepare and submit the DMA request(s), as this may fail */ if (rx) { desc_rx = dmaengine_prep_slave_sg(rspi->master->dma_rx, rx->sgl, rx->nents, DMA_FROM_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - if (!desc_rx) - goto no_dma; + if (!desc_rx) { + ret = -EAGAIN; + goto no_dma_rx; + } + + desc_rx->callback = rspi_dma_complete; + desc_rx->callback_param = rspi; + cookie = dmaengine_submit(desc_rx); + if (dma_submit_error(cookie)) { + ret = cookie; + goto no_dma_rx; + } irq_mask |= SPCR_SPRIE; } + if (tx) { + desc_tx = dmaengine_prep_slave_sg(rspi->master->dma_tx, + tx->sgl, tx->nents, DMA_TO_DEVICE, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!desc_tx) { + ret = -EAGAIN; + goto no_dma_tx; + } + + if (rx) { + /* No callback */ + desc_tx->callback = NULL; + } else { + desc_tx->callback = rspi_dma_complete; + desc_tx->callback_param = rspi; + } + cookie = dmaengine_submit(desc_tx); + if (dma_submit_error(cookie)) { + ret = cookie; + goto no_dma_tx; + } + + irq_mask |= SPCR_SPTIE; + } + /* * DMAC needs SPxIE, but if SPxIE is set, the IRQ routine will be * called. So, this driver disables the IRQ while DMA transfer. @@ -503,34 +530,24 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx, rspi_enable_irq(rspi, irq_mask); rspi->dma_callbacked = 0; - if (rx) { - desc_rx->callback = rspi_dma_complete; - desc_rx->callback_param = rspi; - cookie = dmaengine_submit(desc_rx); - if (dma_submit_error(cookie)) - return cookie; + /* Now start DMA */ + if (rx) dma_async_issue_pending(rspi->master->dma_rx); - } - if (tx) { - if (rx) { - /* No callback */ - desc_tx->callback = NULL; - } else { - desc_tx->callback = rspi_dma_complete; - desc_tx->callback_param = rspi; - } - cookie = dmaengine_submit(desc_tx); - if (dma_submit_error(cookie)) - return cookie; + if (tx) dma_async_issue_pending(rspi->master->dma_tx); - } ret = wait_event_interruptible_timeout(rspi->wait, rspi->dma_callbacked, HZ); if (ret > 0 && rspi->dma_callbacked) ret = 0; - else if (!ret) + else if (!ret) { + dev_err(&rspi->master->dev, "DMA timeout\n"); ret = -ETIMEDOUT; + if (tx) + dmaengine_terminate_all(rspi->master->dma_tx); + if (rx) + dmaengine_terminate_all(rspi->master->dma_rx); + } rspi_disable_irq(rspi, irq_mask); @@ -541,11 +558,16 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx, return ret; -no_dma: - pr_warn_once("%s %s: DMA not available, falling back to PIO\n", - dev_driver_string(&rspi->master->dev), - dev_name(&rspi->master->dev)); - return -EAGAIN; +no_dma_tx: + if (rx) + dmaengine_terminate_all(rspi->master->dma_rx); +no_dma_rx: + if (ret = -EAGAIN) { + pr_warn_once("%s %s: DMA not available, falling back to PIO\n", + dev_driver_string(&rspi->master->dev), + dev_name(&rspi->master->dev)); + } + return ret; } static void rspi_receive_init(const struct rspi_data *rspi) -- 1.9.1
WARNING: multiple messages have this Message-ID (diff)
From: Geert Uytterhoeven <geert+renesas@glider.be> To: Mark Brown <broonie@kernel.org>, Simon Horman <horms@verge.net.au> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>, linux-spi@vger.kernel.org, linux-sh@vger.kernel.org, dmaengine@vger.kernel.org, Geert Uytterhoeven <geert+renesas@glider.be> Subject: [PATCH 01/12] spi: rspi: Fix leaking of unused DMA descriptors Date: Wed, 6 Aug 2014 14:58:58 +0200 [thread overview] Message-ID: <1407329949-5695-2-git-send-email-geert+renesas@glider.be> (raw) In-Reply-To: <1407329949-5695-1-git-send-email-geert+renesas@glider.be> If dmaengine_prep_slave_sg() or dmaengine_submit() fail, we may leak unused DMA descriptors. As per Documentation/dmaengine.txt, once a DMA descriptor has been obtained, it must be submitted. Hence: - First prepare and submit all DMA descriptors, - Prepare the SPI controller for DMA, - Start DMA by calling dma_async_issue_pending(), - Make sure to call dmaengine_terminate_all() on all descriptors that haven't completed. Reported-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> --- drivers/spi/spi-rspi.c | 94 +++++++++++++++++++++++++++++++------------------- 1 file changed, 58 insertions(+), 36 deletions(-) diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index c850dfdfa9e3..ad87a98f8f68 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -472,25 +472,52 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx, dma_cookie_t cookie; int ret; - if (tx) { - desc_tx = dmaengine_prep_slave_sg(rspi->master->dma_tx, - tx->sgl, tx->nents, DMA_TO_DEVICE, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - if (!desc_tx) - goto no_dma; - - irq_mask |= SPCR_SPTIE; - } + /* First prepare and submit the DMA request(s), as this may fail */ if (rx) { desc_rx = dmaengine_prep_slave_sg(rspi->master->dma_rx, rx->sgl, rx->nents, DMA_FROM_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - if (!desc_rx) - goto no_dma; + if (!desc_rx) { + ret = -EAGAIN; + goto no_dma_rx; + } + + desc_rx->callback = rspi_dma_complete; + desc_rx->callback_param = rspi; + cookie = dmaengine_submit(desc_rx); + if (dma_submit_error(cookie)) { + ret = cookie; + goto no_dma_rx; + } irq_mask |= SPCR_SPRIE; } + if (tx) { + desc_tx = dmaengine_prep_slave_sg(rspi->master->dma_tx, + tx->sgl, tx->nents, DMA_TO_DEVICE, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!desc_tx) { + ret = -EAGAIN; + goto no_dma_tx; + } + + if (rx) { + /* No callback */ + desc_tx->callback = NULL; + } else { + desc_tx->callback = rspi_dma_complete; + desc_tx->callback_param = rspi; + } + cookie = dmaengine_submit(desc_tx); + if (dma_submit_error(cookie)) { + ret = cookie; + goto no_dma_tx; + } + + irq_mask |= SPCR_SPTIE; + } + /* * DMAC needs SPxIE, but if SPxIE is set, the IRQ routine will be * called. So, this driver disables the IRQ while DMA transfer. @@ -503,34 +530,24 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx, rspi_enable_irq(rspi, irq_mask); rspi->dma_callbacked = 0; - if (rx) { - desc_rx->callback = rspi_dma_complete; - desc_rx->callback_param = rspi; - cookie = dmaengine_submit(desc_rx); - if (dma_submit_error(cookie)) - return cookie; + /* Now start DMA */ + if (rx) dma_async_issue_pending(rspi->master->dma_rx); - } - if (tx) { - if (rx) { - /* No callback */ - desc_tx->callback = NULL; - } else { - desc_tx->callback = rspi_dma_complete; - desc_tx->callback_param = rspi; - } - cookie = dmaengine_submit(desc_tx); - if (dma_submit_error(cookie)) - return cookie; + if (tx) dma_async_issue_pending(rspi->master->dma_tx); - } ret = wait_event_interruptible_timeout(rspi->wait, rspi->dma_callbacked, HZ); if (ret > 0 && rspi->dma_callbacked) ret = 0; - else if (!ret) + else if (!ret) { + dev_err(&rspi->master->dev, "DMA timeout\n"); ret = -ETIMEDOUT; + if (tx) + dmaengine_terminate_all(rspi->master->dma_tx); + if (rx) + dmaengine_terminate_all(rspi->master->dma_rx); + } rspi_disable_irq(rspi, irq_mask); @@ -541,11 +558,16 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx, return ret; -no_dma: - pr_warn_once("%s %s: DMA not available, falling back to PIO\n", - dev_driver_string(&rspi->master->dev), - dev_name(&rspi->master->dev)); - return -EAGAIN; +no_dma_tx: + if (rx) + dmaengine_terminate_all(rspi->master->dma_rx); +no_dma_rx: + if (ret == -EAGAIN) { + pr_warn_once("%s %s: DMA not available, falling back to PIO\n", + dev_driver_string(&rspi->master->dev), + dev_name(&rspi->master->dev)); + } + return ret; } static void rspi_receive_init(const struct rspi_data *rspi) -- 1.9.1
next prev parent reply other threads:[~2014-08-06 12:58 UTC|newest] Thread overview: 70+ messages / expand[flat|nested] mbox.gz Atom feed top 2014-08-06 12:58 [PATCH 00/12] spi: rspi and sh-msiof driver updates Geert Uytterhoeven 2014-08-06 12:58 ` Geert Uytterhoeven 2014-08-06 12:58 ` Geert Uytterhoeven [this message] 2014-08-06 12:58 ` [PATCH 01/12] spi: rspi: Fix leaking of unused DMA descriptors Geert Uytterhoeven 2014-08-06 20:11 ` Mark Brown 2014-08-06 20:11 ` Mark Brown 2014-08-06 12:58 ` [PATCH 02/12] spi: rspi: Remove unneeded semicolon Geert Uytterhoeven 2014-08-06 12:58 ` Geert Uytterhoeven 2014-08-06 20:26 ` Mark Brown 2014-08-06 20:26 ` Mark Brown [not found] ` <1407329949-5695-1-git-send-email-geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org> 2014-08-06 12:59 ` [PATCH 03/12] spi: rspi: Use devm_kasprintf() Geert Uytterhoeven 2014-08-06 12:59 ` Geert Uytterhoeven [not found] ` <1407329949-5695-4-git-send-email-geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org> 2014-08-06 20:26 ` Mark Brown 2014-08-06 20:26 ` Mark Brown 2014-08-06 12:59 ` [PATCH 04/12] spi: rspi: Configure DMA slave bus width to 8 bit Geert Uytterhoeven 2014-08-06 12:59 ` Geert Uytterhoeven 2014-08-06 20:26 ` Mark Brown 2014-08-06 20:26 ` Mark Brown 2014-08-06 12:59 ` [PATCH 05/12] [v2] spi: rspi: Add DT support to DMA setup Geert Uytterhoeven 2014-08-06 12:59 ` Geert Uytterhoeven 2014-08-06 20:28 ` Mark Brown 2014-08-06 20:28 ` Mark Brown 2014-08-06 12:59 ` [PATCH 09/12] [v3] ARM: shmobile: r8a7791 dtsi: Enable DMA for QSPI Geert Uytterhoeven 2014-08-06 12:59 ` Geert Uytterhoeven 2014-08-07 0:37 ` Simon Horman 2014-08-07 0:37 ` Simon Horman 2014-08-07 0:39 ` Simon Horman 2014-08-07 0:39 ` Simon Horman 2014-08-07 0:41 ` Simon Horman 2014-08-07 0:41 ` Simon Horman [not found] ` <20140807004107.GB30872-/R6kz+dDXgpPR4JQBCEnsQ@public.gmane.org> 2014-08-07 8:27 ` Geert Uytterhoeven 2014-08-07 8:27 ` Geert Uytterhoeven 2014-08-08 1:38 ` Simon Horman 2014-08-08 1:38 ` Simon Horman 2014-08-06 12:59 ` [PATCH 10/12] [v3] ARM: shmobile: r8a7791 dtsi: Enable DMA for MSIOF Geert Uytterhoeven 2014-08-06 12:59 ` Geert Uytterhoeven 2014-08-06 12:59 ` [PATCH 12/12] ARM: shmobile: r8a7790 " Geert Uytterhoeven 2014-08-06 12:59 ` Geert Uytterhoeven 2014-08-07 0:16 ` [PATCH 00/12] spi: rspi and sh-msiof driver updates Laurent Pinchart 2014-08-07 0:16 ` Laurent Pinchart 2014-08-06 12:59 ` [PATCH 06/12] spi: sh-msiof: Fix leaking of unused DMA descriptors Geert Uytterhoeven 2014-08-06 12:59 ` Geert Uytterhoeven 2014-08-06 20:35 ` Mark Brown 2014-08-06 20:35 ` Mark Brown 2014-08-07 0:07 ` Laurent Pinchart 2014-08-07 0:07 ` Laurent Pinchart 2014-08-07 8:55 ` Geert Uytterhoeven 2014-08-07 8:55 ` Geert Uytterhoeven [not found] ` <CAMuHMdUd3OKqDwhLSCMW-rEQSnWky+saN5TgC005rkmNPfEL+g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> 2014-08-07 12:07 ` [PATCH 1/2] spi: sh-msiof: Return early in sh_msiof_dma_once() where possible Geert Uytterhoeven 2014-08-07 12:07 ` Geert Uytterhoeven [not found] ` <1407413263-20177-1-git-send-email-geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org> 2014-08-07 12:07 ` [PATCH 2/2] spi: sh-msiof: Fix transmit-only DMA transfers Geert Uytterhoeven 2014-08-07 12:07 ` Geert Uytterhoeven 2014-08-07 12:51 ` Laurent Pinchart 2014-08-07 12:51 ` Laurent Pinchart 2014-08-07 12:52 ` [PATCH 1/2] spi: sh-msiof: Return early in sh_msiof_dma_once() where possible Laurent Pinchart 2014-08-07 12:52 ` Laurent Pinchart 2014-08-07 17:41 ` Mark Brown 2014-08-07 17:41 ` Mark Brown 2014-08-06 12:59 ` [PATCH 07/12] spi: sh-msiof: Configure DMA slave bus width Geert Uytterhoeven 2014-08-06 12:59 ` Geert Uytterhoeven [not found] ` <1407329949-5695-8-git-send-email-geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org> 2014-08-06 20:36 ` Mark Brown 2014-08-06 20:36 ` Mark Brown 2014-08-06 12:59 ` [PATCH 08/12] [v2] spi: sh-msiof: Add DT support to DMA setup Geert Uytterhoeven 2014-08-06 12:59 ` Geert Uytterhoeven 2014-08-06 20:36 ` Mark Brown 2014-08-06 20:36 ` Mark Brown 2014-08-06 12:59 ` [PATCH 11/12] ARM: shmobile: r8a7790 dtsi: Enable DMA for QSPI Geert Uytterhoeven 2014-08-06 12:59 ` Geert Uytterhoeven 2014-08-06 20:29 ` [PATCH 00/12] spi: rspi and sh-msiof driver updates Mark Brown 2014-08-06 20:29 ` Mark Brown
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1407329949-5695-2-git-send-email-geert+renesas@glider.be \ --to=geert+renesas@glider.be \ --cc=broonie@kernel.org \ --cc=dmaengine@vger.kernel.org \ --cc=horms@verge.net.au \ --cc=laurent.pinchart@ideasonboard.com \ --cc=linux-sh@vger.kernel.org \ --cc=linux-spi@vger.kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.