From: Vinod Koul <vkoul@kernel.org>
To: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
Cc: dmaengine@vger.kernel.org
Subject: Re: [PATCH 3/3] dmaengine: ptdma: Utilize the AE4DMA engine's multi-queue functionality
Date: Mon, 10 Feb 2025 19:48:16 +0530 [thread overview]
Message-ID: <Z6oKqKncVc9AL2Tb@vaman> (raw)
In-Reply-To: <20250203162511.911946-4-Basavaraj.Natikar@amd.com>
On 03-02-25, 21:55, Basavaraj Natikar wrote:
> As AE4DMA offers multi-channel functionality compared to PTDMA’s single
> queue, utilize multi-queue, which supports higher speeds than PTDMA, to
> achieve higher performance using the AE4DMA workqueue based mechanism.
>
> Fixes: 69a47b16a51b ("dmaengine: ptdma: Extend ptdma to support multi-channel and version")
Why is this a fix, again!
> Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
> ---
> drivers/dma/amd/ae4dma/ae4dma.h | 2 +
> drivers/dma/amd/ptdma/ptdma-dmaengine.c | 90 ++++++++++++++++++++++++-
> 2 files changed, 89 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/dma/amd/ae4dma/ae4dma.h b/drivers/dma/amd/ae4dma/ae4dma.h
> index 265c5d436008..57f6048726bb 100644
> --- a/drivers/dma/amd/ae4dma/ae4dma.h
> +++ b/drivers/dma/amd/ae4dma/ae4dma.h
> @@ -37,6 +37,8 @@
> #define AE4_DMA_VERSION 4
> #define CMD_AE4_DESC_DW0_VAL 2
>
> +#define AE4_TIME_OUT 5000
> +
> struct ae4_msix {
> int msix_count;
> struct msix_entry msix_entry[MAX_AE4_HW_QUEUES];
> diff --git a/drivers/dma/amd/ptdma/ptdma-dmaengine.c b/drivers/dma/amd/ptdma/ptdma-dmaengine.c
> index 35c84ec9608b..715ac3ae067b 100644
> --- a/drivers/dma/amd/ptdma/ptdma-dmaengine.c
> +++ b/drivers/dma/amd/ptdma/ptdma-dmaengine.c
> @@ -198,8 +198,10 @@ static struct pt_dma_desc *pt_handle_active_desc(struct pt_dma_chan *chan,
> {
> struct dma_async_tx_descriptor *tx_desc;
> struct virt_dma_desc *vd;
> + struct pt_device *pt;
> unsigned long flags;
>
> + pt = chan->pt;
> /* Loop over descriptors until one is found with commands */
> do {
> if (desc) {
> @@ -217,7 +219,7 @@ static struct pt_dma_desc *pt_handle_active_desc(struct pt_dma_chan *chan,
>
> spin_lock_irqsave(&chan->vc.lock, flags);
>
> - if (desc) {
> + if (pt->ver != AE4_DMA_VERSION && desc) {
> if (desc->status != DMA_COMPLETE) {
> if (desc->status != DMA_ERROR)
> desc->status = DMA_COMPLETE;
> @@ -235,7 +237,7 @@ static struct pt_dma_desc *pt_handle_active_desc(struct pt_dma_chan *chan,
>
> spin_unlock_irqrestore(&chan->vc.lock, flags);
>
> - if (tx_desc) {
> + if (pt->ver != AE4_DMA_VERSION && tx_desc) {
Why should this handling be different for DMA_VERSION?
> dmaengine_desc_get_callback_invoke(tx_desc, NULL);
> dma_run_dependencies(tx_desc);
> vchan_vdesc_fini(vd);
> @@ -245,11 +247,25 @@ static struct pt_dma_desc *pt_handle_active_desc(struct pt_dma_chan *chan,
> return NULL;
> }
>
> +static inline bool ae4_core_queue_full(struct pt_cmd_queue *cmd_q)
> +{
> + u32 front_wi = readl(cmd_q->reg_control + AE4_WR_IDX_OFF);
> + u32 rear_ri = readl(cmd_q->reg_control + AE4_RD_IDX_OFF);
> +
> + if (((MAX_CMD_QLEN + front_wi - rear_ri) % MAX_CMD_QLEN) >= (MAX_CMD_QLEN - 1))
> + return true;
> +
> + return false;
> +}
> +
> static void pt_cmd_callback(void *data, int err)
> {
> struct pt_dma_desc *desc = data;
> + struct ae4_cmd_queue *ae4cmd_q;
> struct dma_chan *dma_chan;
> struct pt_dma_chan *chan;
> + struct ae4_device *ae4;
> + struct pt_device *pt;
> int ret;
>
> if (err == -EINPROGRESS)
> @@ -257,11 +273,32 @@ static void pt_cmd_callback(void *data, int err)
>
> dma_chan = desc->vd.tx.chan;
> chan = to_pt_chan(dma_chan);
> + pt = chan->pt;
>
> if (err)
> desc->status = DMA_ERROR;
>
> while (true) {
> + if (pt->ver == AE4_DMA_VERSION) {
> + ae4 = container_of(pt, struct ae4_device, pt);
> + ae4cmd_q = &ae4->ae4cmd_q[chan->id];
> +
> + if (ae4cmd_q->q_cmd_count >= (CMD_Q_LEN - 1) ||
> + ae4_core_queue_full(&ae4cmd_q->cmd_q)) {
> + wake_up(&ae4cmd_q->q_w);
> +
> + if (wait_for_completion_timeout(&ae4cmd_q->cmp,
> + msecs_to_jiffies(AE4_TIME_OUT))
> + == 0) {
> + dev_err(pt->dev, "TIMEOUT %d:\n", ae4cmd_q->id);
> + break;
> + }
> +
> + reinit_completion(&ae4cmd_q->cmp);
> + continue;
> + }
> + }
> +
> /* Check for DMA descriptor completion */
> desc = pt_handle_active_desc(chan, desc);
>
> @@ -296,6 +333,49 @@ static struct pt_dma_desc *pt_alloc_dma_desc(struct pt_dma_chan *chan,
> return desc;
> }
>
> +static void pt_cmd_callback_work(void *data, int err)
> +{
> + struct dma_async_tx_descriptor *tx_desc;
> + struct pt_dma_desc *desc = data;
> + struct dma_chan *dma_chan;
> + struct virt_dma_desc *vd;
> + struct pt_dma_chan *chan;
> + unsigned long flags;
> +
> + dma_chan = desc->vd.tx.chan;
> + chan = to_pt_chan(dma_chan);
> +
> + if (err == -EINPROGRESS)
> + return;
> +
> + tx_desc = &desc->vd.tx;
> + vd = &desc->vd;
> +
> + if (err)
> + desc->status = DMA_ERROR;
> +
> + spin_lock_irqsave(&chan->vc.lock, flags);
> + if (desc) {
> + if (desc->status != DMA_COMPLETE) {
> + if (desc->status != DMA_ERROR)
> + desc->status = DMA_COMPLETE;
> +
> + dma_cookie_complete(tx_desc);
> + dma_descriptor_unmap(tx_desc);
> + } else {
> + tx_desc = NULL;
> + }
> + }
> + spin_unlock_irqrestore(&chan->vc.lock, flags);
> +
> + if (tx_desc) {
> + dmaengine_desc_get_callback_invoke(tx_desc, NULL);
> + dma_run_dependencies(tx_desc);
> + list_del(&desc->vd.node);
> + vchan_vdesc_fini(vd);
> + }
> +}
Why do we have callback in driver...?
> +
> static struct pt_dma_desc *pt_create_desc(struct dma_chan *dma_chan,
> dma_addr_t dst,
> dma_addr_t src,
> @@ -327,6 +407,7 @@ static struct pt_dma_desc *pt_create_desc(struct dma_chan *dma_chan,
> desc->len = len;
>
> if (pt->ver == AE4_DMA_VERSION) {
> + pt_cmd->pt_cmd_callback = pt_cmd_callback_work;
> ae4 = container_of(pt, struct ae4_device, pt);
> ae4cmd_q = &ae4->ae4cmd_q[chan->id];
> mutex_lock(&ae4cmd_q->cmd_lock);
> @@ -367,13 +448,16 @@ static void pt_issue_pending(struct dma_chan *dma_chan)
> {
> struct pt_dma_chan *chan = to_pt_chan(dma_chan);
> struct pt_dma_desc *desc;
> + struct pt_device *pt;
> unsigned long flags;
> bool engine_is_idle = true;
>
> + pt = chan->pt;
> +
> spin_lock_irqsave(&chan->vc.lock, flags);
>
> desc = pt_next_dma_desc(chan);
> - if (desc)
> + if (desc && pt->ver != AE4_DMA_VERSION)
> engine_is_idle = false;
>
> vchan_issue_pending(&chan->vc);
> --
> 2.25.1
--
~Vinod
next prev parent reply other threads:[~2025-02-10 14:18 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-03 16:25 [PATCH 0/3] Fixes to the AE4DMA Basavaraj Natikar
2025-02-03 16:25 ` [PATCH 1/3] dmaengine: ae4dma: Remove deprecated PCI IDs Basavaraj Natikar
2025-02-10 13:59 ` Vinod Koul
2025-02-10 14:18 ` Basavaraj Natikar
2025-02-03 16:25 ` [PATCH 2/3] dmaengine: ae4dma: Use the MSI count and its corresponding IRQ number Basavaraj Natikar
2025-02-03 16:25 ` [PATCH 3/3] dmaengine: ptdma: Utilize the AE4DMA engine's multi-queue functionality Basavaraj Natikar
2025-02-10 14:18 ` Vinod Koul [this message]
2025-02-10 14:26 ` Basavaraj Natikar
2025-02-10 14:37 ` Basavaraj Natikar
2025-03-10 21:06 ` [PATCH 0/3] Fixes to the AE4DMA Vinod Koul
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=Z6oKqKncVc9AL2Tb@vaman \
--to=vkoul@kernel.org \
--cc=Basavaraj.Natikar@amd.com \
--cc=dmaengine@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.