OSDN Git Service

RDMA/bnxt_re: Increase depth of control path command queue
authorDevesh Sharma <devesh.sharma@broadcom.com>
Wed, 12 Dec 2018 09:56:24 +0000 (01:56 -0800)
committerJason Gunthorpe <jgg@mellanox.com>
Wed, 19 Dec 2018 23:37:33 +0000 (16:37 -0700)
Increasing the depth of control path command queue to 8K entries to handle
burst of commands. This feature needs support from FW and the driver/fw
compatibility is checked from the interface version number.

Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/hw/bnxt_re/main.c
drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
drivers/infiniband/hw/bnxt_re/qplib_rcfw.h

index 1d18b77..e7a997f 100644 (file)
@@ -1314,6 +1314,7 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
         * memory for the function and all child VFs
         */
        rc = bnxt_qplib_alloc_rcfw_channel(rdev->en_dev->pdev, &rdev->rcfw,
+                                          &rdev->qplib_ctx,
                                           BNXT_RE_MAX_QPC_COUNT);
        if (rc) {
                pr_err("Failed to allocate RCFW Channel: %#x\n", rc);
index be4e33e..3268054 100644 (file)
@@ -58,7 +58,7 @@ static int __wait_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)
        u16 cbit;
        int rc;
 
-       cbit = cookie % RCFW_MAX_OUTSTANDING_CMD;
+       cbit = cookie % rcfw->cmdq_depth;
        rc = wait_event_timeout(rcfw->waitq,
                                !test_bit(cbit, rcfw->cmdq_bitmap),
                                msecs_to_jiffies(RCFW_CMD_WAIT_TIME_MS));
@@ -70,7 +70,7 @@ static int __block_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)
        u32 count = RCFW_BLOCKED_CMD_WAIT_COUNT;
        u16 cbit;
 
-       cbit = cookie % RCFW_MAX_OUTSTANDING_CMD;
+       cbit = cookie % rcfw->cmdq_depth;
        if (!test_bit(cbit, rcfw->cmdq_bitmap))
                goto done;
        do {
@@ -86,6 +86,7 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw, struct cmdq_base *req,
 {
        struct bnxt_qplib_cmdqe *cmdqe, **cmdq_ptr;
        struct bnxt_qplib_hwq *cmdq = &rcfw->cmdq;
+       u32 cmdq_depth = rcfw->cmdq_depth;
        struct bnxt_qplib_crsq *crsqe;
        u32 sw_prod, cmdq_prod;
        unsigned long flags;
@@ -124,7 +125,7 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw, struct cmdq_base *req,
 
 
        cookie = rcfw->seq_num & RCFW_MAX_COOKIE_VALUE;
-       cbit = cookie % RCFW_MAX_OUTSTANDING_CMD;
+       cbit = cookie % rcfw->cmdq_depth;
        if (is_block)
                cookie |= RCFW_CMD_IS_BLOCKING;
 
@@ -153,7 +154,8 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw, struct cmdq_base *req,
        do {
                /* Locate the next cmdq slot */
                sw_prod = HWQ_CMP(cmdq->prod, cmdq);
-               cmdqe = &cmdq_ptr[get_cmdq_pg(sw_prod)][get_cmdq_idx(sw_prod)];
+               cmdqe = &cmdq_ptr[get_cmdq_pg(sw_prod, cmdq_depth)]
+                               [get_cmdq_idx(sw_prod, cmdq_depth)];
                if (!cmdqe) {
                        dev_err(&rcfw->pdev->dev,
                                "RCFW request failed with no cmdqe!\n");
@@ -326,7 +328,7 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
                mcookie = qp_event->cookie;
                blocked = cookie & RCFW_CMD_IS_BLOCKING;
                cookie &= RCFW_MAX_COOKIE_VALUE;
-               cbit = cookie % RCFW_MAX_OUTSTANDING_CMD;
+               cbit = cookie % rcfw->cmdq_depth;
                crsqe = &rcfw->crsqe_tbl[cbit];
                if (crsqe->resp &&
                    crsqe->resp->cookie  == mcookie) {
@@ -555,6 +557,7 @@ void bnxt_qplib_free_rcfw_channel(struct bnxt_qplib_rcfw *rcfw)
 
 int bnxt_qplib_alloc_rcfw_channel(struct pci_dev *pdev,
                                  struct bnxt_qplib_rcfw *rcfw,
+                                 struct bnxt_qplib_ctx *ctx,
                                  int qp_tbl_sz)
 {
        rcfw->pdev = pdev;
@@ -567,11 +570,18 @@ int bnxt_qplib_alloc_rcfw_channel(struct pci_dev *pdev,
                        "HW channel CREQ allocation failed\n");
                goto fail;
        }
-       rcfw->cmdq.max_elements = BNXT_QPLIB_CMDQE_MAX_CNT;
-       if (bnxt_qplib_alloc_init_hwq(rcfw->pdev, &rcfw->cmdq, NULL, 0,
-                                     &rcfw->cmdq.max_elements,
-                                     BNXT_QPLIB_CMDQE_UNITS, 0, PAGE_SIZE,
-                                     HWQ_TYPE_CTX)) {
+       if (ctx->hwrm_intf_ver < HWRM_VERSION_RCFW_CMDQ_DEPTH_CHECK)
+               rcfw->cmdq_depth = BNXT_QPLIB_CMDQE_MAX_CNT_256;
+       else
+               rcfw->cmdq_depth = BNXT_QPLIB_CMDQE_MAX_CNT_8192;
+
+       rcfw->cmdq.max_elements = rcfw->cmdq_depth;
+       if (bnxt_qplib_alloc_init_hwq
+                       (rcfw->pdev, &rcfw->cmdq, NULL, 0,
+                        &rcfw->cmdq.max_elements,
+                        BNXT_QPLIB_CMDQE_UNITS, 0,
+                        bnxt_qplib_cmdqe_page_size(rcfw->cmdq_depth),
+                        HWQ_TYPE_CTX)) {
                dev_err(&rcfw->pdev->dev,
                        "HW channel CMDQ allocation failed\n");
                goto fail;
@@ -674,7 +684,7 @@ int bnxt_qplib_enable_rcfw_channel(struct pci_dev *pdev,
        /* General */
        rcfw->seq_num = 0;
        set_bit(FIRMWARE_FIRST_FLAG, &rcfw->flags);
-       bmap_size = BITS_TO_LONGS(RCFW_MAX_OUTSTANDING_CMD *
+       bmap_size = BITS_TO_LONGS(rcfw->cmdq_depth *
                                  sizeof(unsigned long));
        rcfw->cmdq_bitmap = kzalloc(bmap_size, GFP_KERNEL);
        if (!rcfw->cmdq_bitmap)
@@ -734,7 +744,7 @@ int bnxt_qplib_enable_rcfw_channel(struct pci_dev *pdev,
 
        init.cmdq_pbl = cpu_to_le64(rcfw->cmdq.pbl[PBL_LVL_0].pg_map_arr[0]);
        init.cmdq_size_cmdq_lvl = cpu_to_le16(
-               ((BNXT_QPLIB_CMDQE_MAX_CNT << CMDQ_INIT_CMDQ_SIZE_SFT) &
+               ((rcfw->cmdq_depth << CMDQ_INIT_CMDQ_SIZE_SFT) &
                 CMDQ_INIT_CMDQ_SIZE_MASK) |
                ((rcfw->cmdq.level << CMDQ_INIT_CMDQ_LVL_SFT) &
                 CMDQ_INIT_CMDQ_LVL_MASK));
index 9a8687d..be0ef0e 100644 (file)
 
 #define RCFW_CMD_WAIT_TIME_MS          20000 /* 20 Seconds timeout */
 
+/* Cmdq contains a fix number of a 16-Byte slots */
+struct bnxt_qplib_cmdqe {
+       u8              data[16];
+};
+
 /* CMDQ elements */
-#define BNXT_QPLIB_CMDQE_MAX_CNT       256
+#define BNXT_QPLIB_CMDQE_MAX_CNT_256   256
+#define BNXT_QPLIB_CMDQE_MAX_CNT_8192  8192
 #define BNXT_QPLIB_CMDQE_UNITS         sizeof(struct bnxt_qplib_cmdqe)
-#define BNXT_QPLIB_CMDQE_CNT_PER_PG    (PAGE_SIZE / BNXT_QPLIB_CMDQE_UNITS)
+#define BNXT_QPLIB_CMDQE_BYTES(depth)  ((depth) * BNXT_QPLIB_CMDQE_UNITS)
+
+static inline u32 bnxt_qplib_cmdqe_npages(u32 depth)
+{
+       u32 npages;
+
+       npages = BNXT_QPLIB_CMDQE_BYTES(depth) / PAGE_SIZE;
+       if (BNXT_QPLIB_CMDQE_BYTES(depth) % PAGE_SIZE)
+               npages++;
+       return npages;
+}
+
+static inline u32 bnxt_qplib_cmdqe_page_size(u32 depth)
+{
+       return (bnxt_qplib_cmdqe_npages(depth) * PAGE_SIZE);
+}
+
+static inline u32 bnxt_qplib_cmdqe_cnt_per_pg(u32 depth)
+{
+       return (bnxt_qplib_cmdqe_page_size(depth) /
+                BNXT_QPLIB_CMDQE_UNITS);
+}
 
-#define MAX_CMDQ_IDX                   (BNXT_QPLIB_CMDQE_MAX_CNT - 1)
-#define MAX_CMDQ_IDX_PER_PG            (BNXT_QPLIB_CMDQE_CNT_PER_PG - 1)
+#define MAX_CMDQ_IDX(depth)            ((depth) - 1)
+
+static inline u32 bnxt_qplib_max_cmdq_idx_per_pg(u32 depth)
+{
+       return (bnxt_qplib_cmdqe_cnt_per_pg(depth) - 1);
+}
 
-#define RCFW_MAX_OUTSTANDING_CMD       BNXT_QPLIB_CMDQE_MAX_CNT
 #define RCFW_MAX_COOKIE_VALUE          0x7FFF
 #define RCFW_CMD_IS_BLOCKING           0x8000
 #define RCFW_BLOCKED_CMD_WAIT_COUNT    0x4E20
 
-/* Cmdq contains a fix number of a 16-Byte slots */
-struct bnxt_qplib_cmdqe {
-       u8              data[16];
-};
+#define HWRM_VERSION_RCFW_CMDQ_DEPTH_CHECK 0x1000900020011ULL
 
-static inline u32 get_cmdq_pg(u32 val)
+static inline u32 get_cmdq_pg(u32 val, u32 depth)
 {
-       return (val & ~MAX_CMDQ_IDX_PER_PG) / BNXT_QPLIB_CMDQE_CNT_PER_PG;
+       return (val & ~(bnxt_qplib_max_cmdq_idx_per_pg(depth))) /
+               (bnxt_qplib_cmdqe_cnt_per_pg(depth));
 }
 
-static inline u32 get_cmdq_idx(u32 val)
+static inline u32 get_cmdq_idx(u32 val, u32 depth)
 {
-       return val & MAX_CMDQ_IDX_PER_PG;
+       return val & (bnxt_qplib_max_cmdq_idx_per_pg(depth));
 }
 
 /* Crsq buf is 1024-Byte */
@@ -194,11 +222,14 @@ struct bnxt_qplib_rcfw {
        struct bnxt_qplib_qp_node *qp_tbl;
        u64 oos_prev;
        u32 init_oos_stats;
+       u32 cmdq_depth;
 };
 
 void bnxt_qplib_free_rcfw_channel(struct bnxt_qplib_rcfw *rcfw);
 int bnxt_qplib_alloc_rcfw_channel(struct pci_dev *pdev,
-                                 struct bnxt_qplib_rcfw *rcfw, int qp_tbl_sz);
+                                 struct bnxt_qplib_rcfw *rcfw,
+                                 struct bnxt_qplib_ctx *ctx,
+                                 int qp_tbl_sz);
 void bnxt_qplib_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill);
 void bnxt_qplib_disable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw);
 int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector,