Commit c9f3e4e1 authored by Selvin Xavier's avatar Selvin Xavier Committed by Leon Romanovsky
Browse files

RDMA/bnxt_re: Fix the sideband buffer size handling for FW commands



bnxt_qplib_rcfw_alloc_sbuf allocates 24 bytes and it is better to fit
on stack variables. This way we can avoid unwanted kmalloc call.
Call dma_alloc_coherent directly instead of wrapper
bnxt_qplib_rcfw_alloc_sbuf.

Also, FW expects the side buffer  needs to be aligned to
BNXT_QPLIB_CMDQE_UNITS(16B). So align the size to have the
extra padding bytes.

Signed-off-by: default avatarKashyap Desai <kashyap.desai@broadcom.com>
Signed-off-by: default avatarHongguang Gao <hongguang.gao@broadcom.com>
Signed-off-by: default avatarSelvin Xavier <selvin.xavier@broadcom.com>
Link: https://lore.kernel.org/r/1691052326-32143-4-git-send-email-selvin.xavier@broadcom.com


Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
parent fd28c8a8
Loading
Loading
Loading
Loading
+22 −16
Original line number Diff line number Diff line
@@ -709,7 +709,7 @@ int bnxt_qplib_query_srq(struct bnxt_qplib_res *res,
	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
	struct creq_query_srq_resp resp = {};
	struct bnxt_qplib_cmdqmsg msg = {};
	struct bnxt_qplib_rcfw_sbuf *sbuf;
	struct bnxt_qplib_rcfw_sbuf sbuf;
	struct creq_query_srq_resp_sb *sb;
	struct cmdq_query_srq req = {};
	int rc = 0;
@@ -719,17 +719,20 @@ int bnxt_qplib_query_srq(struct bnxt_qplib_res *res,
				 sizeof(req));

	/* Configure the request */
	sbuf = bnxt_qplib_rcfw_alloc_sbuf(rcfw, sizeof(*sb));
	if (!sbuf)
	sbuf.size = ALIGN(sizeof(*sb), BNXT_QPLIB_CMDQE_UNITS);
	sbuf.sb = dma_alloc_coherent(&rcfw->pdev->dev, sbuf.size,
				     &sbuf.dma_addr, GFP_KERNEL);
	if (!sbuf.sb)
		return -ENOMEM;
	req.resp_size = sizeof(*sb) / BNXT_QPLIB_CMDQE_UNITS;
	req.resp_size = sbuf.size / BNXT_QPLIB_CMDQE_UNITS;
	req.srq_cid = cpu_to_le32(srq->id);
	sb = sbuf->sb;
	bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, sbuf, sizeof(req),
	sb = sbuf.sb;
	bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, &sbuf, sizeof(req),
				sizeof(resp), 0);
	rc = bnxt_qplib_rcfw_send_message(rcfw, &msg);
	srq->threshold = le16_to_cpu(sb->srq_limit);
	bnxt_qplib_rcfw_free_sbuf(rcfw, sbuf);
	dma_free_coherent(&rcfw->pdev->dev, sbuf.size,
			  sbuf.sb, sbuf.dma_addr);

	return rc;
}
@@ -1347,24 +1350,26 @@ int bnxt_qplib_query_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
	struct creq_query_qp_resp resp = {};
	struct bnxt_qplib_cmdqmsg msg = {};
	struct bnxt_qplib_rcfw_sbuf *sbuf;
	struct bnxt_qplib_rcfw_sbuf sbuf;
	struct creq_query_qp_resp_sb *sb;
	struct cmdq_query_qp req = {};
	u32 temp32[4];
	int i, rc = 0;

	sbuf.size = ALIGN(sizeof(*sb), BNXT_QPLIB_CMDQE_UNITS);
	sbuf.sb = dma_alloc_coherent(&rcfw->pdev->dev, sbuf.size,
				     &sbuf.dma_addr, GFP_KERNEL);
	if (!sbuf.sb)
		return -ENOMEM;
	sb = sbuf.sb;

	bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
				 CMDQ_BASE_OPCODE_QUERY_QP,
				 sizeof(req));

	sbuf = bnxt_qplib_rcfw_alloc_sbuf(rcfw, sizeof(*sb));
	if (!sbuf)
		return -ENOMEM;
	sb = sbuf->sb;

	req.qp_cid = cpu_to_le32(qp->id);
	req.resp_size = sizeof(*sb) / BNXT_QPLIB_CMDQE_UNITS;
	bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, sbuf, sizeof(req),
	req.resp_size = sbuf.size / BNXT_QPLIB_CMDQE_UNITS;
	bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, &sbuf, sizeof(req),
				sizeof(resp), 0);
	rc = bnxt_qplib_rcfw_send_message(rcfw, &msg);
	if (rc)
@@ -1423,7 +1428,8 @@ int bnxt_qplib_query_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
	memcpy(qp->smac, sb->src_mac, 6);
	qp->vlan_id = le16_to_cpu(sb->vlan_pcp_vlan_dei_vlan_id);
bail:
	bnxt_qplib_rcfw_free_sbuf(rcfw, sbuf);
	dma_free_coherent(&rcfw->pdev->dev, sbuf.size,
			  sbuf.sb, sbuf.dma_addr);
	return rc;
}

+2 −32
Original line number Diff line number Diff line
@@ -335,7 +335,8 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw,
					  cpu_to_le64(sbuf->dma_addr));
		__set_cmdq_base_resp_size(msg->req, msg->req_sz,
					  ALIGN(sbuf->size,
						BNXT_QPLIB_CMDQE_UNITS));
						BNXT_QPLIB_CMDQE_UNITS) /
						BNXT_QPLIB_CMDQE_UNITS);
	}

	preq = (u8 *)msg->req;
@@ -1196,34 +1197,3 @@ int bnxt_qplib_enable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw,

	return 0;
}

struct bnxt_qplib_rcfw_sbuf *bnxt_qplib_rcfw_alloc_sbuf(
		struct bnxt_qplib_rcfw *rcfw,
		u32 size)
{
	struct bnxt_qplib_rcfw_sbuf *sbuf;

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

	sbuf->size = size;
	sbuf->sb = dma_alloc_coherent(&rcfw->pdev->dev, sbuf->size,
				      &sbuf->dma_addr, GFP_KERNEL);
	if (!sbuf->sb)
		goto bail;

	return sbuf;
bail:
	kfree(sbuf);
	return NULL;
}

void bnxt_qplib_rcfw_free_sbuf(struct bnxt_qplib_rcfw *rcfw,
			       struct bnxt_qplib_rcfw_sbuf *sbuf)
{
	if (sbuf->sb)
		dma_free_coherent(&rcfw->pdev->dev, sbuf->size,
				  sbuf->sb, sbuf->dma_addr);
	kfree(sbuf);
}
+31 −32
Original line number Diff line number Diff line
@@ -94,7 +94,7 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw,
	struct creq_query_func_resp resp = {};
	struct bnxt_qplib_cmdqmsg msg = {};
	struct creq_query_func_resp_sb *sb;
	struct bnxt_qplib_rcfw_sbuf *sbuf;
	struct bnxt_qplib_rcfw_sbuf sbuf;
	struct cmdq_query_func req = {};
	u8 *tqm_alloc;
	int i, rc = 0;
@@ -104,16 +104,14 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw,
				 CMDQ_BASE_OPCODE_QUERY_FUNC,
				 sizeof(req));

	sbuf = bnxt_qplib_rcfw_alloc_sbuf(rcfw, sizeof(*sb));
	if (!sbuf) {
		dev_err(&rcfw->pdev->dev,
			"SP: QUERY_FUNC alloc side buffer failed\n");
	sbuf.size = ALIGN(sizeof(*sb), BNXT_QPLIB_CMDQE_UNITS);
	sbuf.sb = dma_alloc_coherent(&rcfw->pdev->dev, sbuf.size,
				     &sbuf.dma_addr, GFP_KERNEL);
	if (!sbuf.sb)
		return -ENOMEM;
	}

	sb = sbuf->sb;
	req.resp_size = sizeof(*sb) / BNXT_QPLIB_CMDQE_UNITS;
	bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, sbuf, sizeof(req),
	sb = sbuf.sb;
	req.resp_size = sbuf.size / BNXT_QPLIB_CMDQE_UNITS;
	bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, &sbuf, sizeof(req),
				sizeof(resp), 0);
	rc = bnxt_qplib_rcfw_send_message(rcfw, &msg);
	if (rc)
@@ -174,7 +172,8 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw,

	attr->is_atomic = bnxt_qplib_is_atomic_cap(rcfw);
bail:
	bnxt_qplib_rcfw_free_sbuf(rcfw, sbuf);
	dma_free_coherent(&rcfw->pdev->dev, sbuf.size,
			  sbuf.sb, sbuf.dma_addr);
	return rc;
}

@@ -717,23 +716,22 @@ int bnxt_qplib_get_roce_stats(struct bnxt_qplib_rcfw *rcfw,
	struct creq_query_roce_stats_resp_sb *sb;
	struct cmdq_query_roce_stats req = {};
	struct bnxt_qplib_cmdqmsg msg = {};
	struct bnxt_qplib_rcfw_sbuf *sbuf;
	struct bnxt_qplib_rcfw_sbuf sbuf;
	int rc = 0;

	bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
				 CMDQ_BASE_OPCODE_QUERY_ROCE_STATS,
				 sizeof(req));

	sbuf = bnxt_qplib_rcfw_alloc_sbuf(rcfw, sizeof(*sb));
	if (!sbuf) {
		dev_err(&rcfw->pdev->dev,
			"SP: QUERY_ROCE_STATS alloc side buffer failed\n");
	sbuf.size = ALIGN(sizeof(*sb), BNXT_QPLIB_CMDQE_UNITS);
	sbuf.sb = dma_alloc_coherent(&rcfw->pdev->dev, sbuf.size,
				     &sbuf.dma_addr, GFP_KERNEL);
	if (!sbuf.sb)
		return -ENOMEM;
	}
	sb = sbuf.sb;

	sb = sbuf->sb;
	req.resp_size = sizeof(*sb) / BNXT_QPLIB_CMDQE_UNITS;
	bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, sbuf, sizeof(req),
	req.resp_size = sbuf.size / BNXT_QPLIB_CMDQE_UNITS;
	bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, &sbuf, sizeof(req),
				sizeof(resp), 0);
	rc = bnxt_qplib_rcfw_send_message(rcfw, &msg);
	if (rc)
@@ -789,7 +787,8 @@ int bnxt_qplib_get_roce_stats(struct bnxt_qplib_rcfw *rcfw,
	}

bail:
	bnxt_qplib_rcfw_free_sbuf(rcfw, sbuf);
	dma_free_coherent(&rcfw->pdev->dev, sbuf.size,
			  sbuf.sb, sbuf.dma_addr);
	return rc;
}

@@ -800,32 +799,31 @@ int bnxt_qplib_qext_stat(struct bnxt_qplib_rcfw *rcfw, u32 fid,
	struct creq_query_roce_stats_ext_resp_sb *sb;
	struct cmdq_query_roce_stats_ext req = {};
	struct bnxt_qplib_cmdqmsg msg = {};
	struct bnxt_qplib_rcfw_sbuf *sbuf;
	struct bnxt_qplib_rcfw_sbuf sbuf;
	int rc;

	sbuf = bnxt_qplib_rcfw_alloc_sbuf(rcfw, sizeof(*sb));
	if (!sbuf) {
		dev_err(&rcfw->pdev->dev,
			"SP: QUERY_ROCE_STATS_EXT alloc sb failed");
	sbuf.size = ALIGN(sizeof(*sb), BNXT_QPLIB_CMDQE_UNITS);
	sbuf.sb = dma_alloc_coherent(&rcfw->pdev->dev, sbuf.size,
				     &sbuf.dma_addr, GFP_KERNEL);
	if (!sbuf.sb)
		return -ENOMEM;
	}

	sb = sbuf.sb;
	bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
				 CMDQ_QUERY_ROCE_STATS_EXT_OPCODE_QUERY_ROCE_STATS,
				 sizeof(req));

	req.resp_size = ALIGN(sizeof(*sb), BNXT_QPLIB_CMDQE_UNITS);
	req.resp_addr = cpu_to_le64(sbuf->dma_addr);
	req.resp_size = sbuf.size / BNXT_QPLIB_CMDQE_UNITS;
	req.resp_addr = cpu_to_le64(sbuf.dma_addr);
	req.function_id = cpu_to_le32(fid);
	req.flags = cpu_to_le16(CMDQ_QUERY_ROCE_STATS_EXT_FLAGS_FUNCTION_ID);

	bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, sbuf, sizeof(req),
	bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, &sbuf, sizeof(req),
				sizeof(resp), 0);
	rc = bnxt_qplib_rcfw_send_message(rcfw, &msg);
	if (rc)
		goto bail;

	sb = sbuf->sb;
	estat->tx_atomic_req = le64_to_cpu(sb->tx_atomic_req_pkts);
	estat->tx_read_req = le64_to_cpu(sb->tx_read_req_pkts);
	estat->tx_read_res = le64_to_cpu(sb->tx_read_res_pkts);
@@ -849,7 +847,8 @@ int bnxt_qplib_qext_stat(struct bnxt_qplib_rcfw *rcfw, u32 fid,
	estat->rx_ecn_marked = le64_to_cpu(sb->rx_ecn_marked_pkts);

bail:
	bnxt_qplib_rcfw_free_sbuf(rcfw, sbuf);
	dma_free_coherent(&rcfw->pdev->dev, sbuf.size,
			  sbuf.sb, sbuf.dma_addr);
	return rc;
}