Skip to contentSkip to conversation

sparc/iommu: fix ->map_sg return value

PATCH In review Christoph Hellwig 2 participants 4 messages Dec 16, 2018 – Dec 19, 2018 SPARC + UltraSPARC (sparc/sparc64)

lore
Share & tools
lore
#0 lore raw

PATCH 2/2 sparc/iommu: fix ->map_sg return value

Just decrementing the sz value will lead to an incorrect return value. Instead of just introducing a local variable switch to the standard for_each_sg helper and standard naming of the arguments.

Fixes ce65d36f3e ("sparc: remove the sparc32_dma_ops indirection")
---
 arch/sparc/mm/iommu.c | 39 ++++++++++++++++++---------------------
 1 file changed, 18 insertions(+), 21 deletions(-)
arch/sparc/mm/iommu.c +18 -21
index 3599485717e7..25ab0fa042ef 100644
@@ -241,32 +241,31 @@ static dma_addr_t sbus_iommu_map_page_pflush(struct device *dev,
 	return __sbus_iommu_map_page(dev, page, offset, len);
 }
 
-static int sbus_iommu_map_sg_gflush(struct device *dev, struct scatterlist *sg,
-		int sz, enum dma_data_direction dir, unsigned long attrs)
+static int sbus_iommu_map_sg_gflush(struct device *dev, struct scatterlist *sgl,
+		int nents, enum dma_data_direction dir, unsigned long attrs)
 {
-	int n;
+	struct scatterlist *sg;
+	int j, n;
 
 	flush_page_for_dma(0);
-	while (sz != 0) {
-		--sz;
+
+	for_each_sg(sgl, sg, nents, j) {
 		n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
 		sg->dma_address = iommu_get_one(dev, sg_page(sg), n) + sg->offset;
 		sg->dma_length = sg->length;
-		sg = sg_next(sg);
 	}
 
-	return sz;
+	return nents;
 }
 
-static int sbus_iommu_map_sg_pflush(struct device *dev, struct scatterlist *sg,
-		int sz, enum dma_data_direction dir, unsigned long attrs)
+static int sbus_iommu_map_sg_pflush(struct device *dev, struct scatterlist *sgl,
+		int nents, enum dma_data_direction dir, unsigned long attrs)
 {
 	unsigned long page, oldpage = 0;
-	int n, i;
-
-	while(sz != 0) {
-		--sz;
+	struct scatterlist *sg;
+	int i, j, n;
 
+	for_each_sg(sgl, sg, nents, j) {
 		n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
 
 		/*
@@ -286,10 +285,9 @@ static int sbus_iommu_map_sg_pflush(struct device *dev, struct scatterlist *sg,
 
 		sg->dma_address = iommu_get_one(dev, sg_page(sg), n) + sg->offset;
 		sg->dma_length = sg->length;
-		sg = sg_next(sg);
 	}
 
-	return sz;
+	return nents;
 }
 
 static void iommu_release_one(struct device *dev, u32 busa, int npages)
@@ -318,17 +316,16 @@ static void sbus_iommu_unmap_page(struct device *dev, dma_addr_t dma_addr,
 	iommu_release_one(dev, dma_addr & PAGE_MASK, npages);
 }
 
-static void sbus_iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
-		int sz, enum dma_data_direction dir, unsigned long attrs)
+static void sbus_iommu_unmap_sg(struct device *dev, struct scatterlist *sgl,
+		int nents, enum dma_data_direction dir, unsigned long attrs)
 {
-	int n;
+	struct scatterlist *sg;
+	int j, n;
 
-	while(sz != 0) {
-		--sz;
+	for_each_sg(sgl, sg, nents, j) {
 		n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
 		iommu_release_one(dev, sg->dma_address & PAGE_MASK, n);
 		sg->dma_address = 0x21212121;
-		sg = sg_next(sg);
 	}
 }
 
Signature · 1 line
2.19.2
Acked-by on v1 2/2
#1 lore raw

Hi Christoph.

Quoted 7 lines · Christoph Hellwig

Just decrementing the sz value will lead to an incorrect return value. Instead of just introducing a local variable switch to the standard for_each_sg helper and standard naming of the arguments.

Fixes ce65d36f3e ("sparc: remove the sparc32_dma_ops indirection")

Some random comments below - nothing that calls for any change of this patch.

Quoted 10 lines
---
 arch/sparc/mm/iommu.c | 39 ++++++++++++++++++---------------------
 1 file changed, 18 insertions(+), 21 deletions(-)
arch/sparc/mm/iommu.c +0 -0
index 3599485717e7..25ab0fa042ef 100644
@@ -241,32 +241,31 @@ static dma_addr_t sbus_iommu_map_page_pflush(struct device *dev,
 	return __sbus_iommu_map_page(dev, page, offset, len);

arch/sparc/mm/iommu.c static dma_addr_t sbus_iommu_map_page_pflush(struct device *dev, · line 248

Quoted 10 lines
arch/sparc/mm/iommu.c +4 -3
 }
 
-static int sbus_iommu_map_sg_gflush(struct device *dev, struct scatterlist *sg,
-		int sz, enum dma_data_direction dir, unsigned long attrs)
+static int sbus_iommu_map_sg_gflush(struct device *dev, struct scatterlist *sgl,
+		int nents, enum dma_data_direction dir, unsigned long attrs)
 {
-	int n;
+	struct scatterlist *sg;
+	int j, n;

Nit - in the other use of for_each_sg() you used "i" as the variable named. It confused me a little to see "j".

sg-lenght and sg->offsett are both unsigned int. So n should looking at this piece of code be unsigned int. But then iommu_get_one() takes an int as argument. So the real issue seems to be that iommu_get_one() should have npages be an unsigned int. And your code is fine.

If you had named n for npages it would have been a little more readable.

Quoted 70 lines
arch/sparc/mm/iommu.c +14 -18
 	flush_page_for_dma(0);
-	while (sz != 0) {
-		--sz;
+
+	for_each_sg(sgl, sg, nents, j) {
 		n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
 		sg->dma_address = iommu_get_one(dev, sg_page(sg), n) + sg->offset;
 		sg->dma_length = sg->length;
-		sg = sg_next(sg);
 	}
 
-	return sz;
+	return nents;
 }
 
-static int sbus_iommu_map_sg_pflush(struct device *dev, struct scatterlist *sg,
-		int sz, enum dma_data_direction dir, unsigned long attrs)
+static int sbus_iommu_map_sg_pflush(struct device *dev, struct scatterlist *sgl,
+		int nents, enum dma_data_direction dir, unsigned long attrs)
 {
 	unsigned long page, oldpage = 0;
-	int n, i;
-
-	while(sz != 0) {
-		--sz;
+	struct scatterlist *sg;
+	int i, j, n;
 
+	for_each_sg(sgl, sg, nents, j) {
 		n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
 
 		/*
@@ -286,10 +285,9 @@ static int sbus_iommu_map_sg_pflush(struct device *dev, struct scatterlist *sg,
 
 		sg->dma_address = iommu_get_one(dev, sg_page(sg), n) + sg->offset;
 		sg->dma_length = sg->length;
-		sg = sg_next(sg);
 	}
 
-	return sz;
+	return nents;
 }
 
 static void iommu_release_one(struct device *dev, u32 busa, int npages)
@@ -318,17 +316,16 @@ static void sbus_iommu_unmap_page(struct device *dev, dma_addr_t dma_addr,
 	iommu_release_one(dev, dma_addr & PAGE_MASK, npages);
 }
 
-static void sbus_iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
-		int sz, enum dma_data_direction dir, unsigned long attrs)
+static void sbus_iommu_unmap_sg(struct device *dev, struct scatterlist *sgl,
+		int nents, enum dma_data_direction dir, unsigned long attrs)
 {
-	int n;
+	struct scatterlist *sg;
+	int j, n;
 
-	while(sz != 0) {
-		--sz;
+	for_each_sg(sgl, sg, nents, j) {
 		n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
 		iommu_release_one(dev, sg->dma_address & PAGE_MASK, n);
 		sg->dma_address = 0x21212121;
-		sg = sg_next(sg);
 	}
 }
 
Signature · 1 line
2.19.2
#2 lore raw
In reply to Christoph Hellwig
Quoted 4 lines · Sam Ravnborg

Review

Quoted 2 lines
(quoted diff) +2 -0
+	struct scatterlist *sg;
+	int j, n;

Nit - in the other use of for_each_sg() you used "i" as the variable named. It confused me a little to see "j".

I think this was a copy and paste from the one function where i was already taken. I can remove it here.

Quoted 7 lines

sg-lenght and sg->offsett are both unsigned int. So n should looking at this piece of code be unsigned int. But then iommu_get_one() takes an int as argument. So the real issue seems to be that iommu_get_one() should have npages be an unsigned int. And your code is fine.

If you had named n for npages it would have been a little more readable.

Well, n isn't really new here but from the existing code. I see plenty of potential for the usual cleanups in that code..

#3 lore raw
In reply to Christoph Hellwig
Quoted 15 lines · Christoph Hellwig
Quoted 4 lines · Sam Ravnborg

Review

Quoted 2 lines
(quoted diff) +2 -0
+	struct scatterlist *sg;
+	int j, n;

Nit - in the other use of for_each_sg() you used "i" as the variable named. It confused me a little to see "j".

I think this was a copy and paste from the one function where i was already taken. I can remove it here.

Quoted 6 lines

sg-lenght and sg->offsett are both unsigned int. So n should looking at this piece of code be unsigned int. But then iommu_get_one() takes an int as argument. So the real issue seems to be that iommu_get_one() should have npages be an unsigned int. And your code is fine.

Quoted 4 lines
Quoted 1 line

If you had named n for npages it would have been a little more readable.

Well, n isn't really new here but from the existing code. I see plenty of potential for the usual cleanups in that code..

Yep. So better leave it as it is.
Then someone with a little more sparc love could do it one day.

Sam