Takashi Iwai fe31f1
From fbc0d19393cbf49c28f538b7fdd94f92655f7870 Mon Sep 17 00:00:00 2001
Takashi Iwai fe31f1
From: Niklas Schnelle <schnelle@linux.ibm.com>
Takashi Iwai fe31f1
Date: Wed, 8 Sep 2021 10:18:48 +0200
Takashi Iwai fe31f1
Subject: [PATCH] RDMA/mlx5: Fix number of allocated XLT entries
Takashi Iwai fe31f1
Git-commit: 9660dcbe0d9186976917c94bce4e69dbd8d7a974
Takashi Iwai fe31f1
Patch-mainline: v5.15-rc1
Takashi Iwai fe31f1
References: stable-5.14.4
Takashi Iwai fe31f1
Takashi Iwai fe31f1
commit 9660dcbe0d9186976917c94bce4e69dbd8d7a974 upstream.
Takashi Iwai fe31f1
Takashi Iwai fe31f1
In commit 8010d74b9965b ("RDMA/mlx5: Split the WR setup out of
Takashi Iwai fe31f1
mlx5_ib_update_xlt()") the allocation logic was split out of
Takashi Iwai fe31f1
mlx5_ib_update_xlt() and the logic was changed to enable better OOM
Takashi Iwai fe31f1
handling. Sadly this change introduced a miscalculation of the number of
Takashi Iwai fe31f1
entries that were actually allocated when under memory pressure where it
Takashi Iwai fe31f1
can actually become 0 which on s390 lets dma_map_single() fail.
Takashi Iwai fe31f1
Takashi Iwai fe31f1
It can also lead to corruption of the free pages list when the wrong
Takashi Iwai fe31f1
number of entries is used in the calculation of sg->length which is used
Takashi Iwai fe31f1
as argument for free_pages().
Takashi Iwai fe31f1
Takashi Iwai fe31f1
Fix this by using the allocation size instead of misusing get_order(size).
Takashi Iwai fe31f1
Takashi Iwai fe31f1
Cc: stable@vger.kernel.org
Takashi Iwai fe31f1
Fixes: 8010d74b9965 ("RDMA/mlx5: Split the WR setup out of mlx5_ib_update_xlt()")
Takashi Iwai fe31f1
Link: https://lore.kernel.org/r/20210908081849.7948-1-schnelle@linux.ibm.com
Takashi Iwai fe31f1
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Takashi Iwai fe31f1
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Takashi Iwai fe31f1
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Takashi Iwai fe31f1
Acked-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai fe31f1
Takashi Iwai fe31f1
---
Takashi Iwai fe31f1
 drivers/infiniband/hw/mlx5/mr.c | 2 +-
Takashi Iwai fe31f1
 1 file changed, 1 insertion(+), 1 deletion(-)
Takashi Iwai fe31f1
Takashi Iwai fe31f1
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
Takashi Iwai fe31f1
index 3f1c5a4f158b..19713cdd7b78 100644
Takashi Iwai fe31f1
--- a/drivers/infiniband/hw/mlx5/mr.c
Takashi Iwai fe31f1
+++ b/drivers/infiniband/hw/mlx5/mr.c
Takashi Iwai fe31f1
@@ -1024,7 +1024,7 @@ static void *mlx5_ib_alloc_xlt(size_t *nents, size_t ent_size, gfp_t gfp_mask)
Takashi Iwai fe31f1
 
Takashi Iwai fe31f1
 	if (size > MLX5_SPARE_UMR_CHUNK) {
Takashi Iwai fe31f1
 		size = MLX5_SPARE_UMR_CHUNK;
Takashi Iwai fe31f1
-		*nents = get_order(size) / ent_size;
Takashi Iwai fe31f1
+		*nents = size / ent_size;
Takashi Iwai fe31f1
 		res = (void *)__get_free_pages(gfp_mask | __GFP_NOWARN,
Takashi Iwai fe31f1
 					       get_order(size));
Takashi Iwai fe31f1
 		if (res)
Takashi Iwai fe31f1
-- 
Takashi Iwai fe31f1
2.26.2
Takashi Iwai fe31f1