Commit 77c6e27d authored by Amit Cohen's avatar Amit Cohen Committed by Jakub Kicinski

mlxsw: pci: Store DQ pointer as part of CQ structure

Currently, for each completion, we check the number of descriptor queue
and take it via mlxsw_pci_{sdq,rdq}_get(). This is inefficient, the
DQ should be the same for all the completions in CQ, as each CQ handles
only one DQ - SDQ or RDQ. This mapping is handled as part of DQ
initialization via mlxsw_cmd_mbox_sw2hw_dq_cq_set().

Instead, as part of DQ initialization, set DQ pointer in the appropriate
CQ structure. When we handle completions, warn in case that the DQ number
that we expect is different from the number we get in the CQE. Call
WARN_ON_ONCE() only after checking the value, to avoid calling this method
for each completion.
Signed-off-by: default avatarAmit Cohen <amcohen@nvidia.com>
Reviewed-by: default avatarIdo Schimmel <idosch@nvidia.com>
Signed-off-by: default avatarPetr Machata <petrm@nvidia.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Link: https://lore.kernel.org/r/a5b2559cd6d532c120f3194f89a1e257110318f1.1712062203.git.petrm@nvidia.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 82238f0d
...@@ -86,6 +86,7 @@ struct mlxsw_pci_queue { ...@@ -86,6 +86,7 @@ struct mlxsw_pci_queue {
struct mlxsw_pci *pci; struct mlxsw_pci *pci;
struct { struct {
enum mlxsw_pci_cqe_v v; enum mlxsw_pci_cqe_v v;
struct mlxsw_pci_queue *dq;
} cq; } cq;
}; };
...@@ -194,13 +195,6 @@ static struct mlxsw_pci_queue *mlxsw_pci_sdq_get(struct mlxsw_pci *mlxsw_pci, ...@@ -194,13 +195,6 @@ static struct mlxsw_pci_queue *mlxsw_pci_sdq_get(struct mlxsw_pci *mlxsw_pci,
MLXSW_PCI_QUEUE_TYPE_SDQ, q_num); MLXSW_PCI_QUEUE_TYPE_SDQ, q_num);
} }
static struct mlxsw_pci_queue *mlxsw_pci_rdq_get(struct mlxsw_pci *mlxsw_pci,
u8 q_num)
{
return __mlxsw_pci_queue_get(mlxsw_pci,
MLXSW_PCI_QUEUE_TYPE_RDQ, q_num);
}
static struct mlxsw_pci_queue *mlxsw_pci_cq_get(struct mlxsw_pci *mlxsw_pci, static struct mlxsw_pci_queue *mlxsw_pci_cq_get(struct mlxsw_pci *mlxsw_pci,
u8 q_num) u8 q_num)
{ {
...@@ -265,7 +259,9 @@ static dma_addr_t __mlxsw_pci_queue_page_get(struct mlxsw_pci_queue *q, ...@@ -265,7 +259,9 @@ static dma_addr_t __mlxsw_pci_queue_page_get(struct mlxsw_pci_queue *q,
static int mlxsw_pci_sdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox, static int mlxsw_pci_sdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
struct mlxsw_pci_queue *q) struct mlxsw_pci_queue *q)
{ {
struct mlxsw_pci_queue *cq;
int tclass; int tclass;
u8 cq_num;
int lp; int lp;
int i; int i;
int err; int err;
...@@ -278,7 +274,8 @@ static int mlxsw_pci_sdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox, ...@@ -278,7 +274,8 @@ static int mlxsw_pci_sdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
MLXSW_CMD_MBOX_SW2HW_DQ_SDQ_LP_WQE; MLXSW_CMD_MBOX_SW2HW_DQ_SDQ_LP_WQE;
/* Set CQ of same number of this SDQ. */ /* Set CQ of same number of this SDQ. */
mlxsw_cmd_mbox_sw2hw_dq_cq_set(mbox, q->num); cq_num = q->num;
mlxsw_cmd_mbox_sw2hw_dq_cq_set(mbox, cq_num);
mlxsw_cmd_mbox_sw2hw_dq_sdq_lp_set(mbox, lp); mlxsw_cmd_mbox_sw2hw_dq_sdq_lp_set(mbox, lp);
mlxsw_cmd_mbox_sw2hw_dq_sdq_tclass_set(mbox, tclass); mlxsw_cmd_mbox_sw2hw_dq_sdq_tclass_set(mbox, tclass);
mlxsw_cmd_mbox_sw2hw_dq_log2_dq_sz_set(mbox, 3); /* 8 pages */ mlxsw_cmd_mbox_sw2hw_dq_log2_dq_sz_set(mbox, 3); /* 8 pages */
...@@ -291,6 +288,9 @@ static int mlxsw_pci_sdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox, ...@@ -291,6 +288,9 @@ static int mlxsw_pci_sdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
err = mlxsw_cmd_sw2hw_sdq(mlxsw_pci->core, mbox, q->num); err = mlxsw_cmd_sw2hw_sdq(mlxsw_pci->core, mbox, q->num);
if (err) if (err)
return err; return err;
cq = mlxsw_pci_cq_get(mlxsw_pci, cq_num);
cq->cq.dq = q;
mlxsw_pci_queue_doorbell_producer_ring(mlxsw_pci, q); mlxsw_pci_queue_doorbell_producer_ring(mlxsw_pci, q);
return 0; return 0;
} }
...@@ -374,6 +374,8 @@ static int mlxsw_pci_rdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox, ...@@ -374,6 +374,8 @@ static int mlxsw_pci_rdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
{ {
struct mlxsw_pci_queue_elem_info *elem_info; struct mlxsw_pci_queue_elem_info *elem_info;
u8 sdq_count = mlxsw_pci->num_sdqs; u8 sdq_count = mlxsw_pci->num_sdqs;
struct mlxsw_pci_queue *cq;
u8 cq_num;
int i; int i;
int err; int err;
...@@ -383,7 +385,8 @@ static int mlxsw_pci_rdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox, ...@@ -383,7 +385,8 @@ static int mlxsw_pci_rdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
/* Set CQ of same number of this RDQ with base /* Set CQ of same number of this RDQ with base
* above SDQ count as the lower ones are assigned to SDQs. * above SDQ count as the lower ones are assigned to SDQs.
*/ */
mlxsw_cmd_mbox_sw2hw_dq_cq_set(mbox, sdq_count + q->num); cq_num = sdq_count + q->num;
mlxsw_cmd_mbox_sw2hw_dq_cq_set(mbox, cq_num);
mlxsw_cmd_mbox_sw2hw_dq_log2_dq_sz_set(mbox, 3); /* 8 pages */ mlxsw_cmd_mbox_sw2hw_dq_log2_dq_sz_set(mbox, 3); /* 8 pages */
for (i = 0; i < MLXSW_PCI_AQ_PAGES; i++) { for (i = 0; i < MLXSW_PCI_AQ_PAGES; i++) {
dma_addr_t mapaddr = __mlxsw_pci_queue_page_get(q, i); dma_addr_t mapaddr = __mlxsw_pci_queue_page_get(q, i);
...@@ -395,6 +398,9 @@ static int mlxsw_pci_rdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox, ...@@ -395,6 +398,9 @@ static int mlxsw_pci_rdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
if (err) if (err)
return err; return err;
cq = mlxsw_pci_cq_get(mlxsw_pci, cq_num);
cq->cq.dq = q;
mlxsw_pci_queue_doorbell_producer_ring(mlxsw_pci, q); mlxsw_pci_queue_doorbell_producer_ring(mlxsw_pci, q);
for (i = 0; i < q->count; i++) { for (i = 0; i < q->count; i++) {
...@@ -415,6 +421,7 @@ static int mlxsw_pci_rdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox, ...@@ -415,6 +421,7 @@ static int mlxsw_pci_rdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
elem_info = mlxsw_pci_queue_elem_info_get(q, i); elem_info = mlxsw_pci_queue_elem_info_get(q, i);
mlxsw_pci_rdq_skb_free(mlxsw_pci, elem_info); mlxsw_pci_rdq_skb_free(mlxsw_pci, elem_info);
} }
cq->cq.dq = NULL;
mlxsw_cmd_hw2sw_rdq(mlxsw_pci->core, q->num); mlxsw_cmd_hw2sw_rdq(mlxsw_pci->core, q->num);
return err; return err;
...@@ -648,6 +655,7 @@ static char *mlxsw_pci_cq_sw_cqe_get(struct mlxsw_pci_queue *q) ...@@ -648,6 +655,7 @@ static char *mlxsw_pci_cq_sw_cqe_get(struct mlxsw_pci_queue *q)
static void mlxsw_pci_cq_rx_tasklet(struct tasklet_struct *t) static void mlxsw_pci_cq_rx_tasklet(struct tasklet_struct *t)
{ {
struct mlxsw_pci_queue *q = from_tasklet(q, t, tasklet); struct mlxsw_pci_queue *q = from_tasklet(q, t, tasklet);
struct mlxsw_pci_queue *rdq = q->cq.dq;
struct mlxsw_pci *mlxsw_pci = q->pci; struct mlxsw_pci *mlxsw_pci = q->pci;
int credits = q->count >> 1; int credits = q->count >> 1;
int items = 0; int items = 0;
...@@ -658,17 +666,20 @@ static void mlxsw_pci_cq_rx_tasklet(struct tasklet_struct *t) ...@@ -658,17 +666,20 @@ static void mlxsw_pci_cq_rx_tasklet(struct tasklet_struct *t)
u8 sendq = mlxsw_pci_cqe_sr_get(q->cq.v, cqe); u8 sendq = mlxsw_pci_cqe_sr_get(q->cq.v, cqe);
u8 dqn = mlxsw_pci_cqe_dqn_get(q->cq.v, cqe); u8 dqn = mlxsw_pci_cqe_dqn_get(q->cq.v, cqe);
char ncqe[MLXSW_PCI_CQE_SIZE_MAX]; char ncqe[MLXSW_PCI_CQE_SIZE_MAX];
struct mlxsw_pci_queue *rdq;
if (unlikely(sendq)) { if (unlikely(sendq)) {
WARN_ON_ONCE(1); WARN_ON_ONCE(1);
continue; continue;
} }
if (unlikely(dqn != rdq->num)) {
WARN_ON_ONCE(1);
continue;
}
memcpy(ncqe, cqe, q->elem_size); memcpy(ncqe, cqe, q->elem_size);
mlxsw_pci_queue_doorbell_consumer_ring(mlxsw_pci, q); mlxsw_pci_queue_doorbell_consumer_ring(mlxsw_pci, q);
rdq = mlxsw_pci_rdq_get(mlxsw_pci, dqn);
mlxsw_pci_cqe_rdq_handle(mlxsw_pci, rdq, mlxsw_pci_cqe_rdq_handle(mlxsw_pci, rdq,
wqe_counter, q->cq.v, ncqe); wqe_counter, q->cq.v, ncqe);
...@@ -682,6 +693,7 @@ static void mlxsw_pci_cq_rx_tasklet(struct tasklet_struct *t) ...@@ -682,6 +693,7 @@ static void mlxsw_pci_cq_rx_tasklet(struct tasklet_struct *t)
static void mlxsw_pci_cq_tx_tasklet(struct tasklet_struct *t) static void mlxsw_pci_cq_tx_tasklet(struct tasklet_struct *t)
{ {
struct mlxsw_pci_queue *q = from_tasklet(q, t, tasklet); struct mlxsw_pci_queue *q = from_tasklet(q, t, tasklet);
struct mlxsw_pci_queue *sdq = q->cq.dq;
struct mlxsw_pci *mlxsw_pci = q->pci; struct mlxsw_pci *mlxsw_pci = q->pci;
int credits = q->count >> 1; int credits = q->count >> 1;
int items = 0; int items = 0;
...@@ -692,17 +704,20 @@ static void mlxsw_pci_cq_tx_tasklet(struct tasklet_struct *t) ...@@ -692,17 +704,20 @@ static void mlxsw_pci_cq_tx_tasklet(struct tasklet_struct *t)
u8 sendq = mlxsw_pci_cqe_sr_get(q->cq.v, cqe); u8 sendq = mlxsw_pci_cqe_sr_get(q->cq.v, cqe);
u8 dqn = mlxsw_pci_cqe_dqn_get(q->cq.v, cqe); u8 dqn = mlxsw_pci_cqe_dqn_get(q->cq.v, cqe);
char ncqe[MLXSW_PCI_CQE_SIZE_MAX]; char ncqe[MLXSW_PCI_CQE_SIZE_MAX];
struct mlxsw_pci_queue *sdq;
if (unlikely(!sendq)) { if (unlikely(!sendq)) {
WARN_ON_ONCE(1); WARN_ON_ONCE(1);
continue; continue;
} }
if (unlikely(dqn != sdq->num)) {
WARN_ON_ONCE(1);
continue;
}
memcpy(ncqe, cqe, q->elem_size); memcpy(ncqe, cqe, q->elem_size);
mlxsw_pci_queue_doorbell_consumer_ring(mlxsw_pci, q); mlxsw_pci_queue_doorbell_consumer_ring(mlxsw_pci, q);
sdq = mlxsw_pci_sdq_get(mlxsw_pci, dqn);
mlxsw_pci_cqe_sdq_handle(mlxsw_pci, sdq, mlxsw_pci_cqe_sdq_handle(mlxsw_pci, sdq,
wqe_counter, q->cq.v, ncqe); wqe_counter, q->cq.v, ncqe);
......
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