All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V2] net/mlx4: Get rid of page operation after dma_alloc_coherent
@ 2018-12-18 19:06 Stephen Warren
  2018-12-18 20:56 ` Christoph Hellwig
  0 siblings, 1 reply; 5+ messages in thread
From: Stephen Warren @ 2018-12-18 19:06 UTC (permalink / raw)
  To: Tariq Toukan, xavier.huwei
  Cc: netdev, linux-rdma, Doug Ledford, Jason Gunthorpe,
	Christoph Hellwig, Stephen Warren

From: Stephen Warren <swarren@nvidia.com>

This patch solves a crash at the time of mlx4 driver unload or system
shutdown. The crash occurs because dma_alloc_coherent() returns one
value in mlx4_alloc_icm_coherent(), but a different value is passed to
dma_free_coherent() in mlx4_free_icm_coherent(). In turn this is because
when allocated, that pointer is passed to sg_set_buf() to record it,
then when freed it is re-calculated by calling
lowmem_page_address(sg_page()) which returns a different value. Solve
this by recording the value that dma_alloc_coherent() returns, and
passing this to dma_free_coherent().

This change is equivalent to commit 378efe798ecf ("RDMA/hns: Get rid of
page operation after dma_alloc_coherent"). That change was described as:

> In general, dma_alloc_coherent() returns a CPU virtual address and
> a DMA address, and we have no guarantee that the underlying memory
> even has an associated struct page at all.
>
> This patch gets rid of the page operation after dma_alloc_coherent,
> and records the VA returned form dma_alloc_coherent in the struct
> of hem in hns RoCE driver.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
v2:
- Rework mlx4_table_find() to explicitly calculate the returned address
  differently depending on wheter the table was allocated using
  dma_alloc_coherent() or alloc_pages(), which in turn allows the
  changes to mlx4_alloc_icm_pages() to be dropped.
- Drop changes to mlx4_alloc/free_icm_pages. This path uses
  pci_map_sg() which can re-write the sg list which in turn would cause
  chunk->mem[] (the sg list) and chunk->buf[] to become inconsistent.
- Enhance commit description.

Note: I've tested this patch in a downstream 4.14 based kernel (using
ibping, ib_read_bw, and ib_write_bw), but can't test it in mainline
since my system isn't supported there yet. I have compile-tested it in
mainline at least, for ARM64.
---
 drivers/net/ethernet/mellanox/mlx4/icm.c | 30 +++++++++++++++---------
 drivers/net/ethernet/mellanox/mlx4/icm.h |  1 +
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.c b/drivers/net/ethernet/mellanox/mlx4/icm.c
index 4b4351141b94..901110c7530a 100644
--- a/drivers/net/ethernet/mellanox/mlx4/icm.c
+++ b/drivers/net/ethernet/mellanox/mlx4/icm.c
@@ -72,7 +72,7 @@ static void mlx4_free_icm_coherent(struct mlx4_dev *dev, struct mlx4_icm_chunk *
 	for (i = 0; i < chunk->npages; ++i)
 		dma_free_coherent(&dev->persist->pdev->dev,
 				  chunk->mem[i].length,
-				  lowmem_page_address(sg_page(&chunk->mem[i])),
+				  chunk->buf[i],
 				  sg_dma_address(&chunk->mem[i]));
 }
 
@@ -112,20 +112,20 @@ static int mlx4_alloc_icm_pages(struct scatterlist *mem, int order,
 }
 
 static int mlx4_alloc_icm_coherent(struct device *dev, struct scatterlist *mem,
-				    int order, gfp_t gfp_mask)
+				   void **buf, int order, gfp_t gfp_mask)
 {
-	void *buf = dma_alloc_coherent(dev, PAGE_SIZE << order,
-				       &sg_dma_address(mem), gfp_mask);
-	if (!buf)
+	*buf = dma_alloc_coherent(dev, PAGE_SIZE << order,
+				  &sg_dma_address(mem), gfp_mask);
+	if (!*buf)
 		return -ENOMEM;
 
-	if (offset_in_page(buf)) {
+	if (offset_in_page(*buf)) {
 		dma_free_coherent(dev, PAGE_SIZE << order,
-				  buf, sg_dma_address(mem));
+				  *buf, sg_dma_address(mem));
 		return -ENOMEM;
 	}
 
-	sg_set_buf(mem, buf, PAGE_SIZE << order);
+	mem->length = PAGE_SIZE << order;
 	sg_dma_len(mem) = PAGE_SIZE << order;
 	return 0;
 }
@@ -174,6 +174,7 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
 			sg_init_table(chunk->mem, MLX4_ICM_CHUNK_LEN);
 			chunk->npages = 0;
 			chunk->nsg    = 0;
+			memset(chunk->buf, 0, sizeof(chunk->buf));
 			list_add_tail(&chunk->list, &icm->chunk_list);
 		}
 
@@ -187,6 +188,7 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
 		if (coherent)
 			ret = mlx4_alloc_icm_coherent(&dev->persist->pdev->dev,
 						      &chunk->mem[chunk->npages],
+						      &chunk->buf[chunk->npages],
 						      cur_order, mask);
 		else
 			ret = mlx4_alloc_icm_pages(&chunk->mem[chunk->npages],
@@ -320,7 +322,8 @@ void *mlx4_table_find(struct mlx4_icm_table *table, u32 obj,
 	u64 idx;
 	struct mlx4_icm_chunk *chunk;
 	struct mlx4_icm *icm;
-	struct page *page = NULL;
+	struct page *page;
+	void *addr = NULL;
 
 	if (!table->lowmem)
 		return NULL;
@@ -348,7 +351,12 @@ void *mlx4_table_find(struct mlx4_icm_table *table, u32 obj,
 			 * been assigned to.
 			 */
 			if (chunk->mem[i].length > offset) {
-				page = sg_page(&chunk->mem[i]);
+				if (table->coherent) {
+					addr = chunk->buf[i];
+				} else {
+					page = sg_page(&chunk->mem[i]);
+					addr = lowmem_page_address(page);
+				}
 				goto out;
 			}
 			offset -= chunk->mem[i].length;
@@ -357,7 +365,7 @@ void *mlx4_table_find(struct mlx4_icm_table *table, u32 obj,
 
 out:
 	mutex_unlock(&table->mutex);
-	return page ? lowmem_page_address(page) + offset : NULL;
+	return addr ? addr + offset : NULL;
 }
 
 int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.h b/drivers/net/ethernet/mellanox/mlx4/icm.h
index c9169a490557..a565188dc391 100644
--- a/drivers/net/ethernet/mellanox/mlx4/icm.h
+++ b/drivers/net/ethernet/mellanox/mlx4/icm.h
@@ -52,6 +52,7 @@ struct mlx4_icm_chunk {
 	int			npages;
 	int			nsg;
 	struct scatterlist	mem[MLX4_ICM_CHUNK_LEN];
+	void			*buf[MLX4_ICM_CHUNK_LEN];
 };
 
 struct mlx4_icm {
-- 
2.19.2

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH V2] net/mlx4: Get rid of page operation after dma_alloc_coherent
  2018-12-18 19:06 [PATCH V2] net/mlx4: Get rid of page operation after dma_alloc_coherent Stephen Warren
@ 2018-12-18 20:56 ` Christoph Hellwig
  2018-12-19  0:12   ` Stephen Warren
  0 siblings, 1 reply; 5+ messages in thread
From: Christoph Hellwig @ 2018-12-18 20:56 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Tariq Toukan, xavier.huwei, netdev, linux-rdma, Doug Ledford,
	Jason Gunthorpe, Christoph Hellwig, Stephen Warren

This goes in the right direction, but I think we need to stop
abusing the scatterlist for the coherent mapping entirely.  Something
like the patch below (based on yours):

diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.c b/drivers/net/ethernet/mellanox/mlx4/icm.c
index 4b4351141b94..717ee2fad707 100644
--- a/drivers/net/ethernet/mellanox/mlx4/icm.c
+++ b/drivers/net/ethernet/mellanox/mlx4/icm.c
@@ -57,12 +57,12 @@ static void mlx4_free_icm_pages(struct mlx4_dev *dev, struct mlx4_icm_chunk *chu
 	int i;
 
 	if (chunk->nsg > 0)
-		pci_unmap_sg(dev->persist->pdev, chunk->mem, chunk->npages,
+		pci_unmap_sg(dev->persist->pdev, chunk->sg, chunk->npages,
 			     PCI_DMA_BIDIRECTIONAL);
 
 	for (i = 0; i < chunk->npages; ++i)
-		__free_pages(sg_page(&chunk->mem[i]),
-			     get_order(chunk->mem[i].length));
+		__free_pages(sg_page(&chunk->sg[i]),
+			     get_order(chunk->sg[i].length));
 }
 
 static void mlx4_free_icm_coherent(struct mlx4_dev *dev, struct mlx4_icm_chunk *chunk)
@@ -71,9 +71,9 @@ static void mlx4_free_icm_coherent(struct mlx4_dev *dev, struct mlx4_icm_chunk *
 
 	for (i = 0; i < chunk->npages; ++i)
 		dma_free_coherent(&dev->persist->pdev->dev,
-				  chunk->mem[i].length,
-				  lowmem_page_address(sg_page(&chunk->mem[i])),
-				  sg_dma_address(&chunk->mem[i]));
+				  chunk->buf[i].size,
+				  chunk->buf[i].addr,
+				  chunk->buf[i].dma_addr);
 }
 
 void mlx4_free_icm(struct mlx4_dev *dev, struct mlx4_icm *icm, int coherent)
@@ -111,22 +111,21 @@ static int mlx4_alloc_icm_pages(struct scatterlist *mem, int order,
 	return 0;
 }
 
-static int mlx4_alloc_icm_coherent(struct device *dev, struct scatterlist *mem,
-				    int order, gfp_t gfp_mask)
+static int mlx4_alloc_icm_coherent(struct device *dev, struct mlx4_icm_buf *buf,
+				   int order, gfp_t gfp_mask)
 {
-	void *buf = dma_alloc_coherent(dev, PAGE_SIZE << order,
-				       &sg_dma_address(mem), gfp_mask);
-	if (!buf)
+	buf->addr = dma_alloc_coherent(dev, PAGE_SIZE << order,
+				  &buf->dma_addr, gfp_mask);
+	if (!buf->addr)
 		return -ENOMEM;
 
-	if (offset_in_page(buf)) {
-		dma_free_coherent(dev, PAGE_SIZE << order,
-				  buf, sg_dma_address(mem));
+	if (offset_in_page(buf->addr)) {
+		dma_free_coherent(dev, PAGE_SIZE << order, buf->addr,
+				  buf->dma_addr);
 		return -ENOMEM;
 	}
 
-	sg_set_buf(mem, buf, PAGE_SIZE << order);
-	sg_dma_len(mem) = PAGE_SIZE << order;
+	buf->size = PAGE_SIZE << order;
 	return 0;
 }
 
@@ -159,21 +158,20 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
 
 	while (npages > 0) {
 		if (!chunk) {
-			chunk = kmalloc_node(sizeof(*chunk),
+			chunk = kzalloc_node(sizeof(*chunk),
 					     gfp_mask & ~(__GFP_HIGHMEM |
 							  __GFP_NOWARN),
 					     dev->numa_node);
 			if (!chunk) {
-				chunk = kmalloc(sizeof(*chunk),
+				chunk = kzalloc(sizeof(*chunk),
 						gfp_mask & ~(__GFP_HIGHMEM |
 							     __GFP_NOWARN));
 				if (!chunk)
 					goto fail;
 			}
 
-			sg_init_table(chunk->mem, MLX4_ICM_CHUNK_LEN);
-			chunk->npages = 0;
-			chunk->nsg    = 0;
+			if (!coherent)
+				sg_init_table(chunk->sg, MLX4_ICM_CHUNK_LEN);
 			list_add_tail(&chunk->list, &icm->chunk_list);
 		}
 
@@ -186,10 +184,10 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
 
 		if (coherent)
 			ret = mlx4_alloc_icm_coherent(&dev->persist->pdev->dev,
-						      &chunk->mem[chunk->npages],
+						      &chunk->buf[chunk->npages],
 						      cur_order, mask);
 		else
-			ret = mlx4_alloc_icm_pages(&chunk->mem[chunk->npages],
+			ret = mlx4_alloc_icm_pages(&chunk->sg[chunk->npages],
 						   cur_order, mask,
 						   dev->numa_node);
 
@@ -205,7 +203,7 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
 		if (coherent)
 			++chunk->nsg;
 		else if (chunk->npages == MLX4_ICM_CHUNK_LEN) {
-			chunk->nsg = pci_map_sg(dev->persist->pdev, chunk->mem,
+			chunk->nsg = pci_map_sg(dev->persist->pdev, chunk->sg,
 						chunk->npages,
 						PCI_DMA_BIDIRECTIONAL);
 
@@ -220,7 +218,7 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
 	}
 
 	if (!coherent && chunk) {
-		chunk->nsg = pci_map_sg(dev->persist->pdev, chunk->mem,
+		chunk->nsg = pci_map_sg(dev->persist->pdev, chunk->sg,
 					chunk->npages,
 					PCI_DMA_BIDIRECTIONAL);
 
@@ -320,7 +318,7 @@ void *mlx4_table_find(struct mlx4_icm_table *table, u32 obj,
 	u64 idx;
 	struct mlx4_icm_chunk *chunk;
 	struct mlx4_icm *icm;
-	struct page *page = NULL;
+	void *addr = NULL;
 
 	if (!table->lowmem)
 		return NULL;
@@ -336,28 +334,48 @@ void *mlx4_table_find(struct mlx4_icm_table *table, u32 obj,
 
 	list_for_each_entry(chunk, &icm->chunk_list, list) {
 		for (i = 0; i < chunk->npages; ++i) {
+			dma_addr_t dma_addr;
+			size_t len;
+
+			if (table->coherent) {
+				len = chunk->buf[i].size;
+				dma_addr = chunk->buf[i].dma_addr;
+				addr = chunk->buf[i].addr;
+			} else {
+				len = sg_dma_len(&chunk->sg[i]);
+				dma_addr = sg_dma_address(&chunk->sg[i]);
+
+				/*
+				 * XXX: we should never do this for highmem
+				 * allocation.  This function either needs
+				 * to be split, or the kernel virtual address
+				 * return needs to be made optional.
+				 */
+				addr = lowmem_page_address(
+						sg_page(&chunk->sg[i]));
+			}
+
 			if (dma_handle && dma_offset >= 0) {
-				if (sg_dma_len(&chunk->mem[i]) > dma_offset)
-					*dma_handle = sg_dma_address(&chunk->mem[i]) +
-						dma_offset;
-				dma_offset -= sg_dma_len(&chunk->mem[i]);
+				if (len > dma_offset)
+					*dma_handle = dma_addr + dma_offset;
+				dma_offset -= len;
 			}
+
 			/*
 			 * DMA mapping can merge pages but not split them,
 			 * so if we found the page, dma_handle has already
 			 * been assigned to.
 			 */
-			if (chunk->mem[i].length > offset) {
-				page = sg_page(&chunk->mem[i]);
+			if (len > offset)
 				goto out;
-			}
-			offset -= chunk->mem[i].length;
+			offset -= len;
 		}
 	}
 
+	addr = NULL;
 out:
 	mutex_unlock(&table->mutex);
-	return page ? lowmem_page_address(page) + offset : NULL;
+	return addr ? addr + offset : NULL;
 }
 
 int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.h b/drivers/net/ethernet/mellanox/mlx4/icm.h
index c9169a490557..5ccf08ac47a3 100644
--- a/drivers/net/ethernet/mellanox/mlx4/icm.h
+++ b/drivers/net/ethernet/mellanox/mlx4/icm.h
@@ -47,11 +47,20 @@ enum {
 	MLX4_ICM_PAGE_SIZE	= 1 << MLX4_ICM_PAGE_SHIFT,
 };
 
+struct mlx4_icm_buf {
+	void			*addr;
+	size_t			size;
+	dma_addr_t		dma_addr;
+};
+
 struct mlx4_icm_chunk {
 	struct list_head	list;
 	int			npages;
 	int			nsg;
-	struct scatterlist	mem[MLX4_ICM_CHUNK_LEN];
+	union {
+		struct scatterlist	sg[MLX4_ICM_CHUNK_LEN];
+		struct mlx4_icm_buf	buf[MLX4_ICM_CHUNK_LEN];
+	};
 };
 
 struct mlx4_icm {
@@ -112,14 +121,16 @@ static inline void mlx4_icm_next(struct mlx4_icm_iter *iter)
 	}
 }
 
+/* Note: won't work on coherent tables */
 static inline dma_addr_t mlx4_icm_addr(struct mlx4_icm_iter *iter)
 {
-	return sg_dma_address(&iter->chunk->mem[iter->page_idx]);
+	return sg_dma_address(&iter->chunk->sg[iter->page_idx]);
 }
 
+/* Note: won't work on coherent tables */
 static inline unsigned long mlx4_icm_size(struct mlx4_icm_iter *iter)
 {
-	return sg_dma_len(&iter->chunk->mem[iter->page_idx]);
+	return sg_dma_len(&iter->chunk->sg[iter->page_idx]);
 }
 
 int mlx4_MAP_ICM_AUX(struct mlx4_dev *dev, struct mlx4_icm *icm);

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH V2] net/mlx4: Get rid of page operation after dma_alloc_coherent
  2018-12-18 20:56 ` Christoph Hellwig
@ 2018-12-19  0:12   ` Stephen Warren
  2018-12-19  7:25     ` Christoph Hellwig
  0 siblings, 1 reply; 5+ messages in thread
From: Stephen Warren @ 2018-12-19  0:12 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Tariq Toukan, xavier.huwei, netdev, linux-rdma, Doug Ledford,
	Jason Gunthorpe, Stephen Warren

On 12/18/18 1:56 PM, Christoph Hellwig wrote:
> This goes in the right direction, but I think we need to stop
> abusing the scatterlist for the coherent mapping entirely.  Something
> like the patch below (based on yours):

Oh, it was simple to get rid of the sg list usage than I thought; I'd 
assume it would be touched in a bunch of other files.

I had to make the additions shown below to get the adapter to get the 
driver to probe without errors, but with these changes, ibping, 
ib_read_bw, and ib_write_bw all work both directions:

(Sorry, this is pasted so the formatting may be broken)

> diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.c b/drivers/net/ethernet/mellanox/mlx4/icm.c
> index ee4fde7e465d..d305c9f575e3 100644
> --- a/drivers/net/ethernet/mellanox/mlx4/icm.c
> +++ b/drivers/net/ethernet/mellanox/mlx4/icm.c
> @@ -167,6 +167,7 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
>  				if (!chunk)
>  					goto fail;
>  			}
> +			chunk->coherent = coherent;
>  
>  			if (!coherent)
>  				sg_init_table(chunk->sg, MLX4_ICM_CHUNK_LEN);
> diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.h b/drivers/net/ethernet/mellanox/mlx4/icm.h
> index 5ccf08ac47a3..574f4bcdd090 100644
> --- a/drivers/net/ethernet/mellanox/mlx4/icm.h
> +++ b/drivers/net/ethernet/mellanox/mlx4/icm.h
> @@ -57,6 +57,7 @@ struct mlx4_icm_chunk {
>  	struct list_head	list;
>  	int			npages;
>  	int			nsg;
> +	int			coherent;
>  	union {
>  		struct scatterlist	sg[MLX4_ICM_CHUNK_LEN];
>  		struct mlx4_icm_buf	buf[MLX4_ICM_CHUNK_LEN];
> @@ -121,16 +122,20 @@ static inline void mlx4_icm_next(struct mlx4_icm_iter *iter)
>  	}
>  }
>  
> -/* Note: won't work on coherent tables */
>  static inline dma_addr_t mlx4_icm_addr(struct mlx4_icm_iter *iter)
>  {
> -	return sg_dma_address(&iter->chunk->sg[iter->page_idx]);
> +	if (iter->chunk->coherent)
> +		return iter->chunk->buf[iter->page_idx].dma_addr;
> +	else
> +		return sg_dma_address(&iter->chunk->sg[iter->page_idx]);
>  }
>  
> -/* Note: won't work on coherent tables */
>  static inline unsigned long mlx4_icm_size(struct mlx4_icm_iter *iter)
>  {
> -	return sg_dma_len(&iter->chunk->sg[iter->page_idx]);
> +	if (iter->chunk->coherent)
> +		return iter->chunk->buf[iter->page_idx].size;
> +	else
> +		return sg_dma_len(&iter->chunk->sg[iter->page_idx]);
>  }
>  
>  int mlx4_MAP_ICM_AUX(struct mlx4_dev *dev, struct mlx4_icm *icm);

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH V2] net/mlx4: Get rid of page operation after dma_alloc_coherent
  2018-12-19  0:12   ` Stephen Warren
@ 2018-12-19  7:25     ` Christoph Hellwig
  2018-12-19 17:31       ` Stephen Warren
  0 siblings, 1 reply; 5+ messages in thread
From: Christoph Hellwig @ 2018-12-19  7:25 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Christoph Hellwig, Tariq Toukan, xavier.huwei, netdev,
	linux-rdma, Doug Ledford, Jason Gunthorpe, Stephen Warren

On Tue, Dec 18, 2018 at 05:12:41PM -0700, Stephen Warren wrote:
> On 12/18/18 1:56 PM, Christoph Hellwig wrote:
>> This goes in the right direction, but I think we need to stop
>> abusing the scatterlist for the coherent mapping entirely.  Something
>> like the patch below (based on yours):
>
> Oh, it was simple to get rid of the sg list usage than I thought; I'd 
> assume it would be touched in a bunch of other files.
>
> I had to make the additions shown below to get the adapter to get the 
> driver to probe without errors, but with these changes, ibping, ib_read_bw, 
> and ib_write_bw all work both directions:

I think the new coherent flag should probably use a bool instead of int,
even despite the fact that the old one still uses bool.

It might also be worth checking if we need the per-chunk and per-table
coherent flags, or if the per-chunk one is enough.

Otherwise this looks fine, feel free to resend it under your name as
you did the original patch and all the analysis and testing.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH V2] net/mlx4: Get rid of page operation after dma_alloc_coherent
  2018-12-19  7:25     ` Christoph Hellwig
@ 2018-12-19 17:31       ` Stephen Warren
  0 siblings, 0 replies; 5+ messages in thread
From: Stephen Warren @ 2018-12-19 17:31 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Tariq Toukan, xavier.huwei, netdev, linux-rdma, Doug Ledford,
	Jason Gunthorpe, Stephen Warren

On 12/19/18 12:25 AM, Christoph Hellwig wrote:
> On Tue, Dec 18, 2018 at 05:12:41PM -0700, Stephen Warren wrote:
>> On 12/18/18 1:56 PM, Christoph Hellwig wrote:
>>> This goes in the right direction, but I think we need to stop
>>> abusing the scatterlist for the coherent mapping entirely.  Something
>>> like the patch below (based on yours):
>>
>> Oh, it was simple to get rid of the sg list usage than I thought; I'd
>> assume it would be touched in a bunch of other files.
>>
>> I had to make the additions shown below to get the adapter to get the
>> driver to probe without errors, but with these changes, ibping, ib_read_bw,
>> and ib_write_bw all work both directions:
> 
> I think the new coherent flag should probably use a bool instead of int,
> even despite the fact that the old one still uses bool.
> 
> It might also be worth checking if we need the per-chunk and per-table
> coherent flags, or if the per-chunk one is enough.

So we need to store the value in the table, because the table is created 
first without any chunks, so we can't store the coherent flag in any 
chunk, and the coherent flag is a property of the table at that time.

We also need to store it per chunk because part of the code acts on 
chunks without knowledge of which table they're part of, so can't access 
the per-table coherent flag.

Instead of duplicating the coherent flag into each chunk, I could 
instead add a pointer from the chunk to the table, so the code could 
read chunk->table->coherent. That would avoid duplication at least, even 
if it does add more pointer chasing. I'm not sure if one way is better 
than the other?

> Otherwise this looks fine, feel free to resend it under your name as
> you did the original patch and all the analysis and testing.

Thanks.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2018-12-19 17:31 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-18 19:06 [PATCH V2] net/mlx4: Get rid of page operation after dma_alloc_coherent Stephen Warren
2018-12-18 20:56 ` Christoph Hellwig
2018-12-19  0:12   ` Stephen Warren
2018-12-19  7:25     ` Christoph Hellwig
2018-12-19 17:31       ` Stephen Warren

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.