get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 29338,
    "url": "https://patches.dpdk.org/api/patches/29338/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1506606959-76230-13-git-send-email-jianfeng.tan@intel.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": "<1506606959-76230-13-git-send-email-jianfeng.tan@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1506606959-76230-13-git-send-email-jianfeng.tan@intel.com",
    "date": "2017-09-28T13:55:59",
    "name": "[dpdk-dev,v2,12/12] net/vhost: support to run in the secondary process",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "7ef47c82747da15b0367e596cc63ee525b5ff730",
    "submitter": {
        "id": 313,
        "url": "https://patches.dpdk.org/api/people/313/?format=api",
        "name": "Jianfeng Tan",
        "email": "jianfeng.tan@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1506606959-76230-13-git-send-email-jianfeng.tan@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/29338/comments/",
    "check": "fail",
    "checks": "https://patches.dpdk.org/api/patches/29338/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 DE5E61B227;\n\tThu, 28 Sep 2017 15:55:13 +0200 (CEST)",
            "from mga03.intel.com (mga03.intel.com [134.134.136.65])\n\tby dpdk.org (Postfix) with ESMTP id 0DA541B204\n\tfor <dev@dpdk.org>; Thu, 28 Sep 2017 15:55:05 +0200 (CEST)",
            "from fmsmga006.fm.intel.com ([10.253.24.20])\n\tby orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t28 Sep 2017 06:55:05 -0700",
            "from dpdk06.sh.intel.com ([10.67.110.196])\n\tby fmsmga006.fm.intel.com with ESMTP; 28 Sep 2017 06:55:03 -0700"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.42,450,1500966000\"; d=\"scan'208\";a=\"157117814\"",
        "From": "Jianfeng Tan <jianfeng.tan@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "bruce.richardson@intel.com, konstantin.ananyev@intel.com,\n\tpablo.de.lara.guarch@intel.com, thomas@monjalon.net,\n\tyliu@fridaylinux.org, maxime.coquelin@redhat.com, mtetsuyah@gmail.com,\n\tferruh.yigit@intel.com, Jianfeng Tan <jianfeng.tan@intel.com>",
        "Date": "Thu, 28 Sep 2017 13:55:59 +0000",
        "Message-Id": "<1506606959-76230-13-git-send-email-jianfeng.tan@intel.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "<1506606959-76230-1-git-send-email-jianfeng.tan@intel.com>",
        "References": "<1503654052-84730-1-git-send-email-jianfeng.tan@intel.com>\n\t<1506606959-76230-1-git-send-email-jianfeng.tan@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v2 12/12] net/vhost: support to run in the\n\tsecondary 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": "<http://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": "<http://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": "Support to run vhost-pmd vdev in the secondary process. We obtain\ninformation, like memory regions, kickfd, callfd, through\nprimary/secondary communication channel.\n\nAnd by invoking rte_vhost_set_vring_effective_fd, we can set the\nkickfd which can be recognized by the secondary process.\n\nSigned-off-by: Jianfeng Tan <jianfeng.tan@intel.com>\n---\n drivers/net/vhost/rte_eth_vhost.c | 200 +++++++++++++++++++++++++++++++++++---\n 1 file changed, 187 insertions(+), 13 deletions(-)",
    "diff": "diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c\nindex 0dac5e6..6a685a3 100644\n--- a/drivers/net/vhost/rte_eth_vhost.c\n+++ b/drivers/net/vhost/rte_eth_vhost.c\n@@ -33,6 +33,7 @@\n #include <unistd.h>\n #include <pthread.h>\n #include <stdbool.h>\n+#include <sys/mman.h>\n \n #include <rte_mbuf.h>\n #include <rte_ethdev.h>\n@@ -46,6 +47,20 @@\n \n #include \"rte_eth_vhost.h\"\n \n+#define VHOST_MSG_TYPE_REGIONS\t1\n+#define VHOST_MSG_TYPE_SET_FDS\t2\n+#define VHOST_MSG_TYPE_INIT\t3\n+\n+struct vhost_params {\n+\tint type;\n+\tunion {\n+\t\tint vid;\n+\t\tint portid;\n+\t};\n+\tint vring_idx;\n+\tstruct rte_vhost_mem_region regions[0];\n+};\n+\n enum {VIRTIO_RXQ, VIRTIO_TXQ, VIRTIO_QNUM};\n \n #define ETH_VHOST_IFACE_ARG\t\t\"iface\"\n@@ -550,6 +565,66 @@ update_queuing_status(struct rte_eth_dev *dev)\n }\n \n static int\n+share_device(int vid)\n+{\n+\tuint32_t i, vring_num;\n+\tint len;\n+\tint fds[8];\n+\tstruct rte_vhost_memory *mem;\n+\tstruct vhost_params *params;\n+\tstruct rte_vhost_vring vring;\n+\n+\t/* share mem table */\n+\tif (rte_vhost_get_mem_table(vid, &mem) < 0) {\n+\t\tRTE_LOG(ERR, PMD, \"Failed to get mem table\\n\");\n+\t\treturn 0;\n+\t}\n+\tfor (i = 0; i < mem->nregions; ++i)\n+\t\tfds[i] = mem->regions[i].fd;\n+\n+\tlen = sizeof(struct rte_vhost_mem_region) * mem->nregions;\n+\tparams = malloc(sizeof(*params) + len);\n+\tif (params == NULL) {\n+\t\tRTE_LOG(ERR, PMD, \"Failed to allocate memory\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tparams->type = VHOST_MSG_TYPE_REGIONS;\n+\tparams->vid = vid;\n+\tmemcpy(params->regions, mem->regions, len);\n+\n+\tif (rte_eal_mp_sendmsg(\"vhost pmd\", params, sizeof(*params) + len,\n+\t\t\t       fds, mem->nregions) < 0) {\n+\t\tRTE_LOG(ERR, PMD, \"Failed to share mem table\\n\");\n+\t\tfree(params);\n+\t\treturn -1;\n+\t}\n+\n+\t/* share callfd and kickfd */\n+\tparams->type = VHOST_MSG_TYPE_SET_FDS;\n+\tvring_num = rte_vhost_get_vring_num(vid);\n+\tfor (i = 0; i < vring_num; i++) {\n+\t\tif (rte_vhost_get_vhost_vring(vid, i, &vring) < 0) {\n+\t\t\tRTE_LOG(ERR, PMD, \"Failed to get vring, idx = %d\\n\", i);\n+\t\t\tfree(params);\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tparams->vring_idx = i;\n+\t\tfds[0] = vring.callfd;\n+\t\tfds[1] = vring.kickfd;\n+\t\tif (rte_eal_mp_sendmsg(\"vhost pmd\", params,\n+\t\t\t\t       sizeof(*params), fds, 2) < 0) {\n+\t\t\tRTE_LOG(ERR, PMD, \"Failed to set fds\\n\");\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\tfree(params);\n+\treturn 0;\n+}\n+\n+static int\n new_device(int vid)\n {\n \tstruct rte_eth_dev *eth_dev;\n@@ -610,6 +685,8 @@ new_device(int vid)\n \t_rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC,\n \t\t\t\t      NULL, NULL);\n \n+\tshare_device(vid);\n+\n \treturn 0;\n }\n \n@@ -1025,13 +1102,6 @@ eth_dev_vhost_create(struct rte_vdev_device *dev, char *iface_name,\n \tRTE_LOG(INFO, PMD, \"Creating VHOST-USER backend on numa socket %u\\n\",\n \t\tnuma_node);\n \n-\t/* now do all data allocation - for eth_dev structure and internal\n-\t * (private) data\n-\t */\n-\tdata = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);\n-\tif (data == NULL)\n-\t\tgoto error;\n-\n \tlist = rte_zmalloc_socket(name, sizeof(*list), 0, numa_node);\n \tif (list == NULL)\n \t\tgoto error;\n@@ -1073,11 +1143,7 @@ eth_dev_vhost_create(struct rte_vdev_device *dev, char *iface_name,\n \trte_spinlock_init(&vring_state->lock);\n \tvring_states[eth_dev->data->port_id] = vring_state;\n \n-\t/* We'll replace the 'data' originally allocated by eth_dev. So the\n-\t * vhost PMD resources won't be shared between multi processes.\n-\t */\n-\trte_memcpy(data, eth_dev->data, sizeof(*data));\n-\teth_dev->data = data;\n+\tdata = eth_dev->data;\n \n \tdata->nb_rx_queues = queues;\n \tdata->nb_tx_queues = queues;\n@@ -1125,6 +1191,30 @@ eth_dev_vhost_create(struct rte_vdev_device *dev, char *iface_name,\n \treturn -1;\n }\n \n+static int\n+eth_dev_vhost_attach(struct rte_vdev_device *dev)\n+{\n+\tstruct rte_eth_dev *eth_dev = NULL;\n+\tstruct rte_eth_dev_data *data = NULL;\n+\n+\tRTE_LOG(INFO, PMD, \"Attach vhost user port\\n\");\n+\n+\t/* reserve an ethdev entry */\n+\teth_dev = rte_eth_vdev_allocate(dev, sizeof(struct pmd_internal));\n+\tif (eth_dev == NULL)\n+\t\treturn -1;\n+\n+\teth_dev->dev_ops = &ops;\n+\n+\t/* finally assign rx and tx ops */\n+\teth_dev->rx_pkt_burst = eth_vhost_rx;\n+\teth_dev->tx_pkt_burst = eth_vhost_tx;\n+\n+\tdata = eth_dev->data;\n+\n+\treturn data->port_id;\n+}\n+\n static inline int\n open_iface(const char *key __rte_unused, const char *value, void *extra_args)\n {\n@@ -1154,10 +1244,84 @@ open_int(const char *key __rte_unused, const char *value, void *extra_args)\n }\n \n static int\n+vhost_pmd_action(const void *params, int len, int fds[], int fds_num)\n+{\n+\tint i;\n+\tint vid;\n+\tvoid *base_addr;\n+\tconst struct vhost_params *p = params;\n+\tconst struct rte_vhost_mem_region *regions;\n+\n+\tif (len < (int)sizeof(*p)) {\n+\t\tRTE_LOG(ERR, PMD, \"message if too short\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tswitch (p->type) {\n+\tcase VHOST_MSG_TYPE_REGIONS:\n+\t\tregions = p->regions;\n+\t\tfor (i = 0; i < fds_num; ++i) {\n+\t\t\tbase_addr = mmap(regions[i].mmap_addr,\n+\t\t\t\t\t regions[i].mmap_size,\n+\t\t\t\t\t PROT_READ | PROT_WRITE,\n+\t\t\t\t\t MAP_FIXED | MAP_SHARED, fds[i], 0);\n+\t\t\tif (base_addr != regions[i].mmap_addr) {\n+\t\t\t\tRTE_LOG(ERR, PMD,\n+\t\t\t\t\t\"vhost in secondary mmap error: %s\\n\",\n+\t\t\t\t\tstrerror(errno));\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t\tbreak;\n+\tcase VHOST_MSG_TYPE_SET_FDS:\n+\t\trte_vhost_set_vring_effective_fd(p->vid,\n+\t\t\t\t\t\t p->vring_idx,\n+\t\t\t\t\t\t fds[0], fds[1]);\n+\t\tbreak;\n+\tcase VHOST_MSG_TYPE_INIT:\n+\t\tvid = rte_eth_vhost_get_vid_from_port_id(p->portid);\n+\t\tshare_device(vid);\n+\t\tbreak;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+probe_secondary(struct rte_vdev_device *dev)\n+{\n+\tint portid = eth_dev_vhost_attach(dev);\n+\tstruct rte_eth_dev *eth_dev;\n+\tstruct pmd_internal *internal;\n+\tstruct vhost_params p;\n+\n+\tif (portid < 0)\n+\t\treturn -1;\n+\n+\teth_dev = &rte_eth_devices[portid];\n+\tinternal = eth_dev->data->dev_private;\n+\n+\tif (!internal ||\n+\t    rte_atomic32_read(&internal->dev_attached) == 0) {\n+\t\tRTE_LOG(INFO, PMD, \"%s is not ready\\n\", dev->device.name);\n+\t\treturn 0;\n+\t}\n+\n+\tp.type = VHOST_MSG_TYPE_INIT;\n+\tp.portid = portid;\n+\tif (rte_eal_mp_sendmsg(\"vhost pmd\", &p, sizeof(p), NULL, 0) < 0) {\n+\t\tRTE_LOG(ERR, PMD, \"Failed to send request for init\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n rte_pmd_vhost_probe(struct rte_vdev_device *dev)\n {\n \tstruct rte_kvargs *kvlist = NULL;\n-\tint ret = 0;\n+\tint ret;\n \tchar *iface_name;\n \tuint16_t queues;\n \tuint64_t flags = 0;\n@@ -1167,6 +1331,15 @@ rte_pmd_vhost_probe(struct rte_vdev_device *dev)\n \tRTE_LOG(INFO, PMD, \"Initializing pmd_vhost for %s\\n\",\n \t\trte_vdev_device_name(dev));\n \n+\tret = rte_eal_mp_action_register(\"vhost pmd\", vhost_pmd_action);\n+\tif (ret < 0 && ret != -EEXIST) {\n+\t\tRTE_LOG(ERR, PMD, \"vhost fails to add action\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tif (rte_eal_process_type() == RTE_PROC_SECONDARY)\n+\t\treturn probe_secondary(dev);\n+\n \tkvlist = rte_kvargs_parse(rte_vdev_device_args(dev), valid_arguments);\n \tif (kvlist == NULL)\n \t\treturn -1;\n@@ -1216,6 +1389,7 @@ rte_pmd_vhost_probe(struct rte_vdev_device *dev)\n \teth_dev_vhost_create(dev, iface_name, queues, dev->device.numa_node,\n \t\tflags);\n \n+\tret = 0;\n out_free:\n \trte_kvargs_free(kvlist);\n \treturn ret;\n",
    "prefixes": [
        "dpdk-dev",
        "v2",
        "12/12"
    ]
}