RDMA/bnxt_re: Fix the sideband buffer size handling for FW commands
authorSelvin Xavier <selvin.xavier@broadcom.com>
Thu, 3 Aug 2023 08:45:23 +0000 (01:45 -0700)
committerLeon Romanovsky <leon@kernel.org>
Mon, 7 Aug 2023 13:39:42 +0000 (16:39 +0300)
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: Kashyap Desai <kashyap.desai@broadcom.com>
Signed-off-by: Hongguang Gao <hongguang.gao@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
Link: https://lore.kernel.org/r/1691052326-32143-4-git-send-email-selvin.xavier@broadcom.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
drivers/infiniband/hw/bnxt_re/qplib_fp.c
drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
drivers/infiniband/hw/bnxt_re/qplib_sp.c

index f9dee0d..282e34e 100644 (file)
@@ -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;
 }
 
index b30e66b..9d26871 100644 (file)
@@ -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);
-}
index b77928a..05ee8fd 100644 (file)
@@ -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;
 }