From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 1360CA00BE for ; Tue, 7 Jul 2020 09:13:01 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id F39E51DADA; Tue, 7 Jul 2020 09:13:00 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id DEFDF1DADA for ; Tue, 7 Jul 2020 09:12:59 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from viacheslavo@mellanox.com) with SMTP; 7 Jul 2020 10:12:55 +0300 Received: from pegasus12.mtr.labs.mlnx (pegasus12.mtr.labs.mlnx [10.210.17.40]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 0677CtGl017910; Tue, 7 Jul 2020 10:12:55 +0300 Received: from pegasus12.mtr.labs.mlnx (localhost [127.0.0.1]) by pegasus12.mtr.labs.mlnx (8.14.7/8.14.7) with ESMTP id 0677Cttr014780; Tue, 7 Jul 2020 07:12:55 GMT Received: (from viacheslavo@localhost) by pegasus12.mtr.labs.mlnx (8.14.7/8.14.7/Submit) id 0677Ct5j014779; Tue, 7 Jul 2020 07:12:55 GMT X-Authentication-Warning: pegasus12.mtr.labs.mlnx: viacheslavo set sender to viacheslavo@mellanox.com using -f From: Viacheslav Ovsiienko To: stable@dpdk.org Cc: ktraynor@redhat.com, Yongseok Koh Date: Tue, 7 Jul 2020 07:12:51 +0000 Message-Id: <1594105971-14738-3-git-send-email-viacheslavo@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1594105971-14738-1-git-send-email-viacheslavo@mellanox.com> References: <1594105971-14738-1-git-send-email-viacheslavo@mellanox.com> Subject: [dpdk-stable] [PATCH v2 3/3] [18.11] net/mlx4: remove device register remap X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: stable-bounces@dpdk.org Sender: "stable" From: Yongseok Koh UAR (User Access Region) register does not need to be remapped for primary process but it should be remapped only for secondary process. UAR register table is in the process private structure in rte_eth_devices[], (struct mlx4_proc_priv *)rte_eth_devices[port_id].process_private The actual UAR table follows the data structure and the table is used for both Tx and Rx. For Tx, BlueFlame in UAR is used to ring the doorbell. MLX4_TX_BFREG(txq) is defined to get a register for the txq. Processes access its own private data to acquire the register from the UAR table. For Rx, the doorbell in UAR is required in arming CQ event. However, it is a known issue that the register isn't remapped for secondary process. Signed-off-by: Yongseok Koh Signed-off-by: Viacheslav Ovsiienko Acked-by: Shahaf Shuler --- drivers/net/mlx4/mlx4.c | 58 +++++++++++++++++++++++++++++++++++++++++++- drivers/net/mlx4/mlx4.h | 11 +++++++++ drivers/net/mlx4/mlx4_prm.h | 3 ++- drivers/net/mlx4/mlx4_rxtx.c | 2 +- drivers/net/mlx4/mlx4_rxtx.h | 4 +++ drivers/net/mlx4/mlx4_txq.c | 20 +++++++++++++++ 6 files changed, 95 insertions(+), 3 deletions(-) diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c index 975df9b..5e22ee4 100644 --- a/drivers/net/mlx4/mlx4.c +++ b/drivers/net/mlx4/mlx4.c @@ -74,6 +74,53 @@ struct mlx4_conf { static void mlx4_dev_stop(struct rte_eth_dev *dev); /** + * Initialize process private data structure. + * + * @param dev + * Pointer to Ethernet device structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx4_proc_priv_init(struct rte_eth_dev *dev) +{ + struct mlx4_proc_priv *ppriv; + size_t ppriv_size; + + /* + * UAR register table follows the process private structure. BlueFlame + * registers for Tx queues are stored in the table. + */ + ppriv_size = sizeof(struct mlx4_proc_priv) + + RTE_MAX_QUEUES_PER_PORT * sizeof(void *); + ppriv = rte_malloc_socket("mlx4_proc_priv", ppriv_size, + RTE_CACHE_LINE_SIZE, dev->device->numa_node); + if (!ppriv) { + rte_errno = ENOMEM; + return -rte_errno; + } + ppriv->uar_table_sz = ppriv_size; + dev->process_private = ppriv; + return 0; +} + +/** + * Un-initialize process private data structure. + * + * @param dev + * Pointer to Ethernet device structure. + */ +static void +mlx4_proc_priv_uninit(struct rte_eth_dev *dev) +{ + if (!dev->process_private) + return; + rte_free(dev->process_private); + dev->process_private = NULL; +} + +/** * DPDK callback for Ethernet device configuration. * * @param dev @@ -99,9 +146,17 @@ struct mlx4_conf { goto exit; } ret = mlx4_intr_install(priv); - if (ret) + if (ret) { ERROR("%p: interrupt handler installation failed", (void *)dev); + goto exit; + } + ret = mlx4_proc_priv_init(dev); + if (ret) { + ERROR("%p: process private data allocation failed", + (void *)dev); + goto exit; + } exit: return ret; } @@ -213,6 +268,7 @@ struct mlx4_conf { mlx4_rx_queue_release(dev->data->rx_queues[i]); for (i = 0; i != dev->data->nb_tx_queues; ++i) mlx4_tx_queue_release(dev->data->tx_queues[i]); + mlx4_proc_priv_uninit(dev); mlx4_mr_release(dev); if (priv->pd != NULL) { assert(priv->ctx != NULL); diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h index 758b7aa..8454a5f 100644 --- a/drivers/net/mlx4/mlx4.h +++ b/drivers/net/mlx4/mlx4.h @@ -75,6 +75,17 @@ enum { LIST_HEAD(mlx4_dev_list, mlx4_priv); LIST_HEAD(mlx4_mr_list, mlx4_mr); +/* Per-process private structure. */ +struct mlx4_proc_priv { + size_t uar_table_sz; + /* Size of UAR register table. */ + void *uar_table[]; + /* Table of UAR registers for each process. */ +}; + +#define MLX4_PROC_PRIV(port_id) \ + ((struct mlx4_proc_priv *)rte_eth_devices[port_id].process_private) + /** Private data structure. */ struct mlx4_priv { LIST_ENTRY(mlx4_priv) mem_event_cb; diff --git a/drivers/net/mlx4/mlx4_prm.h b/drivers/net/mlx4/mlx4_prm.h index aef77ba..16ae6db 100644 --- a/drivers/net/mlx4/mlx4_prm.h +++ b/drivers/net/mlx4/mlx4_prm.h @@ -77,7 +77,8 @@ struct mlx4_sq { uint32_t owner_opcode; /**< Default owner opcode with HW valid owner bit. */ uint32_t stamp; /**< Stamp value with an invalid HW owner bit. */ - volatile uint32_t *db; /**< Pointer to the doorbell. */ + uint32_t *db; /**< Pointer to the doorbell. */ + off_t uar_mmap_offset; /* UAR mmap offset for non-primary process. */ uint32_t doorbell_qpn; /**< qp number to write to the doorbell. */ }; diff --git a/drivers/net/mlx4/mlx4_rxtx.c b/drivers/net/mlx4/mlx4_rxtx.c index 8c88eff..d5290162 100644 --- a/drivers/net/mlx4/mlx4_rxtx.c +++ b/drivers/net/mlx4/mlx4_rxtx.c @@ -1048,7 +1048,7 @@ struct tso_info { /* Make sure that descriptors are written before doorbell record. */ rte_wmb(); /* Ring QP doorbell. */ - rte_write32(txq->msq.doorbell_qpn, txq->msq.db); + rte_write32(txq->msq.doorbell_qpn, MLX4_TX_BFREG(txq)); txq->elts_head += i; return i; } diff --git a/drivers/net/mlx4/mlx4_rxtx.h b/drivers/net/mlx4/mlx4_rxtx.h index baf0cd7..7a7cc36 100644 --- a/drivers/net/mlx4/mlx4_rxtx.h +++ b/drivers/net/mlx4/mlx4_rxtx.h @@ -97,6 +97,7 @@ struct mlx4_txq_stats { struct txq { struct mlx4_sq msq; /**< Info for directly manipulating the SQ. */ struct mlx4_cq mcq; /**< Info for directly manipulating the CQ. */ + uint16_t port_id; /**< Port ID of device. */ unsigned int elts_head; /**< Current index in (*elts)[]. */ unsigned int elts_tail; /**< First element awaiting completion. */ int elts_comp_cd; /**< Countdown for next completion. */ @@ -118,6 +119,9 @@ struct txq { uint8_t data[]; /**< Remaining queue resources. */ }; +#define MLX4_TX_BFREG(txq) \ + (MLX4_PROC_PRIV((txq)->port_id)->uar_table[(txq)->stats.idx]) + /* mlx4_rxq.c */ extern uint8_t mlx4_rss_hash_key_default[MLX4_RSS_HASH_KEY_SIZE]; diff --git a/drivers/net/mlx4/mlx4_txq.c b/drivers/net/mlx4/mlx4_txq.c index 3527008..92c9c03 100644 --- a/drivers/net/mlx4/mlx4_txq.c +++ b/drivers/net/mlx4/mlx4_txq.c @@ -38,6 +38,23 @@ #include "mlx4_utils.h" /** + * Initialize Tx UAR registers for primary process. + * + * @param txq + * Pointer to Tx queue structure. + */ +static void +txq_uar_init(struct txq *txq) +{ + struct mlx4_priv *priv = txq->priv; + struct mlx4_proc_priv *ppriv = MLX4_PROC_PRIV(PORT_ID(priv)); + + assert(rte_eal_process_type() == RTE_PROC_PRIMARY); + assert(ppriv); + ppriv->uar_table[txq->stats.idx] = txq->msq.db; +} + +/** * Free Tx queue elements. * * @param txq @@ -89,6 +106,7 @@ sq->owner_opcode = MLX4_OPCODE_SEND | (0u << MLX4_SQ_OWNER_BIT); sq->stamp = rte_cpu_to_be_32(MLX4_SQ_STAMP_VAL | (0u << MLX4_SQ_OWNER_BIT)); + sq->uar_mmap_offset = -1; /* Make mmap() fail. */ sq->db = dqp->sdb; sq->doorbell_qpn = dqp->doorbell_qpn; cq->buf = dcq->buf.buf; @@ -214,6 +232,7 @@ } *txq = (struct txq){ .priv = priv, + .port_id = dev->data->port_id, .stats = { .idx = idx, }, @@ -319,6 +338,7 @@ goto error; } mlx4_txq_fill_dv_obj_info(txq, &mlxdv); + txq_uar_init(txq); /* Save first wqe pointer in the first element. */ (&(*txq->elts)[0])->wqe = (volatile struct mlx4_wqe_ctrl_seg *)txq->msq.buf; -- 1.8.3.1