From: Jie Hai <haijie1@huawei.com>
To: <vkoul@kernel.org>
Cc: <dmaengine@vger.kernel.org>, <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] dmaengine: virt-dma : fix vchan error on multi-thread
Date: Wed, 31 Jan 2024 09:32:20 +0800 [thread overview]
Message-ID: <665af2fb-5ac7-cfb6-0fc4-3dae816629b1@huawei.com> (raw)
In-Reply-To: <20230720114212.51224-1-haijie1@huawei.com>
Hi, Vkoul,
Kindly ping...
Thanks,
Jie Hai
On 2023/7/20 19:42, Jie Hai wrote:
> List desc_allocated was introduced for the case of a transfer
> submitted multiple times. But elegating descriptors on the list
> causes other problems.
>
> For example, in the multi-thread scenario, which tasks are
> continuously created and submitted by each thread. If one of
> the threads calls dmaengine_terminate_all, for dirvers using
> vchan_get_all_descriptors, all descriptors will be freed. If
> there's another thread submitting a transfer A by
> vchan_tx_submit, the following results may be generated:
> 1. desc A is freeing -> visit wrong address of node prep/next.
> 2. desc A is freed -> visit invalid address of A.
>
> In the above case, calltrace is generated and the system is
> suspended. This can be tested by dmatest.
>
> This patch removes desc_allocated from vchan_get_all_descriptors,
> and add new function 'vchan_get_all_allocated_descs' to get all
> descriptors ever allocated.
>
> And apply vchan_get_all_allocated_descs to free chan resource and
> vchan_get_all_descriptors to terminate all transfers, respectively.
> This avoids freeing up descriptors in use by other threads.
>
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> ---
> drivers/dma/fsl-edma-common.c | 2 +-
> drivers/dma/fsl-qdma.c | 2 +-
> drivers/dma/sf-pdma/sf-pdma.c | 2 +-
> drivers/dma/virt-dma.h | 20 ++++++++++++++++++--
> 4 files changed, 21 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c
> index a06a1575a2a5..c6d2e54ab85d 100644
> --- a/drivers/dma/fsl-edma-common.c
> +++ b/drivers/dma/fsl-edma-common.c
> @@ -674,7 +674,7 @@ void fsl_edma_free_chan_resources(struct dma_chan *chan)
> if (edma->drvdata->dmamuxs)
> fsl_edma_chan_mux(fsl_chan, 0, false);
> fsl_chan->edesc = NULL;
> - vchan_get_all_descriptors(&fsl_chan->vchan, &head);
> + vchan_get_all_allocated_descs(&fsl_chan->vchan, &head);
> fsl_edma_unprep_slave_dma(fsl_chan);
> spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
>
> diff --git a/drivers/dma/fsl-qdma.c b/drivers/dma/fsl-qdma.c
> index eddb2688f234..5ffd7ba92058 100644
> --- a/drivers/dma/fsl-qdma.c
> +++ b/drivers/dma/fsl-qdma.c
> @@ -311,7 +311,7 @@ static void fsl_qdma_free_chan_resources(struct dma_chan *chan)
> LIST_HEAD(head);
>
> spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
> - vchan_get_all_descriptors(&fsl_chan->vchan, &head);
> + vchan_get_all_allocated_descs(&fsl_chan->vchan, &head);
> spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
>
> vchan_dma_desc_free_list(&fsl_chan->vchan, &head);
> diff --git a/drivers/dma/sf-pdma/sf-pdma.c b/drivers/dma/sf-pdma/sf-pdma.c
> index d1c6956af452..f35dc68e1a7c 100644
> --- a/drivers/dma/sf-pdma/sf-pdma.c
> +++ b/drivers/dma/sf-pdma/sf-pdma.c
> @@ -144,7 +144,7 @@ static void sf_pdma_free_chan_resources(struct dma_chan *dchan)
> sf_pdma_disable_request(chan);
> kfree(chan->desc);
> chan->desc = NULL;
> - vchan_get_all_descriptors(&chan->vchan, &head);
> + vchan_get_all_allocated_descs(&chan->vchan, &head);
> sf_pdma_disclaim_chan(chan);
> spin_unlock_irqrestore(&chan->vchan.lock, flags);
> vchan_dma_desc_free_list(&chan->vchan, &head);
> diff --git a/drivers/dma/virt-dma.h b/drivers/dma/virt-dma.h
> index e9f5250fbe4d..65b4f3bdecf7 100644
> --- a/drivers/dma/virt-dma.h
> +++ b/drivers/dma/virt-dma.h
> @@ -177,13 +177,29 @@ static inline struct virt_dma_desc *vchan_next_desc(struct virt_dma_chan *vc)
> static inline void vchan_get_all_descriptors(struct virt_dma_chan *vc,
> struct list_head *head)
> {
> - list_splice_tail_init(&vc->desc_allocated, head);
> list_splice_tail_init(&vc->desc_submitted, head);
> list_splice_tail_init(&vc->desc_issued, head);
> list_splice_tail_init(&vc->desc_completed, head);
> list_splice_tail_init(&vc->desc_terminated, head);
> }
>
> +/**
> + * vchan_get_all_allocated_descs - obtain all descriptors
> + * @vc: virtual channel to get descriptors from
> + * @head: list of descriptors found
> + *
> + * vc.lock must be held by caller
> + *
> + * Removes all descriptors from internal lists, and provides a list of all
> + * descriptors found
> + */
> +static inline void vchan_get_all_allocated_descs(struct virt_dma_chan *vc,
> + struct list_head *head)
> +{
> + list_splice_tail_init(&vc->desc_allocated, head);
> + vchan_get_all_descriptors(vc, head);
> +}
> +
> static inline void vchan_free_chan_resources(struct virt_dma_chan *vc)
> {
> struct virt_dma_desc *vd;
> @@ -191,7 +207,7 @@ static inline void vchan_free_chan_resources(struct virt_dma_chan *vc)
> LIST_HEAD(head);
>
> spin_lock_irqsave(&vc->lock, flags);
> - vchan_get_all_descriptors(vc, &head);
> + vchan_get_all_allocated_descs(vc, &head);
> list_for_each_entry(vd, &head, node)
> dmaengine_desc_clear_reuse(&vd->tx);
> spin_unlock_irqrestore(&vc->lock, flags);
next prev parent reply other threads:[~2024-01-31 1:32 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-20 11:42 [PATCH] dmaengine: virt-dma : fix vchan error on multi-thread Jie Hai
2023-09-25 1:09 ` Jie Hai
2023-12-08 1:52 ` Jie Hai
2024-01-31 1:32 ` Jie Hai [this message]
2024-06-20 2:53 ` [PATCH v2] dmaegine: virt-dma : Fix multi-user with vchan Jie Hai
2024-06-20 2:53 ` Jie Hai
2024-06-20 14:38 ` Frank Li
2024-06-20 14:38 ` Frank Li
2024-06-20 16:17 ` Vinod Koul
2024-06-20 16:17 ` Vinod Koul
2024-06-29 2:00 ` Jie Hai
2024-06-29 2:00 ` Jie Hai
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=665af2fb-5ac7-cfb6-0fc4-3dae816629b1@huawei.com \
--to=haijie1@huawei.com \
--cc=dmaengine@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=vkoul@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.