mlx4: Fix chunk sg list overflow in mlx4_alloc_icm()
Subsystems (2)
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
@@ -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
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@@ -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
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
@@ -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
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@@ -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
-0goto 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
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