[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <49a35126-3cc6-0cbb-e632-42a237ef353e@ti.com>
Date: Mon, 16 Mar 2020 09:20:50 +0200
From: Peter Ujfalusi <peter.ujfalusi@...com>
To: Christophe JAILLET <christophe.jaillet@...adoo.fr>,
<vkoul@...nel.org>, <dan.j.williams@...el.com>,
<grygorii.strashko@...com>
CC: <dmaengine@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
<kernel-janitors@...r.kernel.org>
Subject: Re: [PATCH] dmaengine: ti: k3-udma: Fix an error handling path in
'k3_udma_glue_cfg_rx_flow()'
Hi Christophe,
On 15/03/2020 17.50, Christophe JAILLET wrote:
> All but one error handling paths in the 'k3_udma_glue_cfg_rx_flow()'
> function 'goto err' and call 'k3_udma_glue_release_rx_flow()'.
>
> This not correct because this function has a 'channel->flows_ready--;' at
> the end, but 'flows_ready' has not been incremented here, when we branch to
> the error handling path.
>
> In order to keep a correct value in 'flows_ready', un-roll
> 'k3_udma_glue_release_rx_flow()', simplify it, add some labels and branch
> at the correct places when an error is detected.
Good catch!
> Doing so, we also NULLify 'flow->udma_rflow' in a path that was lacking it.
Even better catch ;)
> Fixes: d70241913413 ("dmaengine: ti: k3-udma: Add glue layer for non DMAengine user")
> Signed-off-by: Christophe JAILLET <christophe.jaillet@...adoo.fr>
> ---
> Not sure that the last point of the description is correct. Maybe, the
> 'xudma_rflow_put / return -ENODEV;' should be kept in order not to
> override 'flow->udma_rflow'.
> ---
> drivers/dma/ti/k3-udma-glue.c | 30 ++++++++++++++++++++----------
> 1 file changed, 20 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/dma/ti/k3-udma-glue.c b/drivers/dma/ti/k3-udma-glue.c
> index dbccdc7c0ed5..890573eb1625 100644
> --- a/drivers/dma/ti/k3-udma-glue.c
> +++ b/drivers/dma/ti/k3-udma-glue.c
> @@ -578,12 +578,12 @@ static int k3_udma_glue_cfg_rx_flow(struct k3_udma_glue_rx_channel *rx_chn,
> if (IS_ERR(flow->udma_rflow)) {
> ret = PTR_ERR(flow->udma_rflow);
> dev_err(dev, "UDMAX rflow get err %d\n", ret);
> - goto err;
> + goto err_return;
return err; ?
> }
Optionally you could have moved the
rx_chn->flows_ready++;
here and
>
> if (flow->udma_rflow_id != xudma_rflow_get_id(flow->udma_rflow)) {
> - xudma_rflow_put(rx_chn->common.udmax, flow->udma_rflow);
> - return -ENODEV;
> + ret = -ENODEV;
> + goto err_rflow_put;
goto err;
> }
>
> /* request and cfg rings */
> @@ -592,7 +592,7 @@ static int k3_udma_glue_cfg_rx_flow(struct k3_udma_glue_rx_channel *rx_chn,
> if (!flow->ringrx) {
> ret = -ENODEV;
> dev_err(dev, "Failed to get RX ring\n");
> - goto err;
> + goto err_rflow_put;
> }
>
> flow->ringrxfdq = k3_ringacc_request_ring(rx_chn->common.ringacc,
> @@ -600,19 +600,19 @@ static int k3_udma_glue_cfg_rx_flow(struct k3_udma_glue_rx_channel *rx_chn,
> if (!flow->ringrxfdq) {
> ret = -ENODEV;
> dev_err(dev, "Failed to get RXFDQ ring\n");
> - goto err;
> + goto err_ringrx_free;
> }
>
> ret = k3_ringacc_ring_cfg(flow->ringrx, &flow_cfg->rx_cfg);
> if (ret) {
> dev_err(dev, "Failed to cfg ringrx %d\n", ret);
> - goto err;
> + goto err_ringrxfdq_free;
> }
>
> ret = k3_ringacc_ring_cfg(flow->ringrxfdq, &flow_cfg->rxfdq_cfg);
> if (ret) {
> dev_err(dev, "Failed to cfg ringrxfdq %d\n", ret);
> - goto err;
> + goto err_ringrxfdq_free;
> }
>
> if (rx_chn->remote) {
> @@ -662,7 +662,7 @@ static int k3_udma_glue_cfg_rx_flow(struct k3_udma_glue_rx_channel *rx_chn,
> if (ret) {
> dev_err(dev, "flow%d config failed: %d\n", flow->udma_rflow_id,
> ret);
> - goto err;
> + goto err_ringrxfdq_free;
> }
>
> rx_chn->flows_ready++;
> @@ -670,8 +670,18 @@ static int k3_udma_glue_cfg_rx_flow(struct k3_udma_glue_rx_channel *rx_chn,
> flow->udma_rflow_id, rx_chn->flows_ready);
>
> return 0;
> -err:
> - k3_udma_glue_release_rx_flow(rx_chn, flow_idx);
> +
> +err_ringrxfdq_free:
> + k3_ringacc_ring_free(flow->ringrxfdq);
> +
> +err_ringrx_free:
> + k3_ringacc_ring_free(flow->ringrx);
> +
> +err_rflow_put:
> + xudma_rflow_put(rx_chn->common.udmax, flow->udma_rflow);
> + flow->udma_rflow = NULL;
> +
> +err_return:
You could have kept the single err label and just copy the
release_rx_flow() without the rx_chn->flows_ready--;
I don't have anything against multiple labels as such, but a single one
might be easier to follow?
and you don't need the err_return, just return in place when you would
jump to it.
> return ret;
> }
>
>
- Péter
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
Powered by blists - more mailing lists