get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/52629/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 52629,
    "url": "http://patches.dpdk.org/api/patches/52629/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20190410184118.39727-4-yskoh@mellanox.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20190410184118.39727-4-yskoh@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20190410184118.39727-4-yskoh@mellanox.com",
    "date": "2019-04-10T18:41:17",
    "name": "[v5,3/4] net/mlx5: remove device register remap",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "1592770f4a7270720ce0267fa88997b843680e64",
    "submitter": {
        "id": 636,
        "url": "http://patches.dpdk.org/api/people/636/?format=api",
        "name": "Yongseok Koh",
        "email": "yskoh@mellanox.com"
    },
    "delegate": {
        "id": 6624,
        "url": "http://patches.dpdk.org/api/users/6624/?format=api",
        "username": "shahafs",
        "first_name": "Shahaf",
        "last_name": "Shuler",
        "email": "shahafs@mellanox.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20190410184118.39727-4-yskoh@mellanox.com/mbox/",
    "series": [
        {
            "id": 4252,
            "url": "http://patches.dpdk.org/api/series/4252/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=4252",
            "date": "2019-04-10T18:41:14",
            "name": "net/mlx: remove device register remap",
            "version": 5,
            "mbox": "http://patches.dpdk.org/series/4252/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/52629/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/52629/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id DDF4F1B443;\n\tWed, 10 Apr 2019 20:41:37 +0200 (CEST)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n\tby dpdk.org (Postfix) with ESMTP id 6A3ED1B42F\n\tfor <dev@dpdk.org>; Wed, 10 Apr 2019 20:41:28 +0200 (CEST)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n\tyskoh@mellanox.com)\n\twith ESMTPS (AES256-SHA encrypted); 10 Apr 2019 21:41:26 +0300",
            "from scfae-sc-2.mti.labs.mlnx (scfae-sc-2.mti.labs.mlnx\n\t[10.101.0.96])\n\tby labmailer.mlnx (8.13.8/8.13.8) with ESMTP id x3AIfKx3002770;\n\tWed, 10 Apr 2019 21:41:25 +0300"
        ],
        "From": "Yongseok Koh <yskoh@mellanox.com>",
        "To": "shahafs@mellanox.com",
        "Cc": "dev@dpdk.org",
        "Date": "Wed, 10 Apr 2019 11:41:17 -0700",
        "Message-Id": "<20190410184118.39727-4-yskoh@mellanox.com>",
        "X-Mailer": "git-send-email 2.11.0",
        "In-Reply-To": "<20190410184118.39727-1-yskoh@mellanox.com>",
        "References": "<20190325193627.19726-1-yskoh@mellanox.com>\n\t<20190410184118.39727-1-yskoh@mellanox.com>",
        "Subject": "[dpdk-dev] [PATCH v5 3/4] net/mlx5: remove device register remap",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "UAR (User Access Region) register does not need to be remapped for primary\nprocess but it should be remapped only for secondary process. UAR register\ntable is in the process private structure in rte_eth_devices[],\n\t(struct mlx5_proc_priv *)rte_eth_devices[port_id].process_private\n\nThe actual UAR table follows the data structure and the table is used for\nboth Tx and Rx.\n\nFor Tx, BlueFlame in UAR is used to ring the doorbell. MLX5_TX_BFREG(txq)\nis defined to get a register for the txq. Processes access its own private\ndata to acquire the register from the UAR table.\n\nFor Rx, the doorbell in UAR is required in arming CQ event. However, it is\na known issue that the register isn't remapped for secondary process.\n\nSigned-off-by: Yongseok Koh <yskoh@mellanox.com>\n---\n drivers/net/mlx5/mlx5.c         | 228 ++++++++++------------------------------\n drivers/net/mlx5/mlx5.h         |  16 ++-\n drivers/net/mlx5/mlx5_defs.h    |  10 --\n drivers/net/mlx5/mlx5_ethdev.c  |   3 +\n drivers/net/mlx5/mlx5_rxtx.h    |  11 +-\n drivers/net/mlx5/mlx5_trigger.c |   6 --\n drivers/net/mlx5/mlx5_txq.c     | 181 +++++++++++++++++++------------\n 7 files changed, 186 insertions(+), 269 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c\nindex 475c93ddf9..9ff50dfbe4 100644\n--- a/drivers/net/mlx5/mlx5.c\n+++ b/drivers/net/mlx5/mlx5.c\n@@ -449,30 +449,6 @@ mlx5_init_shared_data(void)\n }\n \n /**\n- * Uninitialize shared data between primary and secondary process.\n- *\n- * The pointer of secondary process is dereferenced and primary process frees\n- * the memzone.\n- */\n-static void\n-mlx5_uninit_shared_data(void)\n-{\n-\tconst struct rte_memzone *mz;\n-\n-\trte_spinlock_lock(&mlx5_shared_data_lock);\n-\tif (mlx5_shared_data) {\n-\t\tif (rte_eal_process_type() == RTE_PROC_PRIMARY) {\n-\t\t\tmz = rte_memzone_lookup(MZ_MLX5_PMD_SHARED_DATA);\n-\t\t\trte_memzone_free(mz);\n-\t\t} else {\n-\t\t\tmemset(&mlx5_local_data, 0, sizeof(mlx5_local_data));\n-\t\t}\n-\t\tmlx5_shared_data = NULL;\n-\t}\n-\trte_spinlock_unlock(&mlx5_shared_data_lock);\n-}\n-\n-/**\n  * Retrieve integer value from environment variable.\n  *\n  * @param[in] name\n@@ -546,6 +522,54 @@ mlx5_free_verbs_buf(void *ptr, void *data __rte_unused)\n }\n \n /**\n+ * Initialize process private data structure.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_errno is set.\n+ */\n+int\n+mlx5_proc_priv_init(struct rte_eth_dev *dev)\n+{\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct mlx5_proc_priv *ppriv;\n+\tsize_t ppriv_size;\n+\n+\t/*\n+\t * UAR register table follows the process private structure. BlueFlame\n+\t * registers for Tx queues are stored in the table.\n+\t */\n+\tppriv_size =\n+\t\tsizeof(struct mlx5_proc_priv) + priv->txqs_n * sizeof(void *);\n+\tppriv = rte_malloc_socket(\"mlx5_proc_priv\", ppriv_size,\n+\t\t\t\t  RTE_CACHE_LINE_SIZE, dev->device->numa_node);\n+\tif (!ppriv) {\n+\t\trte_errno = ENOMEM;\n+\t\treturn -rte_errno;\n+\t}\n+\tppriv->uar_table_sz = ppriv_size;\n+\tdev->process_private = ppriv;\n+\treturn 0;\n+}\n+\n+/**\n+ * Un-initialize process private data structure.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ */\n+static void\n+mlx5_proc_priv_uninit(struct rte_eth_dev *dev)\n+{\n+\tif (!dev->process_private)\n+\t\treturn;\n+\trte_free(dev->process_private);\n+\tdev->process_private = NULL;\n+}\n+\n+/**\n  * DPDK callback to close the device.\n  *\n  * Destroy all queues and objects, free memory.\n@@ -589,6 +613,7 @@ mlx5_dev_close(struct rte_eth_dev *dev)\n \t\tpriv->txqs_n = 0;\n \t\tpriv->txqs = NULL;\n \t}\n+\tmlx5_proc_priv_uninit(dev);\n \tmlx5_mprq_free_mp(dev);\n \tmlx5_mr_release(dev);\n \tassert(priv->sh);\n@@ -913,132 +938,6 @@ mlx5_args(struct mlx5_dev_config *config, struct rte_devargs *devargs)\n \n static struct rte_pci_driver mlx5_driver;\n \n-static int\n-find_lower_va_bound(const struct rte_memseg_list *msl,\n-\t\tconst struct rte_memseg *ms, void *arg)\n-{\n-\tvoid **addr = arg;\n-\n-\tif (msl->external)\n-\t\treturn 0;\n-\tif (*addr == NULL)\n-\t\t*addr = ms->addr;\n-\telse\n-\t\t*addr = RTE_MIN(*addr, ms->addr);\n-\n-\treturn 0;\n-}\n-\n-/**\n- * Reserve UAR address space for primary process.\n- *\n- * Process local resource is used by both primary and secondary to avoid\n- * duplicate reservation. The space has to be available on both primary and\n- * secondary process, TXQ UAR maps to this area using fixed mmap w/o double\n- * check.\n- *\n- * @return\n- *   0 on success, a negative errno value otherwise and rte_errno is set.\n- */\n-static int\n-mlx5_uar_init_primary(void)\n-{\n-\tstruct mlx5_shared_data *sd = mlx5_shared_data;\n-\tvoid *addr = (void *)0;\n-\n-\tif (sd->uar_base)\n-\t\treturn 0;\n-\t/* find out lower bound of hugepage segments */\n-\trte_memseg_walk(find_lower_va_bound, &addr);\n-\t/* keep distance to hugepages to minimize potential conflicts. */\n-\taddr = RTE_PTR_SUB(addr, (uintptr_t)(MLX5_UAR_OFFSET + MLX5_UAR_SIZE));\n-\t/* anonymous mmap, no real memory consumption. */\n-\taddr = mmap(addr, MLX5_UAR_SIZE,\n-\t\t    PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);\n-\tif (addr == MAP_FAILED) {\n-\t\tDRV_LOG(ERR,\n-\t\t\t\"Failed to reserve UAR address space, please\"\n-\t\t\t\" adjust MLX5_UAR_SIZE or try --base-virtaddr\");\n-\t\trte_errno = ENOMEM;\n-\t\treturn -rte_errno;\n-\t}\n-\t/* Accept either same addr or a new addr returned from mmap if target\n-\t * range occupied.\n-\t */\n-\tDRV_LOG(INFO, \"Reserved UAR address space: %p\", addr);\n-\tsd->uar_base = addr; /* for primary and secondary UAR re-mmap. */\n-\treturn 0;\n-}\n-\n-/**\n- * Unmap UAR address space reserved for primary process.\n- */\n-static void\n-mlx5_uar_uninit_primary(void)\n-{\n-\tstruct mlx5_shared_data *sd = mlx5_shared_data;\n-\n-\tif (!sd->uar_base)\n-\t\treturn;\n-\tmunmap(sd->uar_base, MLX5_UAR_SIZE);\n-\tsd->uar_base = NULL;\n-}\n-\n-/**\n- * Reserve UAR address space for secondary process, align with primary process.\n- *\n- * @return\n- *   0 on success, a negative errno value otherwise and rte_errno is set.\n- */\n-static int\n-mlx5_uar_init_secondary(void)\n-{\n-\tstruct mlx5_shared_data *sd = mlx5_shared_data;\n-\tstruct mlx5_local_data *ld = &mlx5_local_data;\n-\tvoid *addr;\n-\n-\tif (ld->uar_base) { /* Already reserved. */\n-\t\tassert(sd->uar_base == ld->uar_base);\n-\t\treturn 0;\n-\t}\n-\tassert(sd->uar_base);\n-\t/* anonymous mmap, no real memory consumption. */\n-\taddr = mmap(sd->uar_base, MLX5_UAR_SIZE,\n-\t\t    PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);\n-\tif (addr == MAP_FAILED) {\n-\t\tDRV_LOG(ERR, \"UAR mmap failed: %p size: %llu\",\n-\t\t\tsd->uar_base, MLX5_UAR_SIZE);\n-\t\trte_errno = ENXIO;\n-\t\treturn -rte_errno;\n-\t}\n-\tif (sd->uar_base != addr) {\n-\t\tDRV_LOG(ERR,\n-\t\t\t\"UAR address %p size %llu occupied, please\"\n-\t\t\t\" adjust MLX5_UAR_OFFSET or try EAL parameter\"\n-\t\t\t\" --base-virtaddr\",\n-\t\t\tsd->uar_base, MLX5_UAR_SIZE);\n-\t\trte_errno = ENXIO;\n-\t\treturn -rte_errno;\n-\t}\n-\tld->uar_base = addr;\n-\tDRV_LOG(INFO, \"Reserved UAR address space: %p\", addr);\n-\treturn 0;\n-}\n-\n-/**\n- * Unmap UAR address space reserved for secondary process.\n- */\n-static void\n-mlx5_uar_uninit_secondary(void)\n-{\n-\tstruct mlx5_local_data *ld = &mlx5_local_data;\n-\n-\tif (!ld->uar_base)\n-\t\treturn;\n-\tmunmap(ld->uar_base, MLX5_UAR_SIZE);\n-\tld->uar_base = NULL;\n-}\n-\n /**\n  * PMD global initialization.\n  *\n@@ -1054,7 +953,6 @@ mlx5_init_once(void)\n {\n \tstruct mlx5_shared_data *sd;\n \tstruct mlx5_local_data *ld = &mlx5_local_data;\n-\tint ret;\n \n \tif (mlx5_init_shared_data())\n \t\treturn -rte_errno;\n@@ -1070,18 +968,12 @@ mlx5_init_once(void)\n \t\trte_mem_event_callback_register(\"MLX5_MEM_EVENT_CB\",\n \t\t\t\t\t\tmlx5_mr_mem_event_cb, NULL);\n \t\tmlx5_mp_init_primary();\n-\t\tret = mlx5_uar_init_primary();\n-\t\tif (ret)\n-\t\t\tgoto error;\n \t\tsd->init_done = true;\n \t\tbreak;\n \tcase RTE_PROC_SECONDARY:\n \t\tif (ld->init_done)\n \t\t\tbreak;\n \t\tmlx5_mp_init_secondary();\n-\t\tret = mlx5_uar_init_secondary();\n-\t\tif (ret)\n-\t\t\tgoto error;\n \t\t++sd->secondary_cnt;\n \t\tld->init_done = true;\n \t\tbreak;\n@@ -1090,23 +982,6 @@ mlx5_init_once(void)\n \t}\n \trte_spinlock_unlock(&sd->lock);\n \treturn 0;\n-error:\n-\tswitch (rte_eal_process_type()) {\n-\tcase RTE_PROC_PRIMARY:\n-\t\tmlx5_uar_uninit_primary();\n-\t\tmlx5_mp_uninit_primary();\n-\t\trte_mem_event_callback_unregister(\"MLX5_MEM_EVENT_CB\", NULL);\n-\t\tbreak;\n-\tcase RTE_PROC_SECONDARY:\n-\t\tmlx5_uar_uninit_secondary();\n-\t\tmlx5_mp_uninit_secondary();\n-\t\tbreak;\n-\tdefault:\n-\t\tbreak;\n-\t}\n-\trte_spinlock_unlock(&sd->lock);\n-\tmlx5_uninit_shared_data();\n-\treturn -rte_errno;\n }\n \n /**\n@@ -1197,12 +1072,15 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,\n \t\t}\n \t\teth_dev->device = dpdk_dev;\n \t\teth_dev->dev_ops = &mlx5_dev_sec_ops;\n+\t\terr = mlx5_proc_priv_init(eth_dev);\n+\t\tif (err)\n+\t\t\treturn NULL;\n \t\t/* Receive command fd from primary process */\n \t\terr = mlx5_mp_req_verbs_cmd_fd(eth_dev);\n \t\tif (err < 0)\n \t\t\treturn NULL;\n \t\t/* Remap UAR for Tx queues. */\n-\t\terr = mlx5_tx_uar_remap(eth_dev, err);\n+\t\terr = mlx5_tx_uar_init_secondary(eth_dev, err);\n \t\tif (err)\n \t\t\treturn NULL;\n \t\t/*\ndiff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h\nindex 960a2f8191..14c7f3c6fb 100644\n--- a/drivers/net/mlx5/mlx5.h\n+++ b/drivers/net/mlx5/mlx5.h\n@@ -97,8 +97,6 @@ struct mlx5_shared_data {\n \t/* Global spinlock for primary and secondary processes. */\n \tint init_done; /* Whether primary has done initialization. */\n \tunsigned int secondary_cnt; /* Number of secondary processes init'd. */\n-\tvoid *uar_base;\n-\t/* Reserved UAR address space for TXQ UAR(hw doorbell) mapping. */\n \tstruct mlx5_dev_list mem_event_cb_list;\n \trte_rwlock_t mem_event_rwlock;\n };\n@@ -106,8 +104,6 @@ struct mlx5_shared_data {\n /* Per-process data structure, not visible to other processes. */\n struct mlx5_local_data {\n \tint init_done; /* Whether a secondary has done initialization. */\n-\tvoid *uar_base;\n-\t/* Reserved UAR address space for TXQ UAR(hw doorbell) mapping. */\n };\n \n extern struct mlx5_shared_data *mlx5_shared_data;\n@@ -282,6 +278,17 @@ struct mlx5_ibv_shared {\n \tstruct mlx5_ibv_shared_port port[]; /* per device port data array. */\n };\n \n+/* Per-process private structure. */\n+struct mlx5_proc_priv {\n+\tsize_t uar_table_sz;\n+\t/* Size of UAR register table. */\n+\tvoid *uar_table[];\n+\t/* Table of UAR registers for each process. */\n+};\n+\n+#define MLX5_PROC_PRIV(port_id) \\\n+\t((struct mlx5_proc_priv *)rte_eth_devices[port_id].process_private)\n+\n struct mlx5_priv {\n \tLIST_ENTRY(mlx5_priv) mem_event_cb;\n \t/**< Called by memory event callback. */\n@@ -359,6 +366,7 @@ struct mlx5_priv {\n /* mlx5.c */\n \n int mlx5_getenv_int(const char *);\n+int mlx5_proc_priv_init(struct rte_eth_dev *dev);\n \n /* mlx5_ethdev.c */\n \ndiff --git a/drivers/net/mlx5/mlx5_defs.h b/drivers/net/mlx5/mlx5_defs.h\nindex bfe6655800..69b6960e94 100644\n--- a/drivers/net/mlx5/mlx5_defs.h\n+++ b/drivers/net/mlx5/mlx5_defs.h\n@@ -91,16 +91,6 @@\n /* Timeout in seconds to get a valid link status. */\n #define MLX5_LINK_STATUS_TIMEOUT 10\n \n-/* Reserved address space for UAR mapping. */\n-#define MLX5_UAR_SIZE (1ULL << (sizeof(uintptr_t) * 4))\n-\n-/* Offset of reserved UAR address space to hugepage memory. Offset is used here\n- * to minimize possibility of address next to hugepage being used by other code\n- * in either primary or secondary process, failing to map TX UAR would make TX\n- * packets invisible to HW.\n- */\n-#define MLX5_UAR_OFFSET (1ULL << (sizeof(uintptr_t) * 4))\n-\n /* Maximum number of UAR pages used by a port,\n  * These are the size and mask for an array of mutexes used to synchronize\n  * the access to port's UARs on platforms that do not support 64 bit writes.\ndiff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c\nindex 1e6fe192a6..3992918c57 100644\n--- a/drivers/net/mlx5/mlx5_ethdev.c\n+++ b/drivers/net/mlx5/mlx5_ethdev.c\n@@ -450,6 +450,9 @@ mlx5_dev_configure(struct rte_eth_dev *dev)\n \t\tif (++j == rxqs_n)\n \t\t\tj = 0;\n \t}\n+\tret = mlx5_proc_priv_init(dev);\n+\tif (ret)\n+\t\treturn ret;\n \treturn 0;\n }\n \ndiff --git a/drivers/net/mlx5/mlx5_rxtx.h b/drivers/net/mlx5/mlx5_rxtx.h\nindex 7b58063ceb..5d49892429 100644\n--- a/drivers/net/mlx5/mlx5_rxtx.h\n+++ b/drivers/net/mlx5/mlx5_rxtx.h\n@@ -201,8 +201,8 @@ struct mlx5_txq_data {\n \tvolatile void *wqes; /* Work queue (use volatile to write into). */\n \tvolatile uint32_t *qp_db; /* Work queue doorbell. */\n \tvolatile uint32_t *cq_db; /* Completion queue doorbell. */\n-\tvolatile void *bf_reg; /* Blueflame register remapped. */\n \tstruct rte_mbuf *(*elts)[]; /* TX elements. */\n+\tuint16_t port_id; /* Port ID of device. */\n \tuint16_t idx; /* Queue index. */\n \tstruct mlx5_txq_stats stats; /* TX queue counters. */\n #ifndef RTE_ARCH_64\n@@ -231,9 +231,12 @@ struct mlx5_txq_ctrl {\n \tstruct mlx5_txq_ibv *ibv; /* Verbs queue object. */\n \tstruct mlx5_priv *priv; /* Back pointer to private data. */\n \toff_t uar_mmap_offset; /* UAR mmap offset for non-primary process. */\n-\tvolatile void *bf_reg_orig; /* Blueflame register from verbs. */\n+\tvoid *bf_reg; /* BlueFlame register from Verbs. */\n };\n \n+#define MLX5_TX_BFREG(txq) \\\n+\t\t(MLX5_PROC_PRIV((txq)->port_id)->uar_table[(txq)->idx])\n+\n /* mlx5_rxq.c */\n \n extern uint8_t rss_hash_default_key[];\n@@ -301,7 +304,7 @@ uint64_t mlx5_get_rx_queue_offloads(struct rte_eth_dev *dev);\n int mlx5_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,\n \t\t\tunsigned int socket, const struct rte_eth_txconf *conf);\n void mlx5_tx_queue_release(void *dpdk_txq);\n-int mlx5_tx_uar_remap(struct rte_eth_dev *dev, int fd);\n+int mlx5_tx_uar_init_secondary(struct rte_eth_dev *dev, int fd);\n struct mlx5_txq_ibv *mlx5_txq_ibv_new(struct rte_eth_dev *dev, uint16_t idx);\n struct mlx5_txq_ibv *mlx5_txq_ibv_get(struct rte_eth_dev *dev, uint16_t idx);\n int mlx5_txq_ibv_release(struct mlx5_txq_ibv *txq_ibv);\n@@ -704,7 +707,7 @@ static __rte_always_inline void\n mlx5_tx_dbrec_cond_wmb(struct mlx5_txq_data *txq, volatile struct mlx5_wqe *wqe,\n \t\t       int cond)\n {\n-\tuint64_t *dst = (uint64_t *)((uintptr_t)txq->bf_reg);\n+\tuint64_t *dst = MLX5_TX_BFREG(txq);\n \tvolatile uint64_t *src = ((volatile uint64_t *)wqe);\n \n \trte_cio_wmb();\ndiff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c\nindex 7c1e5594d6..b7fde35758 100644\n--- a/drivers/net/mlx5/mlx5_trigger.c\n+++ b/drivers/net/mlx5/mlx5_trigger.c\n@@ -58,12 +58,6 @@ mlx5_txq_start(struct rte_eth_dev *dev)\n \t\t\tgoto error;\n \t\t}\n \t}\n-\tret = mlx5_tx_uar_remap(dev, priv->sh->ctx->cmd_fd);\n-\tif (ret) {\n-\t\t/* Adjust index for rollback. */\n-\t\ti = priv->txqs_n - 1;\n-\t\tgoto error;\n-\t}\n \treturn 0;\n error:\n \tret = rte_errno; /* Save rte_errno before cleanup. */\ndiff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c\nindex 4bd08cb035..9965b2b771 100644\n--- a/drivers/net/mlx5/mlx5_txq.c\n+++ b/drivers/net/mlx5/mlx5_txq.c\n@@ -229,13 +229,100 @@ mlx5_tx_queue_release(void *dpdk_txq)\n \t\t}\n }\n \n+/**\n+ * Initialize Tx UAR registers for primary process.\n+ *\n+ * @param txq_ctrl\n+ *   Pointer to Tx queue control structure.\n+ */\n+static void\n+txq_uar_init(struct mlx5_txq_ctrl *txq_ctrl)\n+{\n+\tstruct mlx5_priv *priv = txq_ctrl->priv;\n+\tstruct mlx5_proc_priv *ppriv = MLX5_PROC_PRIV(PORT_ID(priv));\n+#ifndef RTE_ARCH_64\n+\tunsigned int lock_idx;\n+\tconst size_t page_size = sysconf(_SC_PAGESIZE);\n+#endif\n+\n+\tassert(rte_eal_process_type() == RTE_PROC_PRIMARY);\n+\tassert(ppriv);\n+\tppriv->uar_table[txq_ctrl->txq.idx] = txq_ctrl->bf_reg;\n+#ifndef RTE_ARCH_64\n+\t/* Assign an UAR lock according to UAR page number */\n+\tlock_idx = (txq_ctrl->uar_mmap_offset / page_size) &\n+\t\t   MLX5_UAR_PAGE_NUM_MASK;\n+\ttxq_ctrl->txq.uar_lock = &priv->uar_lock[lock_idx];\n+#endif\n+}\n+\n+/**\n+ * Remap UAR register of a Tx queue for secondary process.\n+ *\n+ * Remapped address is stored at the table in the process private structure of\n+ * the device, indexed by queue index.\n+ *\n+ * @param txq_ctrl\n+ *   Pointer to Tx queue control structure.\n+ * @param fd\n+ *   Verbs file descriptor to map UAR pages.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_errno is set.\n+ */\n+static int\n+txq_uar_init_secondary(struct mlx5_txq_ctrl *txq_ctrl, int fd)\n+{\n+\tstruct mlx5_priv *priv = txq_ctrl->priv;\n+\tstruct mlx5_proc_priv *ppriv = MLX5_PROC_PRIV(PORT_ID(priv));\n+\tstruct mlx5_txq_data *txq = &txq_ctrl->txq;\n+\tvoid *addr;\n+\tuintptr_t uar_va;\n+\tuintptr_t offset;\n+\tconst size_t page_size = sysconf(_SC_PAGESIZE);\n+\n+\tassert(ppriv);\n+\t/*\n+\t * As rdma-core, UARs are mapped in size of OS page\n+\t * size. Ref to libmlx5 function: mlx5_init_context()\n+\t */\n+\tuar_va = (uintptr_t)txq_ctrl->bf_reg;\n+\toffset = uar_va & (page_size - 1); /* Offset in page. */\n+\taddr = mmap(NULL, page_size, PROT_WRITE, MAP_SHARED, fd,\n+\t\t\ttxq_ctrl->uar_mmap_offset);\n+\tif (addr == MAP_FAILED) {\n+\t\tDRV_LOG(ERR,\n+\t\t\t\"port %u mmap failed for BF reg of txq %u\",\n+\t\t\ttxq->port_id, txq->idx);\n+\t\trte_errno = ENXIO;\n+\t\treturn -rte_errno;\n+\t}\n+\taddr = RTE_PTR_ADD(addr, offset);\n+\tppriv->uar_table[txq->idx] = addr;\n+\treturn 0;\n+}\n+\n+/**\n+ * Unmap UAR register of a Tx queue for secondary process.\n+ *\n+ * @param txq_ctrl\n+ *   Pointer to Tx queue control structure.\n+ */\n+static void\n+txq_uar_uninit_secondary(struct mlx5_txq_ctrl *txq_ctrl)\n+{\n+\tstruct mlx5_proc_priv *ppriv = MLX5_PROC_PRIV(PORT_ID(txq_ctrl->priv));\n+\tconst size_t page_size = sysconf(_SC_PAGESIZE);\n+\tvoid *addr;\n+\n+\taddr = ppriv->uar_table[txq_ctrl->txq.idx];\n+\tmunmap(RTE_PTR_ALIGN_FLOOR(addr, page_size), page_size);\n+}\n \n /**\n- * Mmap TX UAR(HW doorbell) pages into reserved UAR address space.\n- * Both primary and secondary process do mmap to make UAR address\n- * aligned.\n+ * Initialize Tx UAR registers for secondary process.\n  *\n- * @param[in] dev\n+ * @param dev\n  *   Pointer to Ethernet device.\n  * @param fd\n  *   Verbs file descriptor to map UAR pages.\n@@ -244,81 +331,36 @@ mlx5_tx_queue_release(void *dpdk_txq)\n  *   0 on success, a negative errno value otherwise and rte_errno is set.\n  */\n int\n-mlx5_tx_uar_remap(struct rte_eth_dev *dev, int fd)\n+mlx5_tx_uar_init_secondary(struct rte_eth_dev *dev, int fd)\n {\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n-\tunsigned int i, j;\n-\tuintptr_t pages[priv->txqs_n];\n-\tunsigned int pages_n = 0;\n-\tuintptr_t uar_va;\n-\tuintptr_t off;\n-\tvoid *addr;\n-\tvoid *ret;\n \tstruct mlx5_txq_data *txq;\n \tstruct mlx5_txq_ctrl *txq_ctrl;\n-\tint already_mapped;\n-\tsize_t page_size = sysconf(_SC_PAGESIZE);\n-#ifndef RTE_ARCH_64\n-\tunsigned int lock_idx;\n-#endif\n+\tunsigned int i;\n+\tint ret;\n \n-\tmemset(pages, 0, priv->txqs_n * sizeof(uintptr_t));\n-\t/*\n-\t * As rdma-core, UARs are mapped in size of OS page size.\n-\t * Use aligned address to avoid duplicate mmap.\n-\t * Ref to libmlx5 function: mlx5_init_context()\n-\t */\n+\tassert(rte_eal_process_type() == RTE_PROC_SECONDARY);\n \tfor (i = 0; i != priv->txqs_n; ++i) {\n \t\tif (!(*priv->txqs)[i])\n \t\t\tcontinue;\n \t\ttxq = (*priv->txqs)[i];\n \t\ttxq_ctrl = container_of(txq, struct mlx5_txq_ctrl, txq);\n \t\tassert(txq->idx == (uint16_t)i);\n-\t\t/* UAR addr form verbs used to find dup and offset in page. */\n-\t\tuar_va = (uintptr_t)txq_ctrl->bf_reg_orig;\n-\t\toff = uar_va & (page_size - 1); /* offset in page. */\n-\t\tuar_va = RTE_ALIGN_FLOOR(uar_va, page_size); /* page addr. */\n-\t\talready_mapped = 0;\n-\t\tfor (j = 0; j != pages_n; ++j) {\n-\t\t\tif (pages[j] == uar_va) {\n-\t\t\t\talready_mapped = 1;\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\t}\n-\t\t/* new address in reserved UAR address space. */\n-\t\taddr = RTE_PTR_ADD(mlx5_shared_data->uar_base,\n-\t\t\t\t   uar_va & (uintptr_t)(MLX5_UAR_SIZE - 1));\n-\t\tif (!already_mapped) {\n-\t\t\tpages[pages_n++] = uar_va;\n-\t\t\t/* fixed mmap to specified address in reserved\n-\t\t\t * address space.\n-\t\t\t */\n-\t\t\tret = mmap(addr, page_size,\n-\t\t\t\t   PROT_WRITE, MAP_FIXED | MAP_SHARED, fd,\n-\t\t\t\t   txq_ctrl->uar_mmap_offset);\n-\t\t\tif (ret != addr) {\n-\t\t\t\t/* fixed mmap have to return same address */\n-\t\t\t\tDRV_LOG(ERR,\n-\t\t\t\t\t\"port %u call to mmap failed on UAR\"\n-\t\t\t\t\t\" for txq %u\",\n-\t\t\t\t\tdev->data->port_id, txq->idx);\n-\t\t\t\trte_errno = ENXIO;\n-\t\t\t\treturn -rte_errno;\n-\t\t\t}\n-\t\t}\n-\t\tif (rte_eal_process_type() == RTE_PROC_PRIMARY) /* save once */\n-\t\t\ttxq_ctrl->txq.bf_reg = RTE_PTR_ADD((void *)addr, off);\n-\t\telse\n-\t\t\tassert(txq_ctrl->txq.bf_reg ==\n-\t\t\t       RTE_PTR_ADD((void *)addr, off));\n-#ifndef RTE_ARCH_64\n-\t\t/* Assign a UAR lock according to UAR page number */\n-\t\tlock_idx = (txq_ctrl->uar_mmap_offset / page_size) &\n-\t\t\t   MLX5_UAR_PAGE_NUM_MASK;\n-\t\ttxq->uar_lock = &priv->uar_lock[lock_idx];\n-#endif\n+\t\tret = txq_uar_init_secondary(txq_ctrl, fd);\n+\t\tif (ret)\n+\t\t\tgoto error;\n \t}\n \treturn 0;\n+error:\n+\t/* Rollback. */\n+\tdo {\n+\t\tif (!(*priv->txqs)[i])\n+\t\t\tcontinue;\n+\t\ttxq = (*priv->txqs)[i];\n+\t\ttxq_ctrl = container_of(txq, struct mlx5_txq_ctrl, txq);\n+\t\ttxq_uar_uninit_secondary(txq_ctrl);\n+\t} while (i--);\n+\treturn -rte_errno;\n }\n \n /**\n@@ -507,7 +549,6 @@ mlx5_txq_ibv_new(struct rte_eth_dev *dev, uint16_t idx)\n \ttxq_data->wqes = qp.sq.buf;\n \ttxq_data->wqe_n = log2above(qp.sq.wqe_cnt);\n \ttxq_data->qp_db = &qp.dbrec[MLX5_SND_DBR];\n-\ttxq_ctrl->bf_reg_orig = qp.bf.reg;\n \ttxq_data->cq_db = cq_info.dbrec;\n \ttxq_data->cqes =\n \t\t(volatile struct mlx5_cqe (*)[])\n@@ -521,6 +562,8 @@ mlx5_txq_ibv_new(struct rte_eth_dev *dev, uint16_t idx)\n \ttxq_ibv->qp = tmpl.qp;\n \ttxq_ibv->cq = tmpl.cq;\n \trte_atomic32_inc(&txq_ibv->refcnt);\n+\ttxq_ctrl->bf_reg = qp.bf.reg;\n+\ttxq_uar_init(txq_ctrl);\n \tif (qp.comp_mask & MLX5DV_QP_MASK_UAR_MMAP_OFFSET) {\n \t\ttxq_ctrl->uar_mmap_offset = qp.uar_mmap_offset;\n \t\tDRV_LOG(DEBUG, \"port %u: uar_mmap_offset 0x%lx\",\n@@ -778,6 +821,7 @@ mlx5_txq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,\n \ttmpl->priv = priv;\n \ttmpl->socket = socket;\n \ttmpl->txq.elts_n = log2above(desc);\n+\ttmpl->txq.port_id = dev->data->port_id;\n \ttmpl->txq.idx = idx;\n \ttxq_set_params(tmpl);\n \tDRV_LOG(DEBUG, \"port %u device_attr.max_qp_wr is %d\",\n@@ -836,15 +880,12 @@ mlx5_txq_release(struct rte_eth_dev *dev, uint16_t idx)\n {\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n \tstruct mlx5_txq_ctrl *txq;\n-\tsize_t page_size = sysconf(_SC_PAGESIZE);\n \n \tif (!(*priv->txqs)[idx])\n \t\treturn 0;\n \ttxq = container_of((*priv->txqs)[idx], struct mlx5_txq_ctrl, txq);\n \tif (txq->ibv && !mlx5_txq_ibv_release(txq->ibv))\n \t\ttxq->ibv = NULL;\n-\tmunmap((void *)RTE_ALIGN_FLOOR((uintptr_t)txq->txq.bf_reg, page_size),\n-\t       page_size);\n \tif (rte_atomic32_dec_and_test(&txq->refcnt)) {\n \t\ttxq_free_elts(txq);\n \t\tmlx5_mr_btree_free(&txq->txq.mr_ctrl.cache_bh);\n",
    "prefixes": [
        "v5",
        "3/4"
    ]
}