Skip to content

Commit 0ef2f05

Browse files
Wengang-oracledledford
authored andcommitted
IB/mlx4: Use vmalloc for WR buffers when needed
There are several hits that WR buffer allocation(kmalloc) failed. It failed at order 3 and/or 4 contigous pages allocation. At the same time there are actually 100MB+ free memory but well fragmented. So try vmalloc when kmalloc failed. Signed-off-by: Wengang Wang <[email protected]> Acked-by: Or Gerlitz <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent 73d4da7 commit 0ef2f05

File tree

2 files changed

+21
-9
lines changed

2 files changed

+21
-9
lines changed

drivers/infiniband/hw/mlx4/qp.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <linux/log2.h>
3535
#include <linux/slab.h>
3636
#include <linux/netdevice.h>
37+
#include <linux/vmalloc.h>
3738

3839
#include <rdma/ib_cache.h>
3940
#include <rdma/ib_pack.h>
@@ -795,8 +796,14 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
795796
if (err)
796797
goto err_mtt;
797798

798-
qp->sq.wrid = kmalloc(qp->sq.wqe_cnt * sizeof (u64), gfp);
799-
qp->rq.wrid = kmalloc(qp->rq.wqe_cnt * sizeof (u64), gfp);
799+
qp->sq.wrid = kmalloc(qp->sq.wqe_cnt * sizeof(u64), gfp);
800+
if (!qp->sq.wrid)
801+
qp->sq.wrid = __vmalloc(qp->sq.wqe_cnt * sizeof(u64),
802+
gfp, PAGE_KERNEL);
803+
qp->rq.wrid = kmalloc(qp->rq.wqe_cnt * sizeof(u64), gfp);
804+
if (!qp->rq.wrid)
805+
qp->rq.wrid = __vmalloc(qp->rq.wqe_cnt * sizeof(u64),
806+
gfp, PAGE_KERNEL);
800807
if (!qp->sq.wrid || !qp->rq.wrid) {
801808
err = -ENOMEM;
802809
goto err_wrid;
@@ -886,8 +893,8 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
886893
if (qp_has_rq(init_attr))
887894
mlx4_ib_db_unmap_user(to_mucontext(pd->uobject->context), &qp->db);
888895
} else {
889-
kfree(qp->sq.wrid);
890-
kfree(qp->rq.wrid);
896+
kvfree(qp->sq.wrid);
897+
kvfree(qp->rq.wrid);
891898
}
892899

893900
err_mtt:
@@ -1062,8 +1069,8 @@ static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp,
10621069
&qp->db);
10631070
ib_umem_release(qp->umem);
10641071
} else {
1065-
kfree(qp->sq.wrid);
1066-
kfree(qp->rq.wrid);
1072+
kvfree(qp->sq.wrid);
1073+
kvfree(qp->rq.wrid);
10671074
if (qp->mlx4_ib_qp_type & (MLX4_IB_QPT_PROXY_SMI_OWNER |
10681075
MLX4_IB_QPT_PROXY_SMI | MLX4_IB_QPT_PROXY_GSI))
10691076
free_proxy_bufs(&dev->ib_dev, qp);

drivers/infiniband/hw/mlx4/srq.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <linux/mlx4/qp.h>
3535
#include <linux/mlx4/srq.h>
3636
#include <linux/slab.h>
37+
#include <linux/vmalloc.h>
3738

3839
#include "mlx4_ib.h"
3940
#include "user.h"
@@ -172,8 +173,12 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd,
172173

173174
srq->wrid = kmalloc(srq->msrq.max * sizeof (u64), GFP_KERNEL);
174175
if (!srq->wrid) {
175-
err = -ENOMEM;
176-
goto err_mtt;
176+
srq->wrid = __vmalloc(srq->msrq.max * sizeof(u64),
177+
GFP_KERNEL, PAGE_KERNEL);
178+
if (!srq->wrid) {
179+
err = -ENOMEM;
180+
goto err_mtt;
181+
}
177182
}
178183
}
179184

@@ -204,7 +209,7 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd,
204209
if (pd->uobject)
205210
mlx4_ib_db_unmap_user(to_mucontext(pd->uobject->context), &srq->db);
206211
else
207-
kfree(srq->wrid);
212+
kvfree(srq->wrid);
208213

209214
err_mtt:
210215
mlx4_mtt_cleanup(dev->dev, &srq->mtt);

0 commit comments

Comments
 (0)