RDMA/bnxt_re: Refactor notification queue management code

Cleaning up the notification queue data structures and management
code. The CQ and SRQ event handlers have been type defined instead of
in-place declaration. NQ doorbell register descriptor has been added in
base NQ structure.  The nq->vector has been renamed to nq->msix_vec.

Link: https://lore.kernel.org/r/1581786665-23705-7-git-send-email-devesh.sharma@broadcom.com
Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:
Devesh Sharma 2020-02-15 12:11:03 -05:00 committed by Jason Gunthorpe
parent cee0c7bba4
commit 9555352bac
2 changed files with 93 additions and 73 deletions

View File

@ -236,16 +236,16 @@ fail:
static void bnxt_qplib_service_nq(unsigned long data) static void bnxt_qplib_service_nq(unsigned long data)
{ {
struct bnxt_qplib_nq *nq = (struct bnxt_qplib_nq *)data; struct bnxt_qplib_nq *nq = (struct bnxt_qplib_nq *)data;
bool gen_p5 = bnxt_qplib_is_chip_gen_p5(nq->res->cctx);
struct bnxt_qplib_hwq *hwq = &nq->hwq; struct bnxt_qplib_hwq *hwq = &nq->hwq;
struct nq_base *nqe, **nq_ptr; struct nq_base *nqe, **nq_ptr;
struct bnxt_qplib_cq *cq; struct bnxt_qplib_cq *cq;
int num_cqne_processed = 0; int num_cqne_processed = 0;
int num_srqne_processed = 0; int num_srqne_processed = 0;
u32 sw_cons, raw_cons;
u16 type;
int budget = nq->budget; int budget = nq->budget;
u32 sw_cons, raw_cons;
uintptr_t q_handle; uintptr_t q_handle;
bool gen_p5 = bnxt_qplib_is_chip_gen_p5(nq->res->cctx); u16 type;
/* Service the NQ until empty */ /* Service the NQ until empty */
raw_cons = hwq->cons; raw_cons = hwq->cons;
@ -314,7 +314,7 @@ static void bnxt_qplib_service_nq(unsigned long data)
} }
if (hwq->cons != raw_cons) { if (hwq->cons != raw_cons) {
hwq->cons = raw_cons; hwq->cons = raw_cons;
bnxt_qplib_ring_nq_db_rearm(nq->bar_reg_iomem, hwq->cons, bnxt_qplib_ring_nq_db_rearm(nq->nq_db.db, hwq->cons,
hwq->max_elements, nq->ring_id, hwq->max_elements, nq->ring_id,
gen_p5); gen_p5);
} }
@ -333,7 +333,7 @@ static irqreturn_t bnxt_qplib_nq_irq(int irq, void *dev_instance)
prefetch(&nq_ptr[NQE_PG(sw_cons)][NQE_IDX(sw_cons)]); prefetch(&nq_ptr[NQE_PG(sw_cons)][NQE_IDX(sw_cons)]);
/* Fan out to CPU affinitized kthreads? */ /* Fan out to CPU affinitized kthreads? */
tasklet_schedule(&nq->worker); tasklet_schedule(&nq->nq_tasklet);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
@ -341,17 +341,17 @@ static irqreturn_t bnxt_qplib_nq_irq(int irq, void *dev_instance)
void bnxt_qplib_nq_stop_irq(struct bnxt_qplib_nq *nq, bool kill) void bnxt_qplib_nq_stop_irq(struct bnxt_qplib_nq *nq, bool kill)
{ {
bool gen_p5 = bnxt_qplib_is_chip_gen_p5(nq->res->cctx); bool gen_p5 = bnxt_qplib_is_chip_gen_p5(nq->res->cctx);
tasklet_disable(&nq->worker); tasklet_disable(&nq->nq_tasklet);
/* Mask h/w interrupt */ /* Mask h/w interrupt */
bnxt_qplib_ring_nq_db(nq->bar_reg_iomem, nq->hwq.cons, bnxt_qplib_ring_nq_db(nq->nq_db.db, nq->hwq.cons,
nq->hwq.max_elements, nq->ring_id, gen_p5); nq->hwq.max_elements, nq->ring_id, gen_p5);
/* Sync with last running IRQ handler */ /* Sync with last running IRQ handler */
synchronize_irq(nq->vector); synchronize_irq(nq->msix_vec);
if (kill) if (kill)
tasklet_kill(&nq->worker); tasklet_kill(&nq->nq_tasklet);
if (nq->requested) { if (nq->requested) {
irq_set_affinity_hint(nq->vector, NULL); irq_set_affinity_hint(nq->msix_vec, NULL);
free_irq(nq->vector, nq); free_irq(nq->msix_vec, nq);
nq->requested = false; nq->requested = false;
} }
} }
@ -364,16 +364,17 @@ void bnxt_qplib_disable_nq(struct bnxt_qplib_nq *nq)
} }
/* Make sure the HW is stopped! */ /* Make sure the HW is stopped! */
if (nq->requested) bnxt_qplib_nq_stop_irq(nq, true);
bnxt_qplib_nq_stop_irq(nq, true);
if (nq->bar_reg_iomem) if (nq->nq_db.reg.bar_reg) {
iounmap(nq->bar_reg_iomem); iounmap(nq->nq_db.reg.bar_reg);
nq->bar_reg_iomem = NULL; nq->nq_db.reg.bar_reg = NULL;
nq->nq_db.db = NULL;
}
nq->cqn_handler = NULL; nq->cqn_handler = NULL;
nq->srqn_handler = NULL; nq->srqn_handler = NULL;
nq->vector = 0; nq->msix_vec = 0;
} }
int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx, int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx,
@ -385,68 +386,87 @@ int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx,
if (nq->requested) if (nq->requested)
return -EFAULT; return -EFAULT;
nq->vector = msix_vector; nq->msix_vec = msix_vector;
if (need_init) if (need_init)
tasklet_init(&nq->worker, bnxt_qplib_service_nq, tasklet_init(&nq->nq_tasklet, bnxt_qplib_service_nq,
(unsigned long)nq); (unsigned long)nq);
else else
tasklet_enable(&nq->worker); tasklet_enable(&nq->nq_tasklet);
snprintf(nq->name, sizeof(nq->name), "bnxt_qplib_nq-%d", nq_indx); snprintf(nq->name, sizeof(nq->name), "bnxt_qplib_nq-%d", nq_indx);
rc = request_irq(nq->vector, bnxt_qplib_nq_irq, 0, nq->name, nq); rc = request_irq(nq->msix_vec, bnxt_qplib_nq_irq, 0, nq->name, nq);
if (rc) if (rc)
return rc; return rc;
cpumask_clear(&nq->mask); cpumask_clear(&nq->mask);
cpumask_set_cpu(nq_indx, &nq->mask); cpumask_set_cpu(nq_indx, &nq->mask);
rc = irq_set_affinity_hint(nq->vector, &nq->mask); rc = irq_set_affinity_hint(nq->msix_vec, &nq->mask);
if (rc) { if (rc) {
dev_warn(&nq->pdev->dev, dev_warn(&nq->pdev->dev,
"set affinity failed; vector: %d nq_idx: %d\n", "set affinity failed; vector: %d nq_idx: %d\n",
nq->vector, nq_indx); nq->msix_vec, nq_indx);
} }
nq->requested = true; nq->requested = true;
bnxt_qplib_ring_nq_db_rearm(nq->bar_reg_iomem, nq->hwq.cons, bnxt_qplib_ring_nq_db_rearm(nq->nq_db.db, nq->hwq.cons,
nq->hwq.max_elements, nq->ring_id, gen_p5); nq->hwq.max_elements, nq->ring_id, gen_p5);
return rc; return rc;
} }
static int bnxt_qplib_map_nq_db(struct bnxt_qplib_nq *nq, u32 reg_offt)
{
resource_size_t reg_base;
struct bnxt_qplib_nq_db *nq_db;
struct pci_dev *pdev;
int rc = 0;
pdev = nq->pdev;
nq_db = &nq->nq_db;
nq_db->reg.bar_id = NQ_CONS_PCI_BAR_REGION;
nq_db->reg.bar_base = pci_resource_start(pdev, nq_db->reg.bar_id);
if (!nq_db->reg.bar_base) {
dev_err(&pdev->dev, "QPLIB: NQ BAR region %d resc start is 0!",
nq_db->reg.bar_id);
rc = -ENOMEM;
goto fail;
}
reg_base = nq_db->reg.bar_base + reg_offt;
/* Unconditionally map 8 bytes to support 57500 series */
nq_db->reg.len = 8;
nq_db->reg.bar_reg = ioremap(reg_base, nq_db->reg.len);
if (!nq_db->reg.bar_reg) {
dev_err(&pdev->dev, "QPLIB: NQ BAR region %d mapping failed",
nq_db->reg.bar_id);
rc = -ENOMEM;
goto fail;
}
nq_db->db = nq_db->reg.bar_reg;
fail:
return rc;
}
int bnxt_qplib_enable_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq, int bnxt_qplib_enable_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq,
int nq_idx, int msix_vector, int bar_reg_offset, int nq_idx, int msix_vector, int bar_reg_offset,
int (*cqn_handler)(struct bnxt_qplib_nq *nq, cqn_handler_t cqn_handler,
struct bnxt_qplib_cq *), srqn_handler_t srqn_handler)
int (*srqn_handler)(struct bnxt_qplib_nq *nq,
struct bnxt_qplib_srq *,
u8 event))
{ {
resource_size_t nq_base;
int rc = -1; int rc = -1;
if (cqn_handler) nq->pdev = pdev;
nq->cqn_handler = cqn_handler; nq->cqn_handler = cqn_handler;
nq->srqn_handler = srqn_handler;
if (srqn_handler)
nq->srqn_handler = srqn_handler;
/* Have a task to schedule CQ notifiers in post send case */ /* Have a task to schedule CQ notifiers in post send case */
nq->cqn_wq = create_singlethread_workqueue("bnxt_qplib_nq"); nq->cqn_wq = create_singlethread_workqueue("bnxt_qplib_nq");
if (!nq->cqn_wq) if (!nq->cqn_wq)
return -ENOMEM; return -ENOMEM;
nq->bar_reg = NQ_CONS_PCI_BAR_REGION; rc = bnxt_qplib_map_nq_db(nq, bar_reg_offset);
nq->bar_reg_off = bar_reg_offset; if (rc)
nq_base = pci_resource_start(pdev, nq->bar_reg);
if (!nq_base) {
rc = -ENOMEM;
goto fail; goto fail;
}
/* Unconditionally map 8 bytes to support 57500 series */
nq->bar_reg_iomem = ioremap(nq_base + nq->bar_reg_off, 8);
if (!nq->bar_reg_iomem) {
rc = -ENOMEM;
goto fail;
}
rc = bnxt_qplib_nq_start_irq(nq, nq_idx, msix_vector, true); rc = bnxt_qplib_nq_start_irq(nq, nq_idx, msix_vector, true);
if (rc) { if (rc) {

View File

@ -470,29 +470,32 @@ static inline void bnxt_qplib_ring_nq_db(void __iomem *db, u32 raw_cons,
writel(NQ_DB_CP_FLAGS | (index & DBC_DBC32_XID_MASK), db); writel(NQ_DB_CP_FLAGS | (index & DBC_DBC32_XID_MASK), db);
} }
struct bnxt_qplib_nq_db {
struct bnxt_qplib_reg_desc reg;
void __iomem *db;
};
typedef int (*cqn_handler_t)(struct bnxt_qplib_nq *nq,
struct bnxt_qplib_cq *cq);
typedef int (*srqn_handler_t)(struct bnxt_qplib_nq *nq,
struct bnxt_qplib_srq *srq, u8 event);
struct bnxt_qplib_nq { struct bnxt_qplib_nq {
struct pci_dev *pdev; struct pci_dev *pdev;
struct bnxt_qplib_res *res; struct bnxt_qplib_res *res;
char name[32];
struct bnxt_qplib_hwq hwq;
struct bnxt_qplib_nq_db nq_db;
u16 ring_id;
int msix_vec;
cpumask_t mask;
struct tasklet_struct nq_tasklet;
bool requested;
int budget;
int vector; cqn_handler_t cqn_handler;
cpumask_t mask; srqn_handler_t srqn_handler;
int budget; struct workqueue_struct *cqn_wq;
bool requested;
struct tasklet_struct worker;
struct bnxt_qplib_hwq hwq;
u16 bar_reg;
u32 bar_reg_off;
u16 ring_id;
void __iomem *bar_reg_iomem;
int (*cqn_handler)(struct bnxt_qplib_nq *nq,
struct bnxt_qplib_cq *cq);
int (*srqn_handler)(struct bnxt_qplib_nq *nq,
struct bnxt_qplib_srq *srq,
u8 event);
struct workqueue_struct *cqn_wq;
char name[32];
}; };
struct bnxt_qplib_nq_work { struct bnxt_qplib_nq_work {
@ -507,11 +510,8 @@ int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx,
int msix_vector, bool need_init); int msix_vector, bool need_init);
int bnxt_qplib_enable_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq, int bnxt_qplib_enable_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq,
int nq_idx, int msix_vector, int bar_reg_offset, int nq_idx, int msix_vector, int bar_reg_offset,
int (*cqn_handler)(struct bnxt_qplib_nq *nq, cqn_handler_t cqn_handler,
struct bnxt_qplib_cq *cq), srqn_handler_t srq_handler);
int (*srqn_handler)(struct bnxt_qplib_nq *nq,
struct bnxt_qplib_srq *srq,
u8 event));
int bnxt_qplib_create_srq(struct bnxt_qplib_res *res, int bnxt_qplib_create_srq(struct bnxt_qplib_res *res,
struct bnxt_qplib_srq *srq); struct bnxt_qplib_srq *srq);
int bnxt_qplib_modify_srq(struct bnxt_qplib_res *res, int bnxt_qplib_modify_srq(struct bnxt_qplib_res *res,