Skip to contentSkip to conversation

mlx4: Fix chunk sg list overflow in mlx4_alloc_icm()

PATCH In review sebastien dugue 3 participants 5 messages Apr 30, 2010 – May 6, 2010 1 message not in the archive

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 mlx4: Fix chunk sg list overflow in mlx4_alloc_icm()

If the number of sg entries in the ICM chunk reaches MLX4_ICM_CHUNK_LEN,
we must set chunk = NULL __even__ for coherent mappings (as is done for mthca). Otherwise we may overflow the sg list.

---
 drivers/net/mlx4/icm.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
drivers/net/mlx4/icm.c +2 -1
index 57288ca..ef62f17 100644
@@ -175,9 +175,10 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
 
 				if (chunk->nsg <= 0)
 					goto fail;
+			}
 
+			if (chunk->npages == MLX4_ICM_CHUNK_LEN)
 				chunk = NULL;
-			}
 
 			npages -= 1 << cur_order;
 		} else {
Signature · 6 lines
1.6.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#1 lore raw

Looks like a valid fix to me.

Quoted 33 lines · sebastien dugue

If the number of sg entries in the ICM chunk reaches MLX4_ICM_CHUNK_LEN,
we must set chunk = NULL __even__ for coherent mappings (as is done for mthca). Otherwise we may overflow the sg list.

---
 drivers/net/mlx4/icm.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
drivers/net/mlx4/icm.c +2 -1
index 57288ca..ef62f17 100644
@@ -175,9 +175,10 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
 
 				if (chunk->nsg <= 0)
 					goto fail;
+			}
 
+			if (chunk->npages == MLX4_ICM_CHUNK_LEN)
 				chunk = NULL;
-			}
 
 			npages -= 1 << cur_order;
 		} else {
Signature · 6 lines
1.6.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#2 lore raw
In reply to sebastien dugue

good catch, applied. Did this hit you in practice? I guess it would take a big coherent ICM allocation, were you getting those?

Also what do you think of this independent cleanup on top of your patch? It handles the error case for allocation and then avoids having the common case inside a deeper nested block:

 drivers/net/mlx4/icm.c |   37 +++++++++++++++++++------------------
 1 files changed, 19 insertions(+), 18 deletions(-)
drivers/net/mlx4/icm.c +20 -19
index ef62f17..b07e4de 100644
@@ -163,29 +163,30 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
 			ret = mlx4_alloc_icm_pages(&chunk->mem[chunk->npages],
 						   cur_order, gfp_mask);
 
-		if (!ret) {
-			++chunk->npages;
-
-			if (coherent)
-				++chunk->nsg;
-			else if (chunk->npages == MLX4_ICM_CHUNK_LEN) {
-				chunk->nsg = pci_map_sg(dev->pdev, chunk->mem,
-							chunk->npages,
-							PCI_DMA_BIDIRECTIONAL);
-
-				if (chunk->nsg <= 0)
-					goto fail;
-			}
+		if (ret) {
+			if (--cur_order < 0)
+				goto fail;
+			else
+				continue;
+		}
 
-			if (chunk->npages == MLX4_ICM_CHUNK_LEN)
-				chunk = NULL;
+		++chunk->npages;
 
-			npages -= 1 << cur_order;
-		} else {
-			--cur_order;
-			if (cur_order < 0)
+		if (coherent)
+			++chunk->nsg;
+		else if (chunk->npages == MLX4_ICM_CHUNK_LEN) {
+			chunk->nsg = pci_map_sg(dev->pdev, chunk->mem,
+						chunk->npages,
+						PCI_DMA_BIDIRECTIONAL);
+
+			if (chunk->nsg <= 0)
 				goto fail;
 		}
+
+		if (chunk->npages == MLX4_ICM_CHUNK_LEN)
+			chunk = NULL;
+
+		npages -= 1 << cur_order;
 	}
 
 	if (!coherent && chunk) {
Signature · 6 lines
Roland Dreier <[email protected]> || For corporate legal information go to:
http://www.cisco.com/web/about/doing_business/legal/cri/index.html
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): adatyqmmej0.fsf-BjVyx320WGW9gfZ95n9DRSW4+XlvGpQz@public.gmane.org

#4 lore raw

Hi Roland,

Quoted 2 lines · On Wed, 05 May 2010 10:42:11 -0700 Roland Dreier…

good catch, applied. Did this hit you in practice? I guess it would take a big coherent ICM allocation, were you getting those?

Yes, some customer got hit by this, which ended up corrupting memory.

Quoted 4 lines

Also what do you think of this independent cleanup on top of your patch? It handles the error case for allocation and then avoids having the common case inside a deeper nested block:

No problem, it indeed makes the code more readable.

Thanks,

Sebastien.

Quoted 49 lines
 drivers/net/mlx4/icm.c |   37 +++++++++++++++++++------------------
 1 files changed, 19 insertions(+), 18 deletions(-)
drivers/net/mlx4/icm.c +15 -19
index ef62f17..b07e4de 100644
@@ -163,29 +163,30 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
 			ret = mlx4_alloc_icm_pages(&chunk->mem[chunk->npages],
 						   cur_order, gfp_mask);
 
-		if (!ret) {
-			++chunk->npages;
-
-			if (coherent)
-				++chunk->nsg;
-			else if (chunk->npages == MLX4_ICM_CHUNK_LEN) {
-				chunk->nsg = pci_map_sg(dev->pdev, chunk->mem,
-							chunk->npages,
-							PCI_DMA_BIDIRECTIONAL);
-
-				if (chunk->nsg <= 0)
-					goto fail;
-			}
+		if (ret) {
+			if (--cur_order < 0)
+				goto fail;
+			else
+				continue;
+		}
 
-			if (chunk->npages == MLX4_ICM_CHUNK_LEN)
-				chunk = NULL;
+		++chunk->npages;
 
-			npages -= 1 << cur_order;
-		} else {
-			--cur_order;
-			if (cur_order < 0)
+		if (coherent)
+			++chunk->nsg;
+		else if (chunk->npages == MLX4_ICM_CHUNK_LEN) {
+			chunk->nsg = pci_map_sg(dev->pdev, chunk->mem,
+						chunk->npages,
+						PCI_DMA_BIDIRECTIONAL);
+
+			if (chunk->nsg <= 0)

drivers/net/mlx4/icm.c struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages, · line 192

Quoted 10 lines
drivers/net/mlx4/icm.c +5 -0
 				goto fail;
 		}
+
+		if (chunk->npages == MLX4_ICM_CHUNK_LEN)
+			chunk = NULL;
+
+		npages -= 1 << cur_order;
 	}
 
 	if (!coherent && chunk) {

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#5 lore raw
Quoted 1 line

Yes, some customer got hit by this, which ended up corrupting memory.

I'll tag it for stable kernels too then. Thanks.

Signature · 6 lines
Roland Dreier <[email protected]> || For corporate legal information go to:
http://www.cisco.com/web/about/doing_business/legal/cri/index.html
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html