Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 40f2287b authored by Jiri Kosina's avatar Jiri Kosina Committed by Roland Dreier
Browse files

IB/mlx4: Implement IB_QP_CREATE_USE_GFP_NOIO



Modify the various routines used to allocate memory resources which
serve QPs in mlx4 to get an input GFP directive.  Have the Ethernet
driver to use GFP_KERNEL in it's QP allocations as done prior to this
commit, and the IB driver to use GFP_NOIO when the IB verbs
IB_QP_CREATE_USE_GFP_NOIO QP creation flag is provided.

Signed-off-by: default avatarMel Gorman <mgorman@suse.de>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
Signed-off-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: default avatarRoland Dreier <roland@purestorage.com>
parent 09b93088
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -102,7 +102,7 @@ static int mlx4_ib_alloc_cq_buf(struct mlx4_ib_dev *dev, struct mlx4_ib_cq_buf *
	int err;

	err = mlx4_buf_alloc(dev->dev, nent * dev->dev->caps.cqe_size,
			     PAGE_SIZE * 2, &buf->buf);
			     PAGE_SIZE * 2, &buf->buf, GFP_KERNEL);

	if (err)
		goto out;
@@ -113,7 +113,7 @@ static int mlx4_ib_alloc_cq_buf(struct mlx4_ib_dev *dev, struct mlx4_ib_cq_buf *
	if (err)
		goto err_buf;

	err = mlx4_buf_write_mtt(dev->dev, &buf->mtt, &buf->buf);
	err = mlx4_buf_write_mtt(dev->dev, &buf->mtt, &buf->buf, GFP_KERNEL);
	if (err)
		goto err_mtt;

@@ -209,7 +209,7 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev, int entries, int vector

		uar = &to_mucontext(context)->uar;
	} else {
		err = mlx4_db_alloc(dev->dev, &cq->db, 1);
		err = mlx4_db_alloc(dev->dev, &cq->db, 1, GFP_KERNEL);
		if (err)
			goto err_cq;

+1 −0
Original line number Diff line number Diff line
@@ -156,6 +156,7 @@ enum mlx4_ib_qp_flags {
	MLX4_IB_QP_LSO = IB_QP_CREATE_IPOIB_UD_LSO,
	MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK = IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK,
	MLX4_IB_QP_NETIF = IB_QP_CREATE_NETIF_QP,
	MLX4_IB_QP_CREATE_USE_GFP_NOIO = IB_QP_CREATE_USE_GFP_NOIO,
	MLX4_IB_SRIOV_TUNNEL_QP = 1 << 30,
	MLX4_IB_SRIOV_SQP = 1 << 31,
};
+17 −13
Original line number Diff line number Diff line
@@ -610,7 +610,8 @@ static int qp_has_rq(struct ib_qp_init_attr *attr)

static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
			    struct ib_qp_init_attr *init_attr,
			    struct ib_udata *udata, int sqpn, struct mlx4_ib_qp **caller_qp)
			    struct ib_udata *udata, int sqpn, struct mlx4_ib_qp **caller_qp,
			    gfp_t gfp)
{
	int qpn;
	int err;
@@ -748,14 +749,14 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
			goto err;

		if (qp_has_rq(init_attr)) {
			err = mlx4_db_alloc(dev->dev, &qp->db, 0);
			err = mlx4_db_alloc(dev->dev, &qp->db, 0, gfp);
			if (err)
				goto err;

			*qp->db.db = 0;
		}

		if (mlx4_buf_alloc(dev->dev, qp->buf_size, PAGE_SIZE * 2, &qp->buf)) {
		if (mlx4_buf_alloc(dev->dev, qp->buf_size, PAGE_SIZE * 2, &qp->buf, gfp)) {
			err = -ENOMEM;
			goto err_db;
		}
@@ -765,13 +766,12 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
		if (err)
			goto err_buf;

		err = mlx4_buf_write_mtt(dev->dev, &qp->mtt, &qp->buf);
		err = mlx4_buf_write_mtt(dev->dev, &qp->mtt, &qp->buf, gfp);
		if (err)
			goto err_mtt;

		qp->sq.wrid  = kmalloc(qp->sq.wqe_cnt * sizeof (u64), GFP_KERNEL);
		qp->rq.wrid  = kmalloc(qp->rq.wqe_cnt * sizeof (u64), GFP_KERNEL);

		qp->sq.wrid  = kmalloc(qp->sq.wqe_cnt * sizeof (u64), gfp);
		qp->rq.wrid  = kmalloc(qp->rq.wqe_cnt * sizeof (u64), gfp);
		if (!qp->sq.wrid || !qp->rq.wrid) {
			err = -ENOMEM;
			goto err_wrid;
@@ -801,7 +801,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
			goto err_proxy;
	}

	err = mlx4_qp_alloc(dev->dev, qpn, &qp->mqp);
	err = mlx4_qp_alloc(dev->dev, qpn, &qp->mqp, gfp);
	if (err)
		goto err_qpn;

@@ -1040,7 +1040,10 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd,
	struct mlx4_ib_qp *qp = NULL;
	int err;
	u16 xrcdn = 0;
	gfp_t gfp;

	gfp = (init_attr->create_flags & MLX4_IB_QP_CREATE_USE_GFP_NOIO) ?
		GFP_NOIO : GFP_KERNEL;
	/*
	 * We only support LSO, vendor flag1, and multicast loopback blocking,
	 * and only for kernel UD QPs.
@@ -1049,7 +1052,8 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd,
					MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK |
					MLX4_IB_SRIOV_TUNNEL_QP |
					MLX4_IB_SRIOV_SQP |
					MLX4_IB_QP_NETIF))
					MLX4_IB_QP_NETIF |
					MLX4_IB_QP_CREATE_USE_GFP_NOIO))
		return ERR_PTR(-EINVAL);

	if (init_attr->create_flags & IB_QP_CREATE_NETIF_QP) {
@@ -1059,7 +1063,7 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd,

	if (init_attr->create_flags &&
	    (udata ||
	     ((init_attr->create_flags & ~MLX4_IB_SRIOV_SQP) &&
	     ((init_attr->create_flags & ~(MLX4_IB_SRIOV_SQP | MLX4_IB_QP_CREATE_USE_GFP_NOIO)) &&
	      init_attr->qp_type != IB_QPT_UD) ||
	     ((init_attr->create_flags & MLX4_IB_SRIOV_SQP) &&
	      init_attr->qp_type > IB_QPT_GSI)))
@@ -1079,7 +1083,7 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd,
	case IB_QPT_RC:
	case IB_QPT_UC:
	case IB_QPT_RAW_PACKET:
		qp = kzalloc(sizeof *qp, GFP_KERNEL);
		qp = kzalloc(sizeof *qp, gfp);
		if (!qp)
			return ERR_PTR(-ENOMEM);
		qp->pri.vid = 0xFFFF;
@@ -1088,7 +1092,7 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd,
	case IB_QPT_UD:
	{
		err = create_qp_common(to_mdev(pd->device), pd, init_attr,
				       udata, 0, &qp);
				       udata, 0, &qp, gfp);
		if (err)
			return ERR_PTR(err);

@@ -1106,7 +1110,7 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd,

		err = create_qp_common(to_mdev(pd->device), pd, init_attr, udata,
				       get_sqp_num(to_mdev(pd->device), init_attr),
				       &qp);
				       &qp, gfp);
		if (err)
			return ERR_PTR(err);

+4 −3
Original line number Diff line number Diff line
@@ -134,13 +134,14 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd,
		if (err)
			goto err_mtt;
	} else {
		err = mlx4_db_alloc(dev->dev, &srq->db, 0);
		err = mlx4_db_alloc(dev->dev, &srq->db, 0, GFP_KERNEL);
		if (err)
			goto err_srq;

		*srq->db.db = 0;

		if (mlx4_buf_alloc(dev->dev, buf_size, PAGE_SIZE * 2, &srq->buf)) {
		if (mlx4_buf_alloc(dev->dev, buf_size, PAGE_SIZE * 2, &srq->buf,
				   GFP_KERNEL)) {
			err = -ENOMEM;
			goto err_db;
		}
@@ -165,7 +166,7 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd,
		if (err)
			goto err_buf;

		err = mlx4_buf_write_mtt(dev->dev, &srq->mtt, &srq->buf);
		err = mlx4_buf_write_mtt(dev->dev, &srq->mtt, &srq->buf, GFP_KERNEL);
		if (err)
			goto err_mtt;

+14 −13
Original line number Diff line number Diff line
@@ -171,7 +171,7 @@ void mlx4_bitmap_cleanup(struct mlx4_bitmap *bitmap)
 */

int mlx4_buf_alloc(struct mlx4_dev *dev, int size, int max_direct,
		   struct mlx4_buf *buf)
		   struct mlx4_buf *buf, gfp_t gfp)
{
	dma_addr_t t;

@@ -180,7 +180,7 @@ int mlx4_buf_alloc(struct mlx4_dev *dev, int size, int max_direct,
		buf->npages       = 1;
		buf->page_shift   = get_order(size) + PAGE_SHIFT;
		buf->direct.buf   = dma_alloc_coherent(&dev->pdev->dev,
						       size, &t, GFP_KERNEL);
						       size, &t, gfp);
		if (!buf->direct.buf)
			return -ENOMEM;

@@ -200,14 +200,14 @@ int mlx4_buf_alloc(struct mlx4_dev *dev, int size, int max_direct,
		buf->npages      = buf->nbufs;
		buf->page_shift  = PAGE_SHIFT;
		buf->page_list   = kcalloc(buf->nbufs, sizeof(*buf->page_list),
					   GFP_KERNEL);
					   gfp);
		if (!buf->page_list)
			return -ENOMEM;

		for (i = 0; i < buf->nbufs; ++i) {
			buf->page_list[i].buf =
				dma_alloc_coherent(&dev->pdev->dev, PAGE_SIZE,
						   &t, GFP_KERNEL);
						   &t, gfp);
			if (!buf->page_list[i].buf)
				goto err_free;

@@ -218,7 +218,7 @@ int mlx4_buf_alloc(struct mlx4_dev *dev, int size, int max_direct,

		if (BITS_PER_LONG == 64) {
			struct page **pages;
			pages = kmalloc(sizeof *pages * buf->nbufs, GFP_KERNEL);
			pages = kmalloc(sizeof *pages * buf->nbufs, gfp);
			if (!pages)
				goto err_free;
			for (i = 0; i < buf->nbufs; ++i)
@@ -260,11 +260,12 @@ void mlx4_buf_free(struct mlx4_dev *dev, int size, struct mlx4_buf *buf)
}
EXPORT_SYMBOL_GPL(mlx4_buf_free);

static struct mlx4_db_pgdir *mlx4_alloc_db_pgdir(struct device *dma_device)
static struct mlx4_db_pgdir *mlx4_alloc_db_pgdir(struct device *dma_device,
						 gfp_t gfp)
{
	struct mlx4_db_pgdir *pgdir;

	pgdir = kzalloc(sizeof *pgdir, GFP_KERNEL);
	pgdir = kzalloc(sizeof *pgdir, gfp);
	if (!pgdir)
		return NULL;

@@ -272,7 +273,7 @@ static struct mlx4_db_pgdir *mlx4_alloc_db_pgdir(struct device *dma_device)
	pgdir->bits[0] = pgdir->order0;
	pgdir->bits[1] = pgdir->order1;
	pgdir->db_page = dma_alloc_coherent(dma_device, PAGE_SIZE,
					    &pgdir->db_dma, GFP_KERNEL);
					    &pgdir->db_dma, gfp);
	if (!pgdir->db_page) {
		kfree(pgdir);
		return NULL;
@@ -312,7 +313,7 @@ found:
	return 0;
}

int mlx4_db_alloc(struct mlx4_dev *dev, struct mlx4_db *db, int order)
int mlx4_db_alloc(struct mlx4_dev *dev, struct mlx4_db *db, int order, gfp_t gfp)
{
	struct mlx4_priv *priv = mlx4_priv(dev);
	struct mlx4_db_pgdir *pgdir;
@@ -324,7 +325,7 @@ int mlx4_db_alloc(struct mlx4_dev *dev, struct mlx4_db *db, int order)
		if (!mlx4_alloc_db_from_pgdir(pgdir, db, order))
			goto out;

	pgdir = mlx4_alloc_db_pgdir(&(dev->pdev->dev));
	pgdir = mlx4_alloc_db_pgdir(&(dev->pdev->dev), gfp);
	if (!pgdir) {
		ret = -ENOMEM;
		goto out;
@@ -376,13 +377,13 @@ int mlx4_alloc_hwq_res(struct mlx4_dev *dev, struct mlx4_hwq_resources *wqres,
{
	int err;

	err = mlx4_db_alloc(dev, &wqres->db, 1);
	err = mlx4_db_alloc(dev, &wqres->db, 1, GFP_KERNEL);
	if (err)
		return err;

	*wqres->db.db = 0;

	err = mlx4_buf_alloc(dev, size, max_direct, &wqres->buf);
	err = mlx4_buf_alloc(dev, size, max_direct, &wqres->buf, GFP_KERNEL);
	if (err)
		goto err_db;

@@ -391,7 +392,7 @@ int mlx4_alloc_hwq_res(struct mlx4_dev *dev, struct mlx4_hwq_resources *wqres,
	if (err)
		goto err_buf;

	err = mlx4_buf_write_mtt(dev, &wqres->mtt, &wqres->buf);
	err = mlx4_buf_write_mtt(dev, &wqres->mtt, &wqres->buf, GFP_KERNEL);
	if (err)
		goto err_mtt;

Loading