IB/mlx5: use kvmalloc_array for mlx5_ib_wq
authorLi Dongyang <dongyang.li@anu.edu.au>
Wed, 16 Aug 2017 13:31:22 +0000 (23:31 +1000)
committerDoug Ledford <dledford@redhat.com>
Tue, 22 Aug 2017 20:48:23 +0000 (16:48 -0400)
We observed multiple times on our Lustre OSS servers that when
the system memory is fragmented, kmalloc() in create_kernel_qp()
could fail order 4/5 allocations while we still have many free pages.

Switch to kvmalloc_array() to allow the operation to contine.

Signed-off-by: Li Dongyang <dongyang.li@anu.edu.au>
Acked-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/hw/mlx5/qp.c
drivers/infiniband/hw/mlx5/srq.c

index 5c7ce9bd466e11f597235d9be69a2b3e8b087a14..e098c97e027a74d96bed9a44765b9f850c29545d 100644 (file)
@@ -965,11 +965,16 @@ static int create_kernel_qp(struct mlx5_ib_dev *dev,
                goto err_free;
        }
 
-       qp->sq.wrid = kmalloc(qp->sq.wqe_cnt * sizeof(*qp->sq.wrid), GFP_KERNEL);
-       qp->sq.wr_data = kmalloc(qp->sq.wqe_cnt * sizeof(*qp->sq.wr_data), GFP_KERNEL);
-       qp->rq.wrid = kmalloc(qp->rq.wqe_cnt * sizeof(*qp->rq.wrid), GFP_KERNEL);
-       qp->sq.w_list = kmalloc(qp->sq.wqe_cnt * sizeof(*qp->sq.w_list), GFP_KERNEL);
-       qp->sq.wqe_head = kmalloc(qp->sq.wqe_cnt * sizeof(*qp->sq.wqe_head), GFP_KERNEL);
+       qp->sq.wrid = kvmalloc_array(qp->sq.wqe_cnt,
+                                    sizeof(*qp->sq.wrid), GFP_KERNEL);
+       qp->sq.wr_data = kvmalloc_array(qp->sq.wqe_cnt,
+                                       sizeof(*qp->sq.wr_data), GFP_KERNEL);
+       qp->rq.wrid = kvmalloc_array(qp->rq.wqe_cnt,
+                                    sizeof(*qp->rq.wrid), GFP_KERNEL);
+       qp->sq.w_list = kvmalloc_array(qp->sq.wqe_cnt,
+                                      sizeof(*qp->sq.w_list), GFP_KERNEL);
+       qp->sq.wqe_head = kvmalloc_array(qp->sq.wqe_cnt,
+                                        sizeof(*qp->sq.wqe_head), GFP_KERNEL);
 
        if (!qp->sq.wrid || !qp->sq.wr_data || !qp->rq.wrid ||
            !qp->sq.w_list || !qp->sq.wqe_head) {
@@ -981,11 +986,11 @@ static int create_kernel_qp(struct mlx5_ib_dev *dev,
        return 0;
 
 err_wrid:
-       kfree(qp->sq.wqe_head);
-       kfree(qp->sq.w_list);
-       kfree(qp->sq.wrid);
-       kfree(qp->sq.wr_data);
-       kfree(qp->rq.wrid);
+       kvfree(qp->sq.wqe_head);
+       kvfree(qp->sq.w_list);
+       kvfree(qp->sq.wrid);
+       kvfree(qp->sq.wr_data);
+       kvfree(qp->rq.wrid);
        mlx5_db_free(dev->mdev, &qp->db);
 
 err_free:
@@ -998,11 +1003,11 @@ err_buf:
 
 static void destroy_qp_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)
 {
-       kfree(qp->sq.wqe_head);
-       kfree(qp->sq.w_list);
-       kfree(qp->sq.wrid);
-       kfree(qp->sq.wr_data);
-       kfree(qp->rq.wrid);
+       kvfree(qp->sq.wqe_head);
+       kvfree(qp->sq.w_list);
+       kvfree(qp->sq.wrid);
+       kvfree(qp->sq.wr_data);
+       kvfree(qp->rq.wrid);
        mlx5_db_free(dev->mdev, &qp->db);
        mlx5_buf_free(dev->mdev, &qp->buf);
 }
index 43707b101f47794ef69fa87e0d7946f89090934d..30b3ddd8e1abf5ed7db6243d784207ae33c4a758 100644 (file)
@@ -196,7 +196,7 @@ static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq,
        }
        mlx5_fill_page_array(&srq->buf, in->pas);
 
-       srq->wrid = kmalloc(srq->msrq.max * sizeof(u64), GFP_KERNEL);
+       srq->wrid = kvmalloc_array(srq->msrq.max, sizeof(u64), GFP_KERNEL);
        if (!srq->wrid) {
                err = -ENOMEM;
                goto err_in;
@@ -230,7 +230,7 @@ static void destroy_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq)
 
 static void destroy_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq)
 {
-       kfree(srq->wrid);
+       kvfree(srq->wrid);
        mlx5_buf_free(dev->mdev, &srq->buf);
        mlx5_db_free(dev->mdev, &srq->db);
 }