get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 58228,
    "url": "http://patches.dpdk.org/api/patches/58228/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20190829080000.20806-11-maxime.coquelin@redhat.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": "<20190829080000.20806-11-maxime.coquelin@redhat.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20190829080000.20806-11-maxime.coquelin@redhat.com",
    "date": "2019-08-29T07:59:55",
    "name": "[10/15] net/virtio: add vDPA op to configure and start the device",
    "commit_ref": null,
    "pull_url": null,
    "state": "rejected",
    "archived": true,
    "hash": "a1765b364440e57787e0e0a67919c37911c2fc11",
    "submitter": {
        "id": 512,
        "url": "http://patches.dpdk.org/api/people/512/?format=api",
        "name": "Maxime Coquelin",
        "email": "maxime.coquelin@redhat.com"
    },
    "delegate": {
        "id": 2642,
        "url": "http://patches.dpdk.org/api/users/2642/?format=api",
        "username": "mcoquelin",
        "first_name": "Maxime",
        "last_name": "Coquelin",
        "email": "maxime.coquelin@redhat.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20190829080000.20806-11-maxime.coquelin@redhat.com/mbox/",
    "series": [
        {
            "id": 6163,
            "url": "http://patches.dpdk.org/api/series/6163/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=6163",
            "date": "2019-08-29T07:59:45",
            "name": "Introduce Virtio vDPA driver",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/6163/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/58228/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/58228/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 3262A1D502;\n\tThu, 29 Aug 2019 10:00:53 +0200 (CEST)",
            "from mx1.redhat.com (mx1.redhat.com [209.132.183.28])\n\tby dpdk.org (Postfix) with ESMTP id 3F91C1D16B;\n\tThu, 29 Aug 2019 10:00:52 +0200 (CEST)",
            "from smtp.corp.redhat.com\n\t(int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby mx1.redhat.com (Postfix) with ESMTPS id A4E6E4E926;\n\tThu, 29 Aug 2019 08:00:51 +0000 (UTC)",
            "from localhost.localdomain (ovpn-112-52.ams2.redhat.com\n\t[10.36.112.52])\n\tby smtp.corp.redhat.com (Postfix) with ESMTP id 0567D5D713;\n\tThu, 29 Aug 2019 08:00:46 +0000 (UTC)"
        ],
        "From": "Maxime Coquelin <maxime.coquelin@redhat.com>",
        "To": "tiwei.bie@intel.com, zhihong.wang@intel.com, amorenoz@redhat.com,\n\txiao.w.wang@intel.com, dev@dpdk.org, jfreimann@redhat.com",
        "Cc": "stable@dpdk.org,\n\tMaxime Coquelin <maxime.coquelin@redhat.com>",
        "Date": "Thu, 29 Aug 2019 09:59:55 +0200",
        "Message-Id": "<20190829080000.20806-11-maxime.coquelin@redhat.com>",
        "In-Reply-To": "<20190829080000.20806-1-maxime.coquelin@redhat.com>",
        "References": "<20190829080000.20806-1-maxime.coquelin@redhat.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-Scanned-By": "MIMEDefang 2.79 on 10.5.11.15",
        "X-Greylist": "Sender IP whitelisted, not delayed by milter-greylist-4.5.16\n\t(mx1.redhat.com [10.5.110.38]); Thu, 29 Aug 2019 08:00:51 +0000 (UTC)",
        "Subject": "[dpdk-dev] [PATCH 10/15] net/virtio: add vDPA op to configure and\n\tstart the device",
        "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": "In order to support multi-queue, we need to implement the control\npath. The problem is that both the Vhost-user master and slave use\nVAs in their processes address spaces as IOVAs, which creates\ncollusions between the data rings IOVAs managed the master, and\nthe Control ring IOVAs. The trick here is to remmap the Control\nring memory to another range, after the slave is aware of master's\nranges.\n\nSigned-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>\n---\n drivers/net/virtio/virtio_vdpa.c | 255 +++++++++++++++++++++++++++++++\n 1 file changed, 255 insertions(+)",
    "diff": "diff --git a/drivers/net/virtio/virtio_vdpa.c b/drivers/net/virtio/virtio_vdpa.c\nindex fc52a8e92..13b4dd07d 100644\n--- a/drivers/net/virtio/virtio_vdpa.c\n+++ b/drivers/net/virtio/virtio_vdpa.c\n@@ -106,6 +106,127 @@ find_internal_resource_by_dev(struct rte_pci_device *pdev)\n \treturn list;\n }\n \n+static int\n+virtio_vdpa_dma_map_ctrl_queue(struct virtio_vdpa_device *dev, int do_map,\n+\t\tuint64_t iova)\n+{\n+\tconst struct rte_memzone *mz;\n+\tint ret;\n+\n+\t/*\n+\t * IOVAs are processes VAs. We cannot use them as the Data and Control\n+\t * paths are run in different processes, which may (does) lead to\n+\t * collusions. The trick here is to fixup Ctrl path IOVAs so that they\n+\t * start after the Data path ranges.\n+\t */\n+\tif (do_map) {\n+\t\tmz = dev->cvq->cq.mz;\n+\t\tret = rte_vfio_container_dma_map(dev->vfio_container_fd,\n+\t\t\t\t(uint64_t)(uintptr_t)mz->addr,\n+\t\t\t\tiova, mz->len);\n+\t\tif (ret < 0) {\n+\t\t\tDRV_LOG(ERR, \"Failed to map ctrl ring (%d)\", ret);\n+\t\t\treturn ret;\n+\t\t}\n+\n+\t\tdev->cvq->vq_ring_mem = iova;\n+\t\tiova += mz->len;\n+\n+\t\tmz = dev->cvq->cq.virtio_net_hdr_mz;\n+\t\tret = rte_vfio_container_dma_map(dev->vfio_container_fd,\n+\t\t\t\t(uint64_t)(uintptr_t)mz->addr,\n+\t\t\t\tiova, mz->len);\n+\t\tif (ret < 0) {\n+\t\t\tDRV_LOG(ERR, \"Failed to map ctrl headers (%d)\", ret);\n+\t\t\treturn ret;\n+\t\t}\n+\n+\t\tdev->cvq->cq.virtio_net_hdr_mem = iova;\n+\t} else {\n+\t\tmz = dev->cvq->cq.mz;\n+\t\tret = rte_vfio_container_dma_unmap(dev->vfio_container_fd,\n+\t\t\t\t(uint64_t)(uintptr_t)mz->addr,\n+\t\t\t\tiova, mz->len);\n+\t\tif (ret < 0) {\n+\t\t\tDRV_LOG(ERR, \"Failed to unmap ctrl ring (%d)\", ret);\n+\t\t\treturn ret;\n+\t\t}\n+\n+\t\tdev->cvq->vq_ring_mem = 0;\n+\t\tiova += mz->len;\n+\n+\t\tmz = dev->cvq->cq.virtio_net_hdr_mz;\n+\t\tret = rte_vfio_container_dma_unmap(dev->vfio_container_fd,\n+\t\t\t\t(uint64_t)(uintptr_t)mz->addr,\n+\t\t\t\tiova, mz->len);\n+\t\tif (ret < 0) {\n+\t\t\tDRV_LOG(ERR, \"Failed to unmap ctrl headers (%d)\", ret);\n+\t\t\treturn ret;\n+\t\t}\n+\n+\t\tdev->cvq->cq.virtio_net_hdr_mem = 0;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+virtio_vdpa_dma_map(struct virtio_vdpa_device *dev, int do_map)\n+{\n+\tuint32_t i;\n+\tint ret;\n+\tstruct rte_vhost_memory *mem = NULL;\n+\tint vfio_container_fd;\n+\tuint64_t avail_iova = 0;\n+\n+\tret = rte_vhost_get_mem_table(dev->vid, &mem);\n+\tif (ret < 0 || !mem) {\n+\t\tDRV_LOG(ERR, \"failed to get VM memory layout.\");\n+\t\treturn ret;\n+\t}\n+\n+\tvfio_container_fd = dev->vfio_container_fd;\n+\n+\tfor (i = 0; i < mem->nregions; i++) {\n+\t\tstruct rte_vhost_mem_region *reg;\n+\n+\t\treg = &mem->regions[i];\n+\t\tDRV_LOG(INFO, \"%s, region %u: HVA 0x%\" PRIx64 \", \"\n+\t\t\t\"GPA 0x%\" PRIx64 \", size 0x%\" PRIx64 \".\",\n+\t\t\tdo_map ? \"DMA map\" : \"DMA unmap\", i,\n+\t\t\treg->host_user_addr, reg->guest_phys_addr, reg->size);\n+\n+\t\tif (reg->guest_phys_addr + reg->size > avail_iova)\n+\t\t\tavail_iova = reg->guest_phys_addr + reg->size;\n+\n+\t\tif (do_map) {\n+\t\t\tret = rte_vfio_container_dma_map(vfio_container_fd,\n+\t\t\t\treg->host_user_addr, reg->guest_phys_addr,\n+\t\t\t\treg->size);\n+\t\t\tif (ret < 0) {\n+\t\t\t\tDRV_LOG(ERR, \"DMA map failed.\");\n+\t\t\t\tgoto exit;\n+\t\t\t}\n+\t\t} else {\n+\t\t\tret = rte_vfio_container_dma_unmap(vfio_container_fd,\n+\t\t\t\treg->host_user_addr, reg->guest_phys_addr,\n+\t\t\t\treg->size);\n+\t\t\tif (ret < 0) {\n+\t\t\t\tDRV_LOG(ERR, \"DMA unmap failed.\");\n+\t\t\t\tgoto exit;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\tif (dev->cvq)\n+\t\tret = virtio_vdpa_dma_map_ctrl_queue(dev, do_map, avail_iova);\n+\n+exit:\n+\tfree(mem);\n+\n+\treturn ret;\n+}\n+\n static int\n virtio_vdpa_vfio_setup(struct virtio_vdpa_device *dev)\n {\n@@ -216,10 +337,144 @@ virtio_vdpa_get_protocol_features(int did __rte_unused, uint64_t *features)\n \treturn 0;\n }\n \n+static uint64_t\n+hva_to_gpa(int vid, uint64_t hva)\n+{\n+\tstruct rte_vhost_memory *mem = NULL;\n+\tstruct rte_vhost_mem_region *reg;\n+\tuint32_t i;\n+\tuint64_t gpa = 0;\n+\n+\tif (rte_vhost_get_mem_table(vid, &mem) < 0)\n+\t\tgoto exit;\n+\n+\tfor (i = 0; i < mem->nregions; i++) {\n+\t\treg = &mem->regions[i];\n+\n+\t\tif (hva >= reg->host_user_addr &&\n+\t\t\t\thva < reg->host_user_addr + reg->size) {\n+\t\t\tgpa = hva - reg->host_user_addr + reg->guest_phys_addr;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+exit:\n+\tif (mem)\n+\t\tfree(mem);\n+\treturn gpa;\n+}\n+\n+static int\n+virtio_vdpa_start(struct virtio_vdpa_device *dev)\n+{\n+\tstruct virtio_hw *hw = &dev->hw;\n+\tint i, vid, nr_vring, ret;\n+\tstruct rte_vhost_vring vr;\n+\tstruct virtio_pmd_ctrl ctrl;\n+\tint dlen[1];\n+\n+\tvid = dev->vid;\n+\tnr_vring = rte_vhost_get_vring_num(vid);\n+\n+\tif (dev->vqs)\n+\t\trte_free(dev->vqs);\n+\n+\tdev->vqs = rte_zmalloc(\"virtio_vdpa\", sizeof(*dev->vqs) * nr_vring, 0);\n+\n+\tfor (i = 0; i < nr_vring; i++) {\n+\t\tstruct virtqueue *vq = &dev->vqs[i];\n+\n+\t\trte_vhost_get_vhost_vring(vid, i, &vr);\n+\n+\t\tvq->vq_queue_index = i;\n+\t\tvq->vq_nentries = vr.size;\n+\t\tvq->vq_ring_mem = hva_to_gpa(vid, (uint64_t)(uintptr_t)vr.desc);\n+\t\tif (vq->vq_ring_mem  == 0) {\n+\t\t\tDRV_LOG(ERR, \"Fail to get GPA for descriptor ring.\");\n+\t\t\tret = -1;\n+\t\t\tgoto out_free_vqs;\n+\t\t}\n+\n+\t\tret = VTPCI_OPS(hw)->setup_queue(hw, vq);\n+\t\tif (ret) {\n+\t\t\tDRV_LOG(ERR, \"Fail to setup queue.\");\n+\t\t\tgoto out_free_vqs;\n+\t\t}\n+\t}\n+\n+\tif (dev->cvq) {\n+\t\tret = VTPCI_OPS(hw)->setup_queue(hw, dev->cvq);\n+\t\tif (ret) {\n+\t\t\tDRV_LOG(ERR, \"Fail to setup ctrl queue.\");\n+\t\t\tgoto out_free_vqs;\n+\t\t}\n+\t}\n+\n+\tvtpci_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER_OK);\n+\n+\tif (!dev->cvq)\n+\t\treturn 0;\n+\n+\tctrl.hdr.class = VIRTIO_NET_CTRL_MQ;\n+\tctrl.hdr.cmd = VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET;\n+\tmemcpy(ctrl.data, &dev->max_queue_pairs, sizeof(uint16_t));\n+\n+\tdlen[0] = sizeof(uint16_t);\n+\n+\tret = virtio_send_command(hw->cvq, &ctrl, dlen, 1);\n+\tif (ret) {\n+\t\tDRV_LOG(ERR, \"Multiqueue configured but send command \"\n+\t\t\t  \"failed, this is too late now...\");\n+\t\tret = -EINVAL;\n+\t\tgoto out_free_vqs;\n+\t}\n+\n+\treturn 0;\n+out_free_vqs:\n+\trte_free(dev->vqs);\n+\n+\treturn ret;\n+}\n+\n+static int\n+virtio_vdpa_dev_config(int vid)\n+{\n+\tint did, ret;\n+\tstruct internal_list *list;\n+\tstruct virtio_vdpa_device *dev;\n+\n+\tdid = rte_vhost_get_vdpa_device_id(vid);\n+\tlist = find_internal_resource_by_did(did);\n+\tif (list == NULL) {\n+\t\tDRV_LOG(ERR, \"Invalid device id: %d\", did);\n+\t\treturn -1;\n+\t}\n+\n+\tdev = list->dev;\n+\tdev->vid = vid;\n+\n+\trte_spinlock_lock(&dev->lock);\n+\n+\tret = virtio_vdpa_dma_map(dev, 1);\n+\tif (ret)\n+\t\tgoto out_unlock;\n+\n+\tret = virtio_vdpa_start(dev);\n+\n+\tif (rte_vhost_host_notifier_ctrl(vid, true) != 0)\n+\t\tDRV_LOG(NOTICE, \"vDPA (%d): software relay is used.\", did);\n+\n+out_unlock:\n+\trte_spinlock_unlock(&dev->lock);\n+\n+\treturn ret;\n+}\n+\n static struct rte_vdpa_dev_ops virtio_vdpa_ops = {\n \t.get_queue_num = virtio_vdpa_get_queue_num,\n \t.get_features = virtio_vdpa_get_features,\n \t.get_protocol_features = virtio_vdpa_get_protocol_features,\n+\t.dev_conf = virtio_vdpa_dev_config,\n };\n \n static inline int\n",
    "prefixes": [
        "10/15"
    ]
}