From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Mark Brown <broonie@kernel.org>,
Simon Horman <horms@verge.net.au>,
linux-spi@vger.kernel.org, linux-sh@vger.kernel.org,
dmaengine@vger.kernel.org
Subject: Re: [PATCH 06/12] spi: sh-msiof: Fix leaking of unused DMA descriptors
Date: Thu, 07 Aug 2014 00:07:44 +0000 [thread overview]
Message-ID: <1888537.ONCuOO6jck@avalon> (raw)
In-Reply-To: <1407329949-5695-7-git-send-email-geert+renesas@glider.be>
Hi Geert,
Thank you for the patch.
On Wednesday 06 August 2014 14:59:03 Geert Uytterhoeven wrote:
> 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-sh-msiof.c | 71 ++++++++++++++++++++++---------------------
> 1 file changed, 38 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c
> index 2a4354dcd661..887c2084130f 100644
> --- a/drivers/spi/spi-sh-msiof.c
> +++ b/drivers/spi/spi-sh-msiof.c
> @@ -636,48 +636,38 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv
> *p, const void *tx, dma_cookie_t cookie;
> int ret;
>
> - if (tx) {
> - ier_bits |= IER_TDREQE | IER_TDMAE;
> - dma_sync_single_for_device(p->master->dma_tx->device->dev,
> - p->tx_dma_addr, len, DMA_TO_DEVICE);
> - desc_tx = dmaengine_prep_slave_single(p->master->dma_tx,
> - p->tx_dma_addr, len, DMA_TO_DEVICE,
> - DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> - if (!desc_tx)
> - return -EAGAIN;
> - }
> -
> + /* First prepare and submit the DMA request(s), as this may fail */
> if (rx) {
> ier_bits |= IER_RDREQE | IER_RDMAE;
> desc_rx = dmaengine_prep_slave_single(p->master->dma_rx,
> p->rx_dma_addr, len, DMA_FROM_DEVICE,
> DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> - if (!desc_rx)
> - return -EAGAIN;
> - }
> -
> - /* 1 stage FIFO watermarks for DMA */
> - sh_msiof_write(p, FCTR, FCTR_TFWM_1 | FCTR_RFWM_1);
> -
> - /* setup msiof transfer mode registers (32-bit words) */
> - sh_msiof_spi_set_mode_regs(p, tx, rx, 32, len / 4);
> -
> - sh_msiof_write(p, IER, ier_bits);
> -
> - reinit_completion(&p->done);
> + if (!desc_rx) {
> + ret = -EAGAIN;
> + goto no_dma_rx;
You could return -EAGAIN directly here.
> + }
>
> - if (rx) {
> desc_rx->callback = sh_msiof_dma_complete;
> desc_rx->callback_param = p;
> cookie = dmaengine_submit(desc_rx);
> if (dma_submit_error(cookie)) {
> ret = cookie;
> - goto stop_ier;
> + goto no_dma_rx;
> }
> - dma_async_issue_pending(p->master->dma_rx);
> }
>
> if (tx) {
> + ier_bits |= IER_TDREQE | IER_TDMAE;
> + dma_sync_single_for_device(p->master->dma_tx->device->dev,
> + p->tx_dma_addr, len, DMA_TO_DEVICE);
> + desc_tx = dmaengine_prep_slave_single(p->master->dma_tx,
> + p->tx_dma_addr, len, 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;
> @@ -688,15 +678,30 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv
> *p, const void *tx, cookie = dmaengine_submit(desc_tx);
> if (dma_submit_error(cookie)) {
> ret = cookie;
> - goto stop_rx;
> + goto no_dma_tx;
> }
> - dma_async_issue_pending(p->master->dma_tx);
> }
>
> + /* 1 stage FIFO watermarks for DMA */
> + sh_msiof_write(p, FCTR, FCTR_TFWM_1 | FCTR_RFWM_1);
> +
> + /* setup msiof transfer mode registers (32-bit words) */
> + sh_msiof_spi_set_mode_regs(p, tx, rx, 32, len / 4);
> +
> + sh_msiof_write(p, IER, ier_bits);
> +
> + reinit_completion(&p->done);
> +
> + /* Now start DMA */
> + if (tx)
> + dma_async_issue_pending(p->master->dma_rx);
if (tx) issue pending on dma_rx ? Shouldn't is be tx -> tx and rx -> rx below
? I would also start rx before tx, but that might be an unnecessary
precaution.
> + if (rx)
> + dma_async_issue_pending(p->master->dma_tx);
> +
> ret = sh_msiof_spi_start(p, rx);
> if (ret) {
> dev_err(&p->pdev->dev, "failed to start hardware\n");
> - goto stop_tx;
> + goto stop_dma;
> }
>
> /* wait for tx fifo to be emptied / rx fifo to be filled */
> @@ -726,14 +731,14 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv
> *p, const void *tx, stop_reset:
> sh_msiof_reset_str(p);
> sh_msiof_spi_stop(p, rx);
> -stop_tx:
> +stop_dma:
> if (tx)
> dmaengine_terminate_all(p->master->dma_tx);
> -stop_rx:
> +no_dma_tx:
> if (rx)
> dmaengine_terminate_all(p->master->dma_rx);
> -stop_ier:
> sh_msiof_write(p, IER, 0);
> +no_dma_rx:
> return ret;
> }
--
Regards,
Laurent Pinchart
WARNING: multiple messages have this Message-ID (diff)
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Mark Brown <broonie@kernel.org>,
Simon Horman <horms@verge.net.au>,
linux-spi@vger.kernel.org, linux-sh@vger.kernel.org,
dmaengine@vger.kernel.org
Subject: Re: [PATCH 06/12] spi: sh-msiof: Fix leaking of unused DMA descriptors
Date: Thu, 07 Aug 2014 02:07:44 +0200 [thread overview]
Message-ID: <1888537.ONCuOO6jck@avalon> (raw)
In-Reply-To: <1407329949-5695-7-git-send-email-geert+renesas@glider.be>
Hi Geert,
Thank you for the patch.
On Wednesday 06 August 2014 14:59:03 Geert Uytterhoeven wrote:
> 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-sh-msiof.c | 71 ++++++++++++++++++++++---------------------
> 1 file changed, 38 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c
> index 2a4354dcd661..887c2084130f 100644
> --- a/drivers/spi/spi-sh-msiof.c
> +++ b/drivers/spi/spi-sh-msiof.c
> @@ -636,48 +636,38 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv
> *p, const void *tx, dma_cookie_t cookie;
> int ret;
>
> - if (tx) {
> - ier_bits |= IER_TDREQE | IER_TDMAE;
> - dma_sync_single_for_device(p->master->dma_tx->device->dev,
> - p->tx_dma_addr, len, DMA_TO_DEVICE);
> - desc_tx = dmaengine_prep_slave_single(p->master->dma_tx,
> - p->tx_dma_addr, len, DMA_TO_DEVICE,
> - DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> - if (!desc_tx)
> - return -EAGAIN;
> - }
> -
> + /* First prepare and submit the DMA request(s), as this may fail */
> if (rx) {
> ier_bits |= IER_RDREQE | IER_RDMAE;
> desc_rx = dmaengine_prep_slave_single(p->master->dma_rx,
> p->rx_dma_addr, len, DMA_FROM_DEVICE,
> DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> - if (!desc_rx)
> - return -EAGAIN;
> - }
> -
> - /* 1 stage FIFO watermarks for DMA */
> - sh_msiof_write(p, FCTR, FCTR_TFWM_1 | FCTR_RFWM_1);
> -
> - /* setup msiof transfer mode registers (32-bit words) */
> - sh_msiof_spi_set_mode_regs(p, tx, rx, 32, len / 4);
> -
> - sh_msiof_write(p, IER, ier_bits);
> -
> - reinit_completion(&p->done);
> + if (!desc_rx) {
> + ret = -EAGAIN;
> + goto no_dma_rx;
You could return -EAGAIN directly here.
> + }
>
> - if (rx) {
> desc_rx->callback = sh_msiof_dma_complete;
> desc_rx->callback_param = p;
> cookie = dmaengine_submit(desc_rx);
> if (dma_submit_error(cookie)) {
> ret = cookie;
> - goto stop_ier;
> + goto no_dma_rx;
> }
> - dma_async_issue_pending(p->master->dma_rx);
> }
>
> if (tx) {
> + ier_bits |= IER_TDREQE | IER_TDMAE;
> + dma_sync_single_for_device(p->master->dma_tx->device->dev,
> + p->tx_dma_addr, len, DMA_TO_DEVICE);
> + desc_tx = dmaengine_prep_slave_single(p->master->dma_tx,
> + p->tx_dma_addr, len, 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;
> @@ -688,15 +678,30 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv
> *p, const void *tx, cookie = dmaengine_submit(desc_tx);
> if (dma_submit_error(cookie)) {
> ret = cookie;
> - goto stop_rx;
> + goto no_dma_tx;
> }
> - dma_async_issue_pending(p->master->dma_tx);
> }
>
> + /* 1 stage FIFO watermarks for DMA */
> + sh_msiof_write(p, FCTR, FCTR_TFWM_1 | FCTR_RFWM_1);
> +
> + /* setup msiof transfer mode registers (32-bit words) */
> + sh_msiof_spi_set_mode_regs(p, tx, rx, 32, len / 4);
> +
> + sh_msiof_write(p, IER, ier_bits);
> +
> + reinit_completion(&p->done);
> +
> + /* Now start DMA */
> + if (tx)
> + dma_async_issue_pending(p->master->dma_rx);
if (tx) issue pending on dma_rx ? Shouldn't is be tx -> tx and rx -> rx below
? I would also start rx before tx, but that might be an unnecessary
precaution.
> + if (rx)
> + dma_async_issue_pending(p->master->dma_tx);
> +
> ret = sh_msiof_spi_start(p, rx);
> if (ret) {
> dev_err(&p->pdev->dev, "failed to start hardware\n");
> - goto stop_tx;
> + goto stop_dma;
> }
>
> /* wait for tx fifo to be emptied / rx fifo to be filled */
> @@ -726,14 +731,14 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv
> *p, const void *tx, stop_reset:
> sh_msiof_reset_str(p);
> sh_msiof_spi_stop(p, rx);
> -stop_tx:
> +stop_dma:
> if (tx)
> dmaengine_terminate_all(p->master->dma_tx);
> -stop_rx:
> +no_dma_tx:
> if (rx)
> dmaengine_terminate_all(p->master->dma_rx);
> -stop_ier:
> sh_msiof_write(p, IER, 0);
> +no_dma_rx:
> return ret;
> }
--
Regards,
Laurent Pinchart
next prev parent reply other threads:[~2014-08-07 0:07 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 ` [PATCH 01/12] spi: rspi: Fix leaking of unused DMA descriptors Geert Uytterhoeven
2014-08-06 12:58 ` 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
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 [this message]
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
[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 20:29 ` 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=1888537.ONCuOO6jck@avalon \
--to=laurent.pinchart@ideasonboard.com \
--cc=broonie@kernel.org \
--cc=dmaengine@vger.kernel.org \
--cc=geert+renesas@glider.be \
--cc=horms@verge.net.au \
--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: link
Be 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.