get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 34123,
    "url": "https://patches.dpdk.org/api/patches/34123/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20180119150854.89828-1-xuemingl@mellanox.com/",
    "project": {
        "id": 1,
        "url": "https://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": "<20180119150854.89828-1-xuemingl@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20180119150854.89828-1-xuemingl@mellanox.com",
    "date": "2018-01-19T15:08:54",
    "name": "[dpdk-dev] net/mlx5: remmap UAR address for multiple process",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "66b44ec910bf5766ab2b54d98740e87870cee2f7",
    "submitter": {
        "id": 814,
        "url": "https://patches.dpdk.org/api/people/814/?format=api",
        "name": "Xueming Li",
        "email": "xuemingl@mellanox.com"
    },
    "delegate": {
        "id": 6624,
        "url": "https://patches.dpdk.org/api/users/6624/?format=api",
        "username": "shahafs",
        "first_name": "Shahaf",
        "last_name": "Shuler",
        "email": "shahafs@mellanox.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20180119150854.89828-1-xuemingl@mellanox.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/34123/comments/",
    "check": "fail",
    "checks": "https://patches.dpdk.org/api/patches/34123/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 5AE231B32E;\n\tFri, 19 Jan 2018 16:09:25 +0100 (CET)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n\tby dpdk.org (Postfix) with ESMTP id 183A51B03F\n\tfor <dev@dpdk.org>; Fri, 19 Jan 2018 16:09:23 +0100 (CET)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n\txuemingl@mellanox.com)\n\twith ESMTPS (AES256-SHA encrypted); 19 Jan 2018 17:09:18 +0200",
            "from dev-r630-06.mtbc.labs.mlnx (dev-r630-06.mtbc.labs.mlnx\n\t[10.12.205.180])\n\tby labmailer.mlnx (8.13.8/8.13.8) with ESMTP id w0JF9HHD030579;\n\tFri, 19 Jan 2018 17:09:18 +0200",
            "from dev-r630-06.mtbc.labs.mlnx (localhost [127.0.0.1])\n\tby dev-r630-06.mtbc.labs.mlnx (8.14.7/8.14.7) with ESMTP id\n\tw0JF9GPs089885; Fri, 19 Jan 2018 23:09:16 +0800",
            "(from xuemingl@localhost)\n\tby dev-r630-06.mtbc.labs.mlnx (8.14.7/8.14.7/Submit) id\n\tw0JF9BVh089882; Fri, 19 Jan 2018 23:09:11 +0800"
        ],
        "From": "Xueming Li <xuemingl@mellanox.com>",
        "To": "Nelio Laranjeiro <nelio.laranjeiro@6wind.com>",
        "Cc": "Xueming Li <xuemingl@mellanox.com>, Shahaf Shuler <shahafs@mellanox.com>,\n\tdev@dpdk.org",
        "Date": "Fri, 19 Jan 2018 23:08:54 +0800",
        "Message-Id": "<20180119150854.89828-1-xuemingl@mellanox.com>",
        "X-Mailer": "git-send-email 2.13.3",
        "Subject": "[dpdk-dev] [PATCH] net/mlx5: remmap UAR address for multiple process",
        "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://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://dpdk.org/ml/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(doorbell) is hw resources that have to be same address between\nprimary and secondary process, failed to mmap UAR will make TX packets\ninvisible to HW.\nToday, UAR address returned from verbs api is mixed in heap and loaded\nlibrary address space, prone to be occupied in secondary process.\nThis patch reserves a dedicate UAR address space, both primary and\nsecondary process re-mmap UAR pages into this space.\nBelow is a brief picture of dpdk app address space allocation:\n\tBefore\t\t\tThis patch\n\t------\t\t\t----------\n\t[stack]\t\t\t[stack]\n\t[.so, uar, heap]\t[.so, heap]\n\t[(empty)]\t\t[(empty)]\n\t[hugepage]\t\t[hugepage]\n\t[? others]\t\t[? others]\n\t[(empty)]\t\t[(empty)]\n\t\t\t\t[uar]\n\t\t\t\t[(empty)]\nTo minimize conflicts, UAR address space comes after hugepage space with\nan offset to skip potential usage from other drivers.\n\nOnce UAR space reserved successfully, UAR pages are re-mmapped into new\narea to keep UAR address aligned between primary and secondary process.\n\nSigned-off-by: Xueming Li <xuemingl@mellanox.com>\n---\n drivers/net/mlx5/mlx5.c         | 107 ++++++++++++++++++++++++++++++++++++++++\n drivers/net/mlx5/mlx5.h         |   1 +\n drivers/net/mlx5/mlx5_defs.h    |  10 ++++\n drivers/net/mlx5/mlx5_rxtx.h    |   3 +-\n drivers/net/mlx5/mlx5_trigger.c |   7 ++-\n drivers/net/mlx5/mlx5_txq.c     |  51 +++++++++++++------\n 6 files changed, 163 insertions(+), 16 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c\nindex fc2d59fee..1539ef608 100644\n--- a/drivers/net/mlx5/mlx5.c\n+++ b/drivers/net/mlx5/mlx5.c\n@@ -39,6 +39,7 @@\n #include <stdlib.h>\n #include <errno.h>\n #include <net/if.h>\n+#include <sys/mman.h>\n \n /* Verbs header. */\n /* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */\n@@ -56,6 +57,7 @@\n #include <rte_pci.h>\n #include <rte_bus_pci.h>\n #include <rte_common.h>\n+#include <rte_eal_memconfig.h>\n #include <rte_kvargs.h>\n \n #include \"mlx5.h\"\n@@ -466,6 +468,101 @@ mlx5_args(struct mlx5_dev_config *config, struct rte_devargs *devargs)\n \n static struct rte_pci_driver mlx5_driver;\n \n+/*\n+ * Reserved UAR address space for TXQ UAR(hw doorbell) mapping, process\n+ * local resource used by both primary and secondary to avoid duplicate\n+ * reservation.\n+ * The space has to be available on both primary and secondary process,\n+ * TXQ UAR maps to this area using fixed mmap w/o double check.\n+ */\n+static void *uar_base;\n+\n+/**\n+ * Reserve UAR address space for primary process\n+ *\n+ * @param[in] priv\n+ *   Pointer to private structure.\n+ *\n+ * @return\n+ *   0 on success, negative errno value on failure.\n+ */\n+static int\n+mlx5_uar_init_primary(struct priv *priv)\n+{\n+\tvoid *addr = (void *)0;\n+\tint i;\n+\tconst struct rte_mem_config *mcfg;\n+\n+\tif (uar_base) { /* UAR address space mapped */\n+\t\tpriv->uar_base = uar_base;\n+\t\treturn 0;\n+\t}\n+\t/* find out lower bound of hugepage segments */\n+\tmcfg = rte_eal_get_configuration()->mem_config;\n+\tfor (i = 0; i < RTE_MAX_MEMSEG && mcfg->memseg[i].addr; i++) {\n+\t\tif (addr)\n+\t\t\taddr = RTE_MIN(addr, mcfg->memseg[i].addr);\n+\t\telse\n+\t\t\taddr = mcfg->memseg[i].addr;\n+\t}\n+\t/* offset down UAR area */\n+\taddr = RTE_PTR_SUB(addr, 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\tERROR(\"Failed to reserve UAR address space, please adjust \"\n+\t\t      \"MLX5_UAR_SIZE or try --base-virtaddr\");\n+\t\treturn -ENOMEM;\n+\t}\n+\t/* Accept either same addr or a new addr returned from mmap if target\n+\t * range occupied.\n+\t */\n+\tINFO(\"Reserved UAR address space: 0x%p\", addr);\n+\tpriv->uar_base = addr; /* for primary and secondary UAR re-mmap */\n+\tuar_base = addr; /* process local, don't reserve again */\n+\treturn 0;\n+}\n+\n+/**\n+ * Reserve UAR address space for secondary process, align with\n+ * primary process.\n+ *\n+ * @param[in] priv\n+ *   Pointer to private structure.\n+ *\n+ * @return\n+ *   0 on success, negative errno value on failure.\n+ */\n+static int\n+mlx5_uar_init_secondary(struct priv *priv)\n+{\n+\tvoid *addr;\n+\n+\tassert(priv->uar_base);\n+\tif (uar_base) { /* already reserved */\n+\t\tassert(uar_base == priv->uar_base);\n+\t\treturn 0;\n+\t}\n+\t/* anonymous mmap, no real memory consumption */\n+\taddr = mmap(priv->uar_base, MLX5_UAR_SIZE,\n+\t\t    PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);\n+\tif (addr == MAP_FAILED) {\n+\t\tERROR(\"UAR mmap failed: 0x%p size: %llu\",\n+\t\t      priv->uar_base, MLX5_UAR_SIZE);\n+\t\treturn -ENXIO;\n+\t}\n+\tif (priv->uar_base != addr) {\n+\t\tERROR(\"UAR address 0x%p size %llu occupied, please adjust \"\n+\t\t      \"MLX5_UAR_OFFSET or try EAL parameter --base-virtaddr\",\n+\t\t      priv->uar_base, MLX5_UAR_SIZE);\n+\t\treturn -ENXIO;\n+\t}\n+\tuar_base = addr; /* process local, don't reserve again */\n+\tINFO(\"Reserved UAR address space: 0x%p\", addr);\n+\treturn 0;\n+}\n+\n /**\n  * DPDK callback to register a PCI device.\n  *\n@@ -648,6 +745,11 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)\n \t\t\teth_dev->device = &pci_dev->device;\n \t\t\teth_dev->dev_ops = &mlx5_dev_sec_ops;\n \t\t\tpriv = eth_dev->data->dev_private;\n+\t\t\terr = mlx5_uar_init_secondary(priv);\n+\t\t\tif (err < 0) {\n+\t\t\t\terr = -err;\n+\t\t\t\tgoto error;\n+\t\t\t}\n \t\t\t/* Receive command fd from primary process */\n \t\t\terr = priv_socket_connect(priv);\n \t\t\tif (err < 0) {\n@@ -805,6 +907,11 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)\n \t\t\tWARN(\"Rx CQE compression isn't supported\");\n \t\t\tconfig.cqe_comp = 0;\n \t\t}\n+\t\terr = mlx5_uar_init_primary(priv);\n+\t\tif (err < 0) {\n+\t\t\terr = -err;\n+\t\t\tgoto port_error;\n+\t\t}\n \t\t/* Configure the first MAC address by default. */\n \t\tif (priv_get_mac(priv, &mac.addr_bytes)) {\n \t\t\tERROR(\"cannot get MAC address, is mlx5_en loaded?\"\ndiff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h\nindex 9a4a59bd4..6a234c14f 100644\n--- a/drivers/net/mlx5/mlx5.h\n+++ b/drivers/net/mlx5/mlx5.h\n@@ -162,6 +162,7 @@ struct priv {\n \tstruct mlx5_xstats_ctrl xstats_ctrl; /* Extended stats control. */\n \trte_spinlock_t lock; /* Lock for control functions. */\n \tint primary_socket; /* Unix socket for primary process. */\n+\tvoid *uar_base; /* Reserved address space for UAR mapping */\n \tstruct rte_intr_handle intr_handle_socket; /* Interrupt handler. */\n \tstruct mlx5_dev_config config; /* Device configuration. */\n };\ndiff --git a/drivers/net/mlx5/mlx5_defs.h b/drivers/net/mlx5/mlx5_defs.h\nindex 64bb0712e..26bb39720 100644\n--- a/drivers/net/mlx5/mlx5_defs.h\n+++ b/drivers/net/mlx5/mlx5_defs.h\n@@ -110,4 +110,14 @@\n /* Supported RSS */\n #define MLX5_RSS_HF_MASK (~(ETH_RSS_IP | ETH_RSS_UDP | ETH_RSS_TCP))\n \n+/* Reserved address space for UAR mapping. */\n+#define MLX5_UAR_SIZE (1ULL << 32)\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 << 32)\n+\n #endif /* RTE_PMD_MLX5_DEFS_H_ */\ndiff --git a/drivers/net/mlx5/mlx5_rxtx.h b/drivers/net/mlx5/mlx5_rxtx.h\nindex a239642ac..be53dd662 100644\n--- a/drivers/net/mlx5/mlx5_rxtx.h\n+++ b/drivers/net/mlx5/mlx5_rxtx.h\n@@ -205,7 +205,7 @@ 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. */\n+\tvolatile void *bf_reg; /* Blueflame register remapped. */\n \tstruct mlx5_mr *mp2mr[MLX5_PMD_TX_MP_CACHE]; /* MR translation table. */\n \tstruct rte_mbuf *(*elts)[]; /* TX elements. */\n \tstruct mlx5_txq_stats stats; /* TX queue counters. */\n@@ -230,6 +230,7 @@ struct mlx5_txq_ctrl {\n \tstruct mlx5_txq_ibv *ibv; /* Verbs queue object. */\n \tstruct mlx5_txq_data txq; /* Data path structure. */\n \toff_t uar_mmap_offset; /* UAR mmap offset for non-primary process. */\n+\tvolatile void *bf_reg_orig; /* Blueflame register from verbs. */\n };\n \n /* mlx5_rxq.c */\ndiff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c\nindex 6f5c799b5..9acfa394f 100644\n--- a/drivers/net/mlx5/mlx5_trigger.c\n+++ b/drivers/net/mlx5/mlx5_trigger.c\n@@ -76,7 +76,12 @@ priv_txq_start(struct priv *priv)\n \t\t\tgoto error;\n \t\t}\n \t}\n-\treturn -ret;\n+\tret = priv_tx_uar_remap(priv, priv->ctx->cmd_fd);\n+\tif (ret) {\n+\t\tret = -ret;\n+\t\tgoto error;\n+\t}\n+\treturn ret;\n error:\n \tpriv_txq_stop(priv);\n \treturn -ret;\ndiff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c\nindex 26db15a4f..82f1b5ae8 100644\n--- a/drivers/net/mlx5/mlx5_txq.c\n+++ b/drivers/net/mlx5/mlx5_txq.c\n@@ -288,7 +288,9 @@ mlx5_tx_queue_release(void *dpdk_txq)\n \n \n /**\n- * Map locally UAR used in Tx queues for BlueFlame doorbell.\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  *\n  * @param[in] priv\n  *   Pointer to private structure.\n@@ -296,7 +298,7 @@ mlx5_tx_queue_release(void *dpdk_txq)\n  *   Verbs file descriptor to map UAR pages.\n  *\n  * @return\n- *   0 on success, errno value on failure.\n+ *   0 on success, negative errno value on failure.\n  */\n int\n priv_tx_uar_remap(struct priv *priv, int fd)\n@@ -305,7 +307,9 @@ priv_tx_uar_remap(struct priv *priv, int fd)\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@@ -320,8 +324,10 @@ priv_tx_uar_remap(struct priv *priv, int fd)\n \tfor (i = 0; i != priv->txqs_n; ++i) {\n \t\ttxq = (*priv->txqs)[i];\n \t\ttxq_ctrl = container_of(txq, struct mlx5_txq_ctrl, txq);\n-\t\tuar_va = (uintptr_t)txq_ctrl->txq.bf_reg;\n-\t\tuar_va = RTE_ALIGN_FLOOR(uar_va, page_size);\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@@ -329,16 +335,29 @@ priv_tx_uar_remap(struct priv *priv, int fd)\n \t\t\t\tbreak;\n \t\t\t}\n \t\t}\n-\t\tif (already_mapped)\n-\t\t\tcontinue;\n-\t\tpages[pages_n++] = uar_va;\n-\t\taddr = mmap((void *)uar_va, page_size,\n-\t\t\t    PROT_WRITE, MAP_FIXED | MAP_SHARED, fd,\n-\t\t\t    txq_ctrl->uar_mmap_offset);\n-\t\tif (addr != (void *)uar_va) {\n-\t\t\tERROR(\"call to mmap failed on UAR for txq %d\\n\", i);\n-\t\t\treturn -1;\n+\t\t/* new address in reserved UAR address space */\n+\t\taddr = RTE_PTR_ADD(priv->uar_base,\n+\t\t\t\t   uar_va & (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\tERROR(\"call to mmap failed on UAR for txq %d\\n\",\n+\t\t\t\t      i);\n+\t\t\t\treturn -ENXIO;\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 \t}\n \treturn 0;\n }\n@@ -503,7 +522,7 @@ mlx5_priv_txq_ibv_new(struct priv *priv, 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_data->bf_reg = qp.bf.reg;\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@@ -836,6 +855,7 @@ mlx5_priv_txq_release(struct priv *priv, uint16_t idx)\n {\n \tunsigned int i;\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@@ -855,6 +875,9 @@ mlx5_priv_txq_release(struct priv *priv, uint16_t idx)\n \t\t\ttxq->txq.mp2mr[i] = NULL;\n \t\t}\n \t}\n+\tif (priv->uar_base)\n+\t\tmunmap((void *)RTE_ALIGN_FLOOR((uintptr_t)txq->txq.bf_reg,\n+\t\t       page_size), page_size);\n \tif (rte_atomic32_dec_and_test(&txq->refcnt)) {\n \t\ttxq_free_elts(txq);\n \t\tLIST_REMOVE(txq, next);\n",
    "prefixes": [
        "dpdk-dev"
    ]
}