Commit 3a4304d8 authored by Chandramohan Akula's avatar Chandramohan Akula Committed by Leon Romanovsky

RDMA/bnxt_re: Refactor the queue index update

The queue index wrap around logic is based on power of 2 size depth.
All queues are created with power of 2 depth. This increases the
memory usage by the driver. This change is required for the next
patches that avoids the power of 2 depth requirement for each of
the queues.

Update the function that increments producer index and consumer
index during wrap around. Also, changes the index handling across
multiple functions.
Signed-off-by: default avatarChandramohan Akula <chandramohan.akula@broadcom.com>
Signed-off-by: default avatarSelvin Xavier <selvin.xavier@broadcom.com>
Link: https://lore.kernel.org/r/1698069803-1787-2-git-send-email-selvin.xavier@broadcom.comSigned-off-by: default avatarLeon Romanovsky <leon@kernel.org>
parent c170d4ff
This diff is collapsed.
...@@ -348,9 +348,21 @@ struct bnxt_qplib_qp { ...@@ -348,9 +348,21 @@ struct bnxt_qplib_qp {
#define CQE_IDX(x) ((x) & CQE_MAX_IDX_PER_PG) #define CQE_IDX(x) ((x) & CQE_MAX_IDX_PER_PG)
#define ROCE_CQE_CMP_V 0 #define ROCE_CQE_CMP_V 0
#define CQE_CMP_VALID(hdr, raw_cons, cp_bit) \ #define CQE_CMP_VALID(hdr, pass) \
(!!((hdr)->cqe_type_toggle & CQ_BASE_TOGGLE) == \ (!!((hdr)->cqe_type_toggle & CQ_BASE_TOGGLE) == \
!((raw_cons) & (cp_bit))) !((pass) & BNXT_QPLIB_FLAG_EPOCH_CONS_MASK))
static inline u32 __bnxt_qplib_get_avail(struct bnxt_qplib_hwq *hwq)
{
int cons, prod, avail;
cons = hwq->cons;
prod = hwq->prod;
avail = cons - prod;
if (cons <= prod)
avail += hwq->depth;
return avail;
}
static inline bool bnxt_qplib_queue_full(struct bnxt_qplib_q *que, static inline bool bnxt_qplib_queue_full(struct bnxt_qplib_q *que,
u8 slots) u8 slots)
...@@ -443,9 +455,9 @@ struct bnxt_qplib_cq { ...@@ -443,9 +455,9 @@ struct bnxt_qplib_cq {
#define NQE_PG(x) (((x) & ~NQE_MAX_IDX_PER_PG) / NQE_CNT_PER_PG) #define NQE_PG(x) (((x) & ~NQE_MAX_IDX_PER_PG) / NQE_CNT_PER_PG)
#define NQE_IDX(x) ((x) & NQE_MAX_IDX_PER_PG) #define NQE_IDX(x) ((x) & NQE_MAX_IDX_PER_PG)
#define NQE_CMP_VALID(hdr, raw_cons, cp_bit) \ #define NQE_CMP_VALID(hdr, pass) \
(!!(le32_to_cpu((hdr)->info63_v[0]) & NQ_BASE_V) == \ (!!(le32_to_cpu((hdr)->info63_v[0]) & NQ_BASE_V) == \
!((raw_cons) & (cp_bit))) !((pass) & BNXT_QPLIB_FLAG_EPOCH_CONS_MASK))
#define BNXT_QPLIB_NQE_MAX_CNT (128 * 1024) #define BNXT_QPLIB_NQE_MAX_CNT (128 * 1024)
......
...@@ -734,17 +734,15 @@ static void bnxt_qplib_service_creq(struct tasklet_struct *t) ...@@ -734,17 +734,15 @@ static void bnxt_qplib_service_creq(struct tasklet_struct *t)
u32 type, budget = CREQ_ENTRY_POLL_BUDGET; u32 type, budget = CREQ_ENTRY_POLL_BUDGET;
struct bnxt_qplib_hwq *hwq = &creq->hwq; struct bnxt_qplib_hwq *hwq = &creq->hwq;
struct creq_base *creqe; struct creq_base *creqe;
u32 sw_cons, raw_cons;
unsigned long flags; unsigned long flags;
u32 num_wakeup = 0; u32 num_wakeup = 0;
u32 hw_polled = 0;
/* Service the CREQ until budget is over */ /* Service the CREQ until budget is over */
spin_lock_irqsave(&hwq->lock, flags); spin_lock_irqsave(&hwq->lock, flags);
raw_cons = hwq->cons;
while (budget > 0) { while (budget > 0) {
sw_cons = HWQ_CMP(raw_cons, hwq); creqe = bnxt_qplib_get_qe(hwq, hwq->cons, NULL);
creqe = bnxt_qplib_get_qe(hwq, sw_cons, NULL); if (!CREQ_CMP_VALID(creqe, creq->creq_db.dbinfo.flags))
if (!CREQ_CMP_VALID(creqe, raw_cons, hwq->max_elements))
break; break;
/* The valid test of the entry must be done first before /* The valid test of the entry must be done first before
* reading any further. * reading any further.
...@@ -775,15 +773,15 @@ static void bnxt_qplib_service_creq(struct tasklet_struct *t) ...@@ -775,15 +773,15 @@ static void bnxt_qplib_service_creq(struct tasklet_struct *t)
type); type);
break; break;
} }
raw_cons++;
budget--; budget--;
hw_polled++;
bnxt_qplib_hwq_incr_cons(hwq->max_elements, &hwq->cons,
1, &creq->creq_db.dbinfo.flags);
} }
if (hwq->cons != raw_cons) { if (hw_polled)
hwq->cons = raw_cons;
bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo,
rcfw->res->cctx, true); rcfw->res->cctx, true);
}
spin_unlock_irqrestore(&hwq->lock, flags); spin_unlock_irqrestore(&hwq->lock, flags);
if (num_wakeup) if (num_wakeup)
wake_up_nr(&rcfw->cmdq.waitq, num_wakeup); wake_up_nr(&rcfw->cmdq.waitq, num_wakeup);
...@@ -1113,6 +1111,7 @@ static int bnxt_qplib_map_creq_db(struct bnxt_qplib_rcfw *rcfw, u32 reg_offt) ...@@ -1113,6 +1111,7 @@ static int bnxt_qplib_map_creq_db(struct bnxt_qplib_rcfw *rcfw, u32 reg_offt)
pdev = rcfw->pdev; pdev = rcfw->pdev;
creq_db = &rcfw->creq.creq_db; creq_db = &rcfw->creq.creq_db;
creq_db->dbinfo.flags = 0;
creq_db->reg.bar_id = RCFW_COMM_CONS_PCI_BAR_REGION; creq_db->reg.bar_id = RCFW_COMM_CONS_PCI_BAR_REGION;
creq_db->reg.bar_base = pci_resource_start(pdev, creq_db->reg.bar_id); creq_db->reg.bar_base = pci_resource_start(pdev, creq_db->reg.bar_id);
if (!creq_db->reg.bar_id) if (!creq_db->reg.bar_id)
......
...@@ -141,9 +141,9 @@ struct bnxt_qplib_crsbe { ...@@ -141,9 +141,9 @@ struct bnxt_qplib_crsbe {
/* Allocate 1 per QP for async error notification for now */ /* Allocate 1 per QP for async error notification for now */
#define BNXT_QPLIB_CREQE_MAX_CNT (64 * 1024) #define BNXT_QPLIB_CREQE_MAX_CNT (64 * 1024)
#define BNXT_QPLIB_CREQE_UNITS 16 /* 16-Bytes per prod unit */ #define BNXT_QPLIB_CREQE_UNITS 16 /* 16-Bytes per prod unit */
#define CREQ_CMP_VALID(hdr, raw_cons, cp_bit) \ #define CREQ_CMP_VALID(hdr, pass) \
(!!((hdr)->v & CREQ_BASE_V) == \ (!!((hdr)->v & CREQ_BASE_V) == \
!((raw_cons) & (cp_bit))) !((pass) & BNXT_QPLIB_FLAG_EPOCH_CONS_MASK))
#define CREQ_ENTRY_POLL_BUDGET 0x100 #define CREQ_ENTRY_POLL_BUDGET 0x100
/* HWQ */ /* HWQ */
......
...@@ -343,7 +343,7 @@ int bnxt_qplib_alloc_init_hwq(struct bnxt_qplib_hwq *hwq, ...@@ -343,7 +343,7 @@ int bnxt_qplib_alloc_init_hwq(struct bnxt_qplib_hwq *hwq,
hwq->cons = 0; hwq->cons = 0;
hwq->pdev = pdev; hwq->pdev = pdev;
hwq->depth = hwq_attr->depth; hwq->depth = hwq_attr->depth;
hwq->max_elements = depth; hwq->max_elements = hwq->depth;
hwq->element_size = stride; hwq->element_size = stride;
hwq->qe_ppg = pg_size / stride; hwq->qe_ppg = pg_size / stride;
/* For direct access to the elements */ /* For direct access to the elements */
......
...@@ -186,6 +186,14 @@ struct bnxt_qplib_db_info { ...@@ -186,6 +186,14 @@ struct bnxt_qplib_db_info {
struct bnxt_qplib_hwq *hwq; struct bnxt_qplib_hwq *hwq;
u32 xid; u32 xid;
u32 max_slot; u32 max_slot;
u32 flags;
};
enum bnxt_qplib_db_info_flags_mask {
BNXT_QPLIB_FLAG_EPOCH_CONS_SHIFT = 0x0UL,
BNXT_QPLIB_FLAG_EPOCH_PROD_SHIFT = 0x1UL,
BNXT_QPLIB_FLAG_EPOCH_CONS_MASK = 0x1UL,
BNXT_QPLIB_FLAG_EPOCH_PROD_MASK = 0x2UL,
}; };
/* Tables */ /* Tables */
...@@ -396,24 +404,34 @@ void bnxt_qplib_unmap_db_bar(struct bnxt_qplib_res *res); ...@@ -396,24 +404,34 @@ void bnxt_qplib_unmap_db_bar(struct bnxt_qplib_res *res);
int bnxt_qplib_determine_atomics(struct pci_dev *dev); int bnxt_qplib_determine_atomics(struct pci_dev *dev);
static inline void bnxt_qplib_hwq_incr_prod(struct bnxt_qplib_hwq *hwq, u32 cnt) static inline void bnxt_qplib_hwq_incr_prod(struct bnxt_qplib_db_info *dbinfo,
struct bnxt_qplib_hwq *hwq, u32 cnt)
{ {
hwq->prod = (hwq->prod + cnt) % hwq->depth; /* move prod and update toggle/epoch if wrap around */
hwq->prod += cnt;
if (hwq->prod >= hwq->depth) {
hwq->prod %= hwq->depth;
dbinfo->flags ^= 1UL << BNXT_QPLIB_FLAG_EPOCH_PROD_SHIFT;
}
} }
static inline void bnxt_qplib_hwq_incr_cons(struct bnxt_qplib_hwq *hwq, static inline void bnxt_qplib_hwq_incr_cons(u32 max_elements, u32 *cons, u32 cnt,
u32 cnt) u32 *dbinfo_flags)
{ {
hwq->cons = (hwq->cons + cnt) % hwq->depth; /* move cons and update toggle/epoch if wrap around */
*cons += cnt;
if (*cons >= max_elements) {
*cons %= max_elements;
*dbinfo_flags ^= 1UL << BNXT_QPLIB_FLAG_EPOCH_CONS_SHIFT;
}
} }
static inline void bnxt_qplib_ring_db32(struct bnxt_qplib_db_info *info, static inline void bnxt_qplib_ring_db32(struct bnxt_qplib_db_info *info,
bool arm) bool arm)
{ {
u32 key; u32 key = 0;
key = info->hwq->cons & (info->hwq->max_elements - 1); key |= info->hwq->cons | (CMPL_DOORBELL_IDX_VALID |
key |= (CMPL_DOORBELL_IDX_VALID |
(CMPL_DOORBELL_KEY_CMPL & CMPL_DOORBELL_KEY_MASK)); (CMPL_DOORBELL_KEY_CMPL & CMPL_DOORBELL_KEY_MASK));
if (!arm) if (!arm)
key |= CMPL_DOORBELL_MASK; key |= CMPL_DOORBELL_MASK;
...@@ -427,8 +445,7 @@ static inline void bnxt_qplib_ring_db(struct bnxt_qplib_db_info *info, ...@@ -427,8 +445,7 @@ static inline void bnxt_qplib_ring_db(struct bnxt_qplib_db_info *info,
key = (info->xid & DBC_DBC_XID_MASK) | DBC_DBC_PATH_ROCE | type; key = (info->xid & DBC_DBC_XID_MASK) | DBC_DBC_PATH_ROCE | type;
key <<= 32; key <<= 32;
key |= (info->hwq->cons & (info->hwq->max_elements - 1)) & key |= (info->hwq->cons & DBC_DBC_INDEX_MASK);
DBC_DBC_INDEX_MASK;
writeq(key, info->db); writeq(key, info->db);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment