Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1225093 > unrolled thread

[PATCH 0/4] at_xdmac: improvment and fixes for the interleaved mode

Started byLudovic Desroches <ludovic.desroches@atmel.com>
First post2015-09-15 15:30 +0200
Last post2015-09-15 15:40 +0200
Articles 5 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [PATCH 0/4] at_xdmac: improvment and fixes for the interleaved mode Ludovic Desroches <ludovic.desroches@atmel.com> - 2015-09-15 15:30 +0200
    [PATCH 1/4] dmaengine: at_xdmac: handle numf > 1 Ludovic Desroches <ludovic.desroches@atmel.com> - 2015-09-15 15:30 +0200
    [PATCH 4/4] dmaengine: at_xdmac: clean used descriptor Ludovic Desroches <ludovic.desroches@atmel.com> - 2015-09-15 15:40 +0200
    [PATCH 2/4] dmaengine: at_xdmac: change block increment addressing mode Ludovic Desroches <ludovic.desroches@atmel.com> - 2015-09-15 15:40 +0200
    [PATCH 3/4] dmaengine: at_xdmac: fix memory leak in interleaved mode Ludovic Desroches <ludovic.desroches@atmel.com> - 2015-09-15 15:40 +0200

#1225093 — [PATCH 0/4] at_xdmac: improvment and fixes for the interleaved mode

FromLudovic Desroches <ludovic.desroches@atmel.com>
Date2015-09-15 15:30 +0200
Subject[PATCH 0/4] at_xdmac: improvment and fixes for the interleaved mode
Message-ID<q8Yt4-64o-7@gated-at.bofh.it>
Hi Vinod,

This set of patches introduces the support of 'numf > 1' case for the
interleaved mode and several fixes: 'change block increment addressing mode'
and 'clean used descriptor' can be backported to 4.2.

Maxime,

I had some conflicts to merge on a mainline kernel the 'handle numf > 1'
patch. Can you check if I have not done a mistake. Thanks.

Regards

Ludovic Desroches (2):
  dmaengine: at_xdmac: fix memory leak in interleaved mode
  dmaengine: at_xdmac: clean used descriptor

Maxime Ripard (2):
  dmaengine: at_xdmac: handle numf > 1
  dmaengine: at_xdmac: change block increment addressing mode

 drivers/dma/at_xdmac.c | 121 ++++++++++++++++++++++++++-----------------------
 1 file changed, 65 insertions(+), 56 deletions(-)

-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1225096 — [PATCH 1/4] dmaengine: at_xdmac: handle numf > 1

FromLudovic Desroches <ludovic.desroches@atmel.com>
Date2015-09-15 15:30 +0200
Subject[PATCH 1/4] dmaengine: at_xdmac: handle numf > 1
Message-ID<q8Yt4-64o-13@gated-at.bofh.it>
In reply to#1225093
From: Maxime Ripard <maxime.ripard@free-electrons.com>

Handle 'numf > 1' case for interleaved mode.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
---
 drivers/dma/at_xdmac.c | 104 ++++++++++++++++++++++++-------------------------
 1 file changed, 50 insertions(+), 54 deletions(-)

diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index a165b4b..0190d1c 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -929,13 +929,19 @@ at_xdmac_prep_interleaved(struct dma_chan *chan,
 {
 	struct at_xdmac_chan	*atchan = to_at_xdmac_chan(chan);
 	struct at_xdmac_desc	*prev = NULL, *first = NULL;
-	struct data_chunk	*chunk, *prev_chunk = NULL;
 	dma_addr_t		dst_addr, src_addr;
-	size_t			dst_skip, src_skip, len = 0;
-	size_t			prev_dst_icg = 0, prev_src_icg = 0;
+	size_t			src_skip = 0, dst_skip = 0, len = 0;
+	struct data_chunk	*chunk;
 	int			i;
 
-	if (!xt || (xt->numf != 1) || (xt->dir != DMA_MEM_TO_MEM))
+	if (!xt || !xt->numf || (xt->dir != DMA_MEM_TO_MEM))
+		return NULL;
+
+	/*
+	 * TODO: Handle the case where we have to repeat a chain of
+	 * descriptors...
+	 */
+	if ((xt->numf > 1) && (xt->frame_size > 1))
 		return NULL;
 
 	dev_dbg(chan2dev(chan), "%s: src=0x%08x, dest=0x%08x, numf=%d, frame_size=%d, flags=0x%lx\n",
@@ -945,66 +951,56 @@ at_xdmac_prep_interleaved(struct dma_chan *chan,
 	src_addr = xt->src_start;
 	dst_addr = xt->dst_start;
 
-	for (i = 0; i < xt->frame_size; i++) {
-		struct at_xdmac_desc *desc;
-		size_t src_icg, dst_icg;
-
-		chunk = xt->sgl + i;
+	if (xt->numf > 1) {
+		first = at_xdmac_interleaved_queue_desc(chan, atchan,
+							NULL,
+							src_addr, dst_addr,
+							xt, xt->sgl);
+		for (i = 0; i < xt->numf; i++)
+			at_xdmac_increment_block_count(chan, first);
+	} else {
+		for (i = 0; i < xt->frame_size; i++) {
+			size_t src_icg = 0, dst_icg = 0;
+			struct at_xdmac_desc *desc;
 
-		dst_icg = dmaengine_get_dst_icg(xt, chunk);
-		src_icg = dmaengine_get_src_icg(xt, chunk);
+			chunk = xt->sgl + i;
 
-		src_skip = chunk->size + src_icg;
-		dst_skip = chunk->size + dst_icg;
+			dst_icg = dmaengine_get_dst_icg(xt, chunk);
+			src_icg = dmaengine_get_src_icg(xt, chunk);
 
-		dev_dbg(chan2dev(chan),
-			"%s: chunk size=%d, src icg=%d, dst icg=%d\n",
-			__func__, chunk->size, src_icg, dst_icg);
+			src_skip = chunk->size + src_icg;
+			dst_skip = chunk->size + dst_icg;
 
-		/*
-		 * Handle the case where we just have the same
-		 * transfer to setup, we can just increase the
-		 * block number and reuse the same descriptor.
-		 */
-		if (prev_chunk && prev &&
-		    (prev_chunk->size == chunk->size) &&
-		    (prev_src_icg == src_icg) &&
-		    (prev_dst_icg == dst_icg)) {
 			dev_dbg(chan2dev(chan),
-				"%s: same configuration that the previous chunk, merging the descriptors...\n",
-				__func__);
-			at_xdmac_increment_block_count(chan, prev);
-			continue;
-		}
-
-		desc = at_xdmac_interleaved_queue_desc(chan, atchan,
-						       prev,
-						       src_addr, dst_addr,
-						       xt, chunk);
-		if (!desc) {
-			list_splice_init(&first->descs_list,
-					 &atchan->free_descs_list);
-			return NULL;
-		}
+				"%s: chunk size=%d, src icg=%d, dst icg=%d\n",
+				__func__, chunk->size, src_icg, dst_icg);
+
+			desc = at_xdmac_interleaved_queue_desc(chan, atchan,
+							       prev,
+							       src_addr, dst_addr,
+							       xt, chunk);
+			if (!desc) {
+				list_splice_init(&first->descs_list,
+						 &atchan->free_descs_list);
+				return NULL;
+			}
 
-		if (!first)
-			first = desc;
+			if (!first)
+				first = desc;
 
-		dev_dbg(chan2dev(chan), "%s: add desc 0x%p to descs_list 0x%p\n",
-			__func__, desc, first);
-		list_add_tail(&desc->desc_node, &first->descs_list);
+			dev_dbg(chan2dev(chan), "%s: add desc 0x%p to descs_list 0x%p\n",
+				__func__, desc, first);
+			list_add_tail(&desc->desc_node, &first->descs_list);
 
-		if (xt->src_sgl)
-			src_addr += src_skip;
+			if (xt->src_sgl)
+				src_addr += src_skip;
 
-		if (xt->dst_sgl)
-			dst_addr += dst_skip;
+			if (xt->dst_sgl)
+				dst_addr += dst_skip;
 
-		len += chunk->size;
-		prev_chunk = chunk;
-		prev_dst_icg = dst_icg;
-		prev_src_icg = src_icg;
-		prev = desc;
+			len += chunk->size;
+			prev = desc;
+		}
 	}
 
 	first->tx_dma_desc.cookie = -EBUSY;
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1225101 — [PATCH 4/4] dmaengine: at_xdmac: clean used descriptor

FromLudovic Desroches <ludovic.desroches@atmel.com>
Date2015-09-15 15:40 +0200
Subject[PATCH 4/4] dmaengine: at_xdmac: clean used descriptor
Message-ID<q8YCJ-6fP-13@gated-at.bofh.it>
In reply to#1225093
When putting back a descriptor to the free descs list, some fields are
not set to 0, it can cause bugs if someone uses it without having this
in mind.
Descriptor are not put back one by one so it is easier to clean
descriptors when we request them.

Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Cc: stable@vger.kernel.org #4.2
---
 drivers/dma/at_xdmac.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index fbd4093..b5e132d 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -455,6 +455,15 @@ static struct at_xdmac_desc *at_xdmac_alloc_desc(struct dma_chan *chan,
 	return desc;
 }
 
+void at_xdmac_init_used_desc(struct at_xdmac_desc *desc)
+{
+	memset(&desc->lld, 0, sizeof(desc->lld));
+	INIT_LIST_HEAD(&desc->descs_list);
+	desc->direction = DMA_TRANS_NONE;
+	desc->xfer_size = 0;
+	desc->active_xfer = false;
+}
+
 /* Call must be protected by lock. */
 static struct at_xdmac_desc *at_xdmac_get_desc(struct at_xdmac_chan *atchan)
 {
@@ -466,7 +475,7 @@ static struct at_xdmac_desc *at_xdmac_get_desc(struct at_xdmac_chan *atchan)
 		desc = list_first_entry(&atchan->free_descs_list,
 					struct at_xdmac_desc, desc_node);
 		list_del(&desc->desc_node);
-		desc->active_xfer = false;
+		at_xdmac_init_used_desc(desc);
 	}
 
 	return desc;
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1225105 — [PATCH 2/4] dmaengine: at_xdmac: change block increment addressing mode

FromLudovic Desroches <ludovic.desroches@atmel.com>
Date2015-09-15 15:40 +0200
Subject[PATCH 2/4] dmaengine: at_xdmac: change block increment addressing mode
Message-ID<q8YCK-6fP-25@gated-at.bofh.it>
In reply to#1225093
From: Maxime Ripard <maxime.ripard@free-electrons.com>

The addressing mode we were using was not only incrementing the address at
each microblock, but also at each data boundary, which was severely slowing
the transfer, without any benefit since we were not using the data stride.

Switch to the micro block increment only in order to get back to an
acceptable performance level.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Fixes: 6007ccb57744 ("dmaengine: xdmac: Add interleaved transfer support")
Cc: stable@vger.kernel.org #4.2
---
 drivers/dma/at_xdmac.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index 0190d1c..3952bff 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -875,14 +875,14 @@ at_xdmac_interleaved_queue_desc(struct dma_chan *chan,
 
 	if (xt->src_inc) {
 		if (xt->src_sgl)
-			chan_cc |=  AT_XDMAC_CC_SAM_UBS_DS_AM;
+			chan_cc |=  AT_XDMAC_CC_SAM_UBS_AM;
 		else
 			chan_cc |=  AT_XDMAC_CC_SAM_INCREMENTED_AM;
 	}
 
 	if (xt->dst_inc) {
 		if (xt->dst_sgl)
-			chan_cc |=  AT_XDMAC_CC_DAM_UBS_DS_AM;
+			chan_cc |=  AT_XDMAC_CC_DAM_UBS_AM;
 		else
 			chan_cc |=  AT_XDMAC_CC_DAM_INCREMENTED_AM;
 	}
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1225108 — [PATCH 3/4] dmaengine: at_xdmac: fix memory leak in interleaved mode

FromLudovic Desroches <ludovic.desroches@atmel.com>
Date2015-09-15 15:40 +0200
Subject[PATCH 3/4] dmaengine: at_xdmac: fix memory leak in interleaved mode
Message-ID<q8YCK-6fP-37@gated-at.bofh.it>
In reply to#1225093
In interleaved mode, when numf > 1, we have only one descriptor for the
transfer but this descriptor has to be added to the descs_list. If not,
when doing remove_xfer, the descriptor won't be put back in the
free_descs_list.

Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
---
 drivers/dma/at_xdmac.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index 3952bff..fbd4093 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -958,6 +958,10 @@ at_xdmac_prep_interleaved(struct dma_chan *chan,
 							xt, xt->sgl);
 		for (i = 0; i < xt->numf; i++)
 			at_xdmac_increment_block_count(chan, first);
+
+		dev_dbg(chan2dev(chan), "%s: add desc 0x%p to descs_list 0x%p\n",
+			__func__, first, first);
+		list_add_tail(&first->desc_node, &first->descs_list);
 	} else {
 		for (i = 0; i < xt->frame_size; i++) {
 			size_t src_icg = 0, dst_icg = 0;
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web