diff options
author | Wengang Wang <wen.gang.wang@oracle.com> | 2015-10-08 01:27:04 -0400 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2015-12-08 16:48:10 -0500 |
commit | 0ef2f05c7e02ff99c0b5b583d7dee2cd12b053f2 (patch) | |
tree | c5305adcf047948e7eb5d368b951c47940a1869c | |
parent | 73d4da7b9fec13cbddcf548888c4d0e46f1d5087 (diff) |
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 <wen.gang.wang@oracle.com>
Acked-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r-- | drivers/infiniband/hw/mlx4/qp.c | 19 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/srq.c | 11 |
2 files changed, 21 insertions, 9 deletions
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index a2e4ca56da44..13eaaf45288f 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/log2.h> | 34 | #include <linux/log2.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/netdevice.h> | 36 | #include <linux/netdevice.h> |
37 | #include <linux/vmalloc.h> | ||
37 | 38 | ||
38 | #include <rdma/ib_cache.h> | 39 | #include <rdma/ib_cache.h> |
39 | #include <rdma/ib_pack.h> | 40 | #include <rdma/ib_pack.h> |
@@ -795,8 +796,14 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, | |||
795 | if (err) | 796 | if (err) |
796 | goto err_mtt; | 797 | goto err_mtt; |
797 | 798 | ||
798 | qp->sq.wrid = kmalloc(qp->sq.wqe_cnt * sizeof (u64), gfp); | 799 | qp->sq.wrid = kmalloc(qp->sq.wqe_cnt * sizeof(u64), gfp); |
799 | qp->rq.wrid = kmalloc(qp->rq.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); | ||
800 | if (!qp->sq.wrid || !qp->rq.wrid) { | 807 | if (!qp->sq.wrid || !qp->rq.wrid) { |
801 | err = -ENOMEM; | 808 | err = -ENOMEM; |
802 | goto err_wrid; | 809 | goto err_wrid; |
@@ -886,8 +893,8 @@ err_wrid: | |||
886 | if (qp_has_rq(init_attr)) | 893 | if (qp_has_rq(init_attr)) |
887 | mlx4_ib_db_unmap_user(to_mucontext(pd->uobject->context), &qp->db); | 894 | mlx4_ib_db_unmap_user(to_mucontext(pd->uobject->context), &qp->db); |
888 | } else { | 895 | } else { |
889 | kfree(qp->sq.wrid); | 896 | kvfree(qp->sq.wrid); |
890 | kfree(qp->rq.wrid); | 897 | kvfree(qp->rq.wrid); |
891 | } | 898 | } |
892 | 899 | ||
893 | err_mtt: | 900 | err_mtt: |
@@ -1062,8 +1069,8 @@ static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp, | |||
1062 | &qp->db); | 1069 | &qp->db); |
1063 | ib_umem_release(qp->umem); | 1070 | ib_umem_release(qp->umem); |
1064 | } else { | 1071 | } else { |
1065 | kfree(qp->sq.wrid); | 1072 | kvfree(qp->sq.wrid); |
1066 | kfree(qp->rq.wrid); | 1073 | kvfree(qp->rq.wrid); |
1067 | if (qp->mlx4_ib_qp_type & (MLX4_IB_QPT_PROXY_SMI_OWNER | | 1074 | if (qp->mlx4_ib_qp_type & (MLX4_IB_QPT_PROXY_SMI_OWNER | |
1068 | MLX4_IB_QPT_PROXY_SMI | MLX4_IB_QPT_PROXY_GSI)) | 1075 | MLX4_IB_QPT_PROXY_SMI | MLX4_IB_QPT_PROXY_GSI)) |
1069 | free_proxy_bufs(&dev->ib_dev, qp); | 1076 | free_proxy_bufs(&dev->ib_dev, qp); |
diff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index dce5dfe3a70e..8d133c40fa0e 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/mlx4/qp.h> | 34 | #include <linux/mlx4/qp.h> |
35 | #include <linux/mlx4/srq.h> | 35 | #include <linux/mlx4/srq.h> |
36 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
37 | #include <linux/vmalloc.h> | ||
37 | 38 | ||
38 | #include "mlx4_ib.h" | 39 | #include "mlx4_ib.h" |
39 | #include "user.h" | 40 | #include "user.h" |
@@ -172,8 +173,12 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd, | |||
172 | 173 | ||
173 | srq->wrid = kmalloc(srq->msrq.max * sizeof (u64), GFP_KERNEL); | 174 | srq->wrid = kmalloc(srq->msrq.max * sizeof (u64), GFP_KERNEL); |
174 | if (!srq->wrid) { | 175 | if (!srq->wrid) { |
175 | err = -ENOMEM; | 176 | srq->wrid = __vmalloc(srq->msrq.max * sizeof(u64), |
176 | goto err_mtt; | 177 | GFP_KERNEL, PAGE_KERNEL); |
178 | if (!srq->wrid) { | ||
179 | err = -ENOMEM; | ||
180 | goto err_mtt; | ||
181 | } | ||
177 | } | 182 | } |
178 | } | 183 | } |
179 | 184 | ||
@@ -204,7 +209,7 @@ err_wrid: | |||
204 | if (pd->uobject) | 209 | if (pd->uobject) |
205 | mlx4_ib_db_unmap_user(to_mucontext(pd->uobject->context), &srq->db); | 210 | mlx4_ib_db_unmap_user(to_mucontext(pd->uobject->context), &srq->db); |
206 | else | 211 | else |
207 | kfree(srq->wrid); | 212 | kvfree(srq->wrid); |
208 | 213 | ||
209 | err_mtt: | 214 | err_mtt: |
210 | mlx4_mtt_cleanup(dev->dev, &srq->mtt); | 215 | mlx4_mtt_cleanup(dev->dev, &srq->mtt); |