]> www.infradead.org Git - nvme.git/commitdiff
mlxsw: pci: Store DQ pointer as part of CQ structure
authorAmit Cohen <amcohen@nvidia.com>
Tue, 2 Apr 2024 13:54:28 +0000 (15:54 +0200)
committerJakub Kicinski <kuba@kernel.org>
Thu, 4 Apr 2024 02:50:41 +0000 (19:50 -0700)
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: Amit Cohen <amcohen@nvidia.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Petr Machata <petrm@nvidia.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://lore.kernel.org/r/a5b2559cd6d532c120f3194f89a1e257110318f1.1712062203.git.petrm@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/mellanox/mlxsw/pci.c

index 094b9d752a02ee207d8672ed69ba6a8437832235..4d617057af25cf1d0e59894ff805a239424aaf11 100644 (file)
@@ -86,6 +86,7 @@ struct mlxsw_pci_queue {
        struct mlxsw_pci *pci;
        struct {
                enum mlxsw_pci_cqe_v v;
+               struct mlxsw_pci_queue *dq;
        } cq;
 };
 
@@ -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);
 }
 
-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,
                                                u8 q_num)
 {
@@ -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,
                              struct mlxsw_pci_queue *q)
 {
+       struct mlxsw_pci_queue *cq;
        int tclass;
+       u8 cq_num;
        int lp;
        int i;
        int err;
@@ -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;
 
        /* 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_tclass_set(mbox, tclass);
        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,
        err = mlxsw_cmd_sw2hw_sdq(mlxsw_pci->core, mbox, q->num);
        if (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);
        return 0;
 }
@@ -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;
        u8 sdq_count = mlxsw_pci->num_sdqs;
+       struct mlxsw_pci_queue *cq;
+       u8 cq_num;
        int i;
        int err;
 
@@ -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
         * 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 */
        for (i = 0; i < MLXSW_PCI_AQ_PAGES; 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,
        if (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);
 
        for (i = 0; i < q->count; i++) {
@@ -415,6 +421,7 @@ rollback:
                elem_info = mlxsw_pci_queue_elem_info_get(q, i);
                mlxsw_pci_rdq_skb_free(mlxsw_pci, elem_info);
        }
+       cq->cq.dq = NULL;
        mlxsw_cmd_hw2sw_rdq(mlxsw_pci->core, q->num);
 
        return err;
@@ -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)
 {
        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;
        int credits = q->count >> 1;
        int items = 0;
@@ -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 dqn = mlxsw_pci_cqe_dqn_get(q->cq.v, cqe);
                char ncqe[MLXSW_PCI_CQE_SIZE_MAX];
-               struct mlxsw_pci_queue *rdq;
 
                if (unlikely(sendq)) {
                        WARN_ON_ONCE(1);
                        continue;
                }
 
+               if (unlikely(dqn != rdq->num)) {
+                       WARN_ON_ONCE(1);
+                       continue;
+               }
+
                memcpy(ncqe, cqe, q->elem_size);
                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,
                                         wqe_counter, q->cq.v, ncqe);
 
@@ -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)
 {
        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;
        int credits = q->count >> 1;
        int items = 0;
@@ -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 dqn = mlxsw_pci_cqe_dqn_get(q->cq.v, cqe);
                char ncqe[MLXSW_PCI_CQE_SIZE_MAX];
-               struct mlxsw_pci_queue *sdq;
 
                if (unlikely(!sendq)) {
                        WARN_ON_ONCE(1);
                        continue;
                }
 
+               if (unlikely(dqn != sdq->num)) {
+                       WARN_ON_ONCE(1);
+                       continue;
+               }
+
                memcpy(ncqe, cqe, q->elem_size);
                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,
                                         wqe_counter, q->cq.v, ncqe);