RDMA/bnxt_re: Increase depth of control path command queue

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>
This commit is contained in:
Devesh Sharma 2018-12-12 01:56:24 -08:00 committed by Jason Gunthorpe
parent 2b827ea192
commit bd1c24ccf9
3 changed files with 72 additions and 30 deletions

View File

@ -1314,6 +1314,7 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
* memory for the function and all child VFs * memory for the function and all child VFs
*/ */
rc = bnxt_qplib_alloc_rcfw_channel(rdev->en_dev->pdev, &rdev->rcfw, rc = bnxt_qplib_alloc_rcfw_channel(rdev->en_dev->pdev, &rdev->rcfw,
&rdev->qplib_ctx,
BNXT_RE_MAX_QPC_COUNT); BNXT_RE_MAX_QPC_COUNT);
if (rc) { if (rc) {
pr_err("Failed to allocate RCFW Channel: %#x\n", rc); pr_err("Failed to allocate RCFW Channel: %#x\n", rc);

View File

@ -58,7 +58,7 @@ static int __wait_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)
u16 cbit; u16 cbit;
int rc; int rc;
cbit = cookie % RCFW_MAX_OUTSTANDING_CMD; cbit = cookie % rcfw->cmdq_depth;
rc = wait_event_timeout(rcfw->waitq, rc = wait_event_timeout(rcfw->waitq,
!test_bit(cbit, rcfw->cmdq_bitmap), !test_bit(cbit, rcfw->cmdq_bitmap),
msecs_to_jiffies(RCFW_CMD_WAIT_TIME_MS)); 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; u32 count = RCFW_BLOCKED_CMD_WAIT_COUNT;
u16 cbit; u16 cbit;
cbit = cookie % RCFW_MAX_OUTSTANDING_CMD; cbit = cookie % rcfw->cmdq_depth;
if (!test_bit(cbit, rcfw->cmdq_bitmap)) if (!test_bit(cbit, rcfw->cmdq_bitmap))
goto done; goto done;
do { 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_cmdqe *cmdqe, **cmdq_ptr;
struct bnxt_qplib_hwq *cmdq = &rcfw->cmdq; struct bnxt_qplib_hwq *cmdq = &rcfw->cmdq;
u32 cmdq_depth = rcfw->cmdq_depth;
struct bnxt_qplib_crsq *crsqe; struct bnxt_qplib_crsq *crsqe;
u32 sw_prod, cmdq_prod; u32 sw_prod, cmdq_prod;
unsigned long flags; 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; cookie = rcfw->seq_num & RCFW_MAX_COOKIE_VALUE;
cbit = cookie % RCFW_MAX_OUTSTANDING_CMD; cbit = cookie % rcfw->cmdq_depth;
if (is_block) if (is_block)
cookie |= RCFW_CMD_IS_BLOCKING; cookie |= RCFW_CMD_IS_BLOCKING;
@ -153,7 +154,8 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw, struct cmdq_base *req,
do { do {
/* Locate the next cmdq slot */ /* Locate the next cmdq slot */
sw_prod = HWQ_CMP(cmdq->prod, cmdq); 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) { if (!cmdqe) {
dev_err(&rcfw->pdev->dev, dev_err(&rcfw->pdev->dev,
"RCFW request failed with no cmdqe!\n"); "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; mcookie = qp_event->cookie;
blocked = cookie & RCFW_CMD_IS_BLOCKING; blocked = cookie & RCFW_CMD_IS_BLOCKING;
cookie &= RCFW_MAX_COOKIE_VALUE; cookie &= RCFW_MAX_COOKIE_VALUE;
cbit = cookie % RCFW_MAX_OUTSTANDING_CMD; cbit = cookie % rcfw->cmdq_depth;
crsqe = &rcfw->crsqe_tbl[cbit]; crsqe = &rcfw->crsqe_tbl[cbit];
if (crsqe->resp && if (crsqe->resp &&
crsqe->resp->cookie == mcookie) { 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, int bnxt_qplib_alloc_rcfw_channel(struct pci_dev *pdev,
struct bnxt_qplib_rcfw *rcfw, struct bnxt_qplib_rcfw *rcfw,
struct bnxt_qplib_ctx *ctx,
int qp_tbl_sz) int qp_tbl_sz)
{ {
rcfw->pdev = pdev; rcfw->pdev = pdev;
@ -567,11 +570,18 @@ int bnxt_qplib_alloc_rcfw_channel(struct pci_dev *pdev,
"HW channel CREQ allocation failed\n"); "HW channel CREQ allocation failed\n");
goto fail; goto fail;
} }
rcfw->cmdq.max_elements = BNXT_QPLIB_CMDQE_MAX_CNT; if (ctx->hwrm_intf_ver < HWRM_VERSION_RCFW_CMDQ_DEPTH_CHECK)
if (bnxt_qplib_alloc_init_hwq(rcfw->pdev, &rcfw->cmdq, NULL, 0, rcfw->cmdq_depth = BNXT_QPLIB_CMDQE_MAX_CNT_256;
&rcfw->cmdq.max_elements, else
BNXT_QPLIB_CMDQE_UNITS, 0, PAGE_SIZE, rcfw->cmdq_depth = BNXT_QPLIB_CMDQE_MAX_CNT_8192;
HWQ_TYPE_CTX)) {
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, dev_err(&rcfw->pdev->dev,
"HW channel CMDQ allocation failed\n"); "HW channel CMDQ allocation failed\n");
goto fail; goto fail;
@ -674,7 +684,7 @@ int bnxt_qplib_enable_rcfw_channel(struct pci_dev *pdev,
/* General */ /* General */
rcfw->seq_num = 0; rcfw->seq_num = 0;
set_bit(FIRMWARE_FIRST_FLAG, &rcfw->flags); 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)); sizeof(unsigned long));
rcfw->cmdq_bitmap = kzalloc(bmap_size, GFP_KERNEL); rcfw->cmdq_bitmap = kzalloc(bmap_size, GFP_KERNEL);
if (!rcfw->cmdq_bitmap) 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_pbl = cpu_to_le64(rcfw->cmdq.pbl[PBL_LVL_0].pg_map_arr[0]);
init.cmdq_size_cmdq_lvl = cpu_to_le16( 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) | CMDQ_INIT_CMDQ_SIZE_MASK) |
((rcfw->cmdq.level << CMDQ_INIT_CMDQ_LVL_SFT) & ((rcfw->cmdq.level << CMDQ_INIT_CMDQ_LVL_SFT) &
CMDQ_INIT_CMDQ_LVL_MASK)); CMDQ_INIT_CMDQ_LVL_MASK));

View File

@ -63,32 +63,60 @@
#define RCFW_CMD_WAIT_TIME_MS 20000 /* 20 Seconds timeout */ #define RCFW_CMD_WAIT_TIME_MS 20000 /* 20 Seconds timeout */
/* CMDQ elements */
#define BNXT_QPLIB_CMDQE_MAX_CNT 256
#define BNXT_QPLIB_CMDQE_UNITS sizeof(struct bnxt_qplib_cmdqe)
#define BNXT_QPLIB_CMDQE_CNT_PER_PG (PAGE_SIZE / 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 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 */ /* Cmdq contains a fix number of a 16-Byte slots */
struct bnxt_qplib_cmdqe { struct bnxt_qplib_cmdqe {
u8 data[16]; u8 data[16];
}; };
static inline u32 get_cmdq_pg(u32 val) /* CMDQ elements */
#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_BYTES(depth) ((depth) * BNXT_QPLIB_CMDQE_UNITS)
static inline u32 bnxt_qplib_cmdqe_npages(u32 depth)
{ {
return (val & ~MAX_CMDQ_IDX_PER_PG) / BNXT_QPLIB_CMDQE_CNT_PER_PG; u32 npages;
npages = BNXT_QPLIB_CMDQE_BYTES(depth) / PAGE_SIZE;
if (BNXT_QPLIB_CMDQE_BYTES(depth) % PAGE_SIZE)
npages++;
return npages;
} }
static inline u32 get_cmdq_idx(u32 val) static inline u32 bnxt_qplib_cmdqe_page_size(u32 depth)
{ {
return val & MAX_CMDQ_IDX_PER_PG; 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(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_COOKIE_VALUE 0x7FFF
#define RCFW_CMD_IS_BLOCKING 0x8000
#define RCFW_BLOCKED_CMD_WAIT_COUNT 0x4E20
#define HWRM_VERSION_RCFW_CMDQ_DEPTH_CHECK 0x1000900020011ULL
static inline u32 get_cmdq_pg(u32 val, u32 depth)
{
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, u32 depth)
{
return val & (bnxt_qplib_max_cmdq_idx_per_pg(depth));
} }
/* Crsq buf is 1024-Byte */ /* Crsq buf is 1024-Byte */
@ -194,11 +222,14 @@ struct bnxt_qplib_rcfw {
struct bnxt_qplib_qp_node *qp_tbl; struct bnxt_qplib_qp_node *qp_tbl;
u64 oos_prev; u64 oos_prev;
u32 init_oos_stats; u32 init_oos_stats;
u32 cmdq_depth;
}; };
void bnxt_qplib_free_rcfw_channel(struct bnxt_qplib_rcfw *rcfw); void bnxt_qplib_free_rcfw_channel(struct bnxt_qplib_rcfw *rcfw);
int bnxt_qplib_alloc_rcfw_channel(struct pci_dev *pdev, 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_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill);
void bnxt_qplib_disable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw); 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, int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector,