Skip to content

Commit 89dd86d

Browse files
yishaihrolandd
authored andcommitted
mlx4_core: Allow large mlx4_buddy bitmaps
mlx4_buddy_init uses kmalloc() to allocate bitmaps, which fails when the required size is beyond the max supported value (or when memory is too fragmented to handle a huge allocation). Extend this to use use vmalloc() if kmalloc() fails, and take that into account when freeing the bitmaps as well. This fixes a driver load failure when log num mtt is 26 or higher, and is a step in the direction of allowing to register huge amounts of memory on large memory systems. Signed-off-by: Yishai Hadas <[email protected]> Signed-off-by: Or Gerlitz <[email protected]> Signed-off-by: Roland Dreier <[email protected]>
1 parent df7fba6 commit 89dd86d

File tree

1 file changed

+14
-4
lines changed
  • drivers/net/ethernet/mellanox/mlx4

1 file changed

+14
-4
lines changed

drivers/net/ethernet/mellanox/mlx4/mr.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <linux/export.h>
3838
#include <linux/slab.h>
3939
#include <linux/kernel.h>
40+
#include <linux/vmalloc.h>
4041

4142
#include <linux/mlx4/cmd.h>
4243

@@ -130,8 +131,11 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order)
130131
for (i = 0; i <= buddy->max_order; ++i) {
131132
s = BITS_TO_LONGS(1 << (buddy->max_order - i));
132133
buddy->bits[i] = kmalloc(s * sizeof (long), GFP_KERNEL);
133-
if (!buddy->bits[i])
134-
goto err_out_free;
134+
if (!buddy->bits[i]) {
135+
buddy->bits[i] = vmalloc(s * sizeof(long));
136+
if (!buddy->bits[i])
137+
goto err_out_free;
138+
}
135139
bitmap_zero(buddy->bits[i], 1 << (buddy->max_order - i));
136140
}
137141

@@ -142,7 +146,10 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order)
142146

143147
err_out_free:
144148
for (i = 0; i <= buddy->max_order; ++i)
145-
kfree(buddy->bits[i]);
149+
if (buddy->bits[i] && is_vmalloc_addr(buddy->bits[i]))
150+
vfree(buddy->bits[i]);
151+
else
152+
kfree(buddy->bits[i]);
146153

147154
err_out:
148155
kfree(buddy->bits);
@@ -156,7 +163,10 @@ static void mlx4_buddy_cleanup(struct mlx4_buddy *buddy)
156163
int i;
157164

158165
for (i = 0; i <= buddy->max_order; ++i)
159-
kfree(buddy->bits[i]);
166+
if (is_vmalloc_addr(buddy->bits[i]))
167+
vfree(buddy->bits[i]);
168+
else
169+
kfree(buddy->bits[i]);
160170

161171
kfree(buddy->bits);
162172
kfree(buddy->num_free);

0 commit comments

Comments
 (0)