get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 26339,
    "url": "http://patches.dpdk.org/api/patches/26339/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20170704094922.11405-2-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": "<20170704094922.11405-2-maxime.coquelin@redhat.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20170704094922.11405-2-maxime.coquelin@redhat.com",
    "date": "2017-07-04T09:49:04",
    "name": "[dpdk-dev,RFC,01/19] vhost: protect virtio_net device struct",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "4403e03dfbf896f3603c019daeee2d0543565e4c",
    "submitter": {
        "id": 512,
        "url": "http://patches.dpdk.org/api/people/512/?format=api",
        "name": "Maxime Coquelin",
        "email": "maxime.coquelin@redhat.com"
    },
    "delegate": {
        "id": 355,
        "url": "http://patches.dpdk.org/api/users/355/?format=api",
        "username": "yliu",
        "first_name": "Yuanhan",
        "last_name": "Liu",
        "email": "yuanhan.liu@linux.intel.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20170704094922.11405-2-maxime.coquelin@redhat.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/26339/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/26339/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 [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id 9B80F377A;\n\tTue,  4 Jul 2017 11:49:43 +0200 (CEST)",
            "from mx1.redhat.com (mx1.redhat.com [209.132.183.28])\n\tby dpdk.org (Postfix) with ESMTP id 11EFB3195\n\tfor <dev@dpdk.org>; Tue,  4 Jul 2017 11:49:42 +0200 (CEST)",
            "from smtp.corp.redhat.com\n\t(int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11])\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 327057F6A2;\n\tTue,  4 Jul 2017 09:49:41 +0000 (UTC)",
            "from localhost.localdomain (ovpn-112-47.ams2.redhat.com\n\t[10.36.112.47])\n\tby smtp.corp.redhat.com (Postfix) with ESMTP id 48DE75C6CF;\n\tTue,  4 Jul 2017 09:49:38 +0000 (UTC)"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.3.2 mx1.redhat.com 327057F6A2",
        "Authentication-Results": [
            "ext-mx01.extmail.prod.ext.phx2.redhat.com;\n\tdmarc=none (p=none dis=none) header.from=redhat.com",
            "ext-mx01.extmail.prod.ext.phx2.redhat.com;\n\tspf=pass smtp.mailfrom=maxime.coquelin@redhat.com"
        ],
        "DKIM-Filter": "OpenDKIM Filter v2.11.0 mx1.redhat.com 327057F6A2",
        "From": "Maxime Coquelin <maxime.coquelin@redhat.com>",
        "To": "dev@dpdk.org,\n\tYuanhan Liu <yliu@fridaylinux.org>",
        "Cc": "mst@redhat.com, vkaplans@redhat.com, jasowang@redhat.com,\n\tjfreiman@redhat.com, Maxime Coquelin <maxime.coquelin@redhat.com>",
        "Date": "Tue,  4 Jul 2017 11:49:04 +0200",
        "Message-Id": "<20170704094922.11405-2-maxime.coquelin@redhat.com>",
        "In-Reply-To": "<20170704094922.11405-1-maxime.coquelin@redhat.com>",
        "References": "<20170704094922.11405-1-maxime.coquelin@redhat.com>",
        "X-Scanned-By": "MIMEDefang 2.79 on 10.5.11.11",
        "X-Greylist": "Sender IP whitelisted, not delayed by milter-greylist-4.5.16\n\t(mx1.redhat.com [10.5.110.25]); Tue, 04 Jul 2017 09:49:41 +0000 (UTC)",
        "Subject": "[dpdk-dev] [RFC 01/19] vhost: protect virtio_net device struct",
        "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": "virtio_net device might be accessed while being reallocated\nin case of NUMA awareness. This case might be theoretical,\nbut it will be needed anyway to protect vrings pages against\ninvalidation.\n\nThe virtio_net devs are now protected with a readers/writers\nlock, so that before reallocating the device, it is ensured\nthat it is not being referenced by the processing threads.\n\nSigned-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>\n---\n lib/librte_vhost/vhost.c      | 223 +++++++++++++++++++++++++++++++++++-------\n lib/librte_vhost/vhost.h      |   3 +-\n lib/librte_vhost/vhost_user.c |  73 +++++---------\n lib/librte_vhost/virtio_net.c |  17 +++-\n 4 files changed, 228 insertions(+), 88 deletions(-)",
    "diff": "diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c\nindex 19c5a43..2a4bc91 100644\n--- a/lib/librte_vhost/vhost.c\n+++ b/lib/librte_vhost/vhost.c\n@@ -45,16 +45,25 @@\n #include <rte_string_fns.h>\n #include <rte_memory.h>\n #include <rte_malloc.h>\n+#include <rte_rwlock.h>\n #include <rte_vhost.h>\n \n #include \"vhost.h\"\n \n-struct virtio_net *vhost_devices[MAX_VHOST_DEVICE];\n+struct vhost_device {\n+\tstruct virtio_net *dev;\n+\trte_rwlock_t lock;\n+};\n \n-struct virtio_net *\n-get_device(int vid)\n+/* Declared as static so that .lock is initialized */\n+static struct vhost_device vhost_devices[MAX_VHOST_DEVICE];\n+\n+static inline struct virtio_net *\n+__get_device(int vid)\n {\n-\tstruct virtio_net *dev = vhost_devices[vid];\n+\tstruct virtio_net *dev;\n+\n+\tdev = vhost_devices[vid].dev;\n \n \tif (unlikely(!dev)) {\n \t\tRTE_LOG(ERR, VHOST_CONFIG,\n@@ -64,6 +73,78 @@ get_device(int vid)\n \treturn dev;\n }\n \n+struct virtio_net *\n+get_device(int vid)\n+{\n+\tstruct virtio_net *dev;\n+\n+\trte_rwlock_read_lock(&vhost_devices[vid].lock);\n+\n+\tdev = __get_device(vid);\n+\tif (unlikely(!dev))\n+\t\trte_rwlock_read_unlock(&vhost_devices[vid].lock);\n+\n+\treturn dev;\n+}\n+\n+void\n+put_device(int vid)\n+{\n+\trte_rwlock_read_unlock(&vhost_devices[vid].lock);\n+}\n+\n+static struct virtio_net *\n+get_device_wr(int vid)\n+{\n+\tstruct virtio_net *dev;\n+\n+\trte_rwlock_write_lock(&vhost_devices[vid].lock);\n+\n+\tdev = __get_device(vid);\n+\tif (unlikely(!dev))\n+\t\trte_rwlock_write_unlock(&vhost_devices[vid].lock);\n+\n+\treturn dev;\n+}\n+\n+static void\n+put_device_wr(int vid)\n+{\n+\trte_rwlock_write_unlock(&vhost_devices[vid].lock);\n+}\n+\n+int\n+realloc_device(int vid, int vq_index, int node)\n+{\n+\tstruct virtio_net *dev, *old_dev;\n+\tstruct vhost_virtqueue *vq;\n+\n+\tdev = rte_malloc_socket(NULL, sizeof(*dev), 0, node);\n+\tif (!dev)\n+\t\treturn -1;\n+\n+\tvq = rte_malloc_socket(NULL, sizeof(*vq), 0, node);\n+\tif (!vq)\n+\t\treturn -1;\n+\n+\told_dev = get_device_wr(vid);\n+\tif (!old_dev)\n+\t\treturn -1;\n+\n+\tmemcpy(dev, old_dev, sizeof(*dev));\n+\tmemcpy(vq, old_dev->virtqueue[vq_index], sizeof(*vq));\n+\tdev->virtqueue[vq_index] = vq;\n+\n+\trte_free(old_dev->virtqueue[vq_index]);\n+\trte_free(old_dev);\n+\n+\tvhost_devices[vid].dev = dev;\n+\n+\tput_device_wr(vid);\n+\n+\treturn 0;\n+}\n+\n static void\n cleanup_vq(struct vhost_virtqueue *vq, int destroy)\n {\n@@ -194,7 +275,7 @@ vhost_new_device(void)\n \t}\n \n \tfor (i = 0; i < MAX_VHOST_DEVICE; i++) {\n-\t\tif (vhost_devices[i] == NULL)\n+\t\tif (vhost_devices[i].dev == NULL)\n \t\t\tbreak;\n \t}\n \tif (i == MAX_VHOST_DEVICE) {\n@@ -204,8 +285,10 @@ vhost_new_device(void)\n \t\treturn -1;\n \t}\n \n-\tvhost_devices[i] = dev;\n+\trte_rwlock_write_lock(&vhost_devices[i].lock);\n+\tvhost_devices[i].dev = dev;\n \tdev->vid = i;\n+\trte_rwlock_write_unlock(&vhost_devices[i].lock);\n \n \treturn i;\n }\n@@ -227,10 +310,15 @@ vhost_destroy_device(int vid)\n \t\tdev->notify_ops->destroy_device(vid);\n \t}\n \n+\tput_device(vid);\n+\tdev = get_device_wr(vid);\n+\n \tcleanup_device(dev, 1);\n \tfree_device(dev);\n \n-\tvhost_devices[vid] = NULL;\n+\tvhost_devices[vid].dev = NULL;\n+\n+\tput_device_wr(vid);\n }\n \n void\n@@ -248,6 +336,8 @@ vhost_set_ifname(int vid, const char *if_name, unsigned int if_len)\n \n \tstrncpy(dev->ifname, if_name, len);\n \tdev->ifname[sizeof(dev->ifname) - 1] = '\\0';\n+\n+\tput_device(vid);\n }\n \n void\n@@ -259,25 +349,30 @@ vhost_enable_dequeue_zero_copy(int vid)\n \t\treturn;\n \n \tdev->dequeue_zero_copy = 1;\n+\n+\tput_device(vid);\n }\n \n int\n rte_vhost_get_mtu(int vid, uint16_t *mtu)\n {\n \tstruct virtio_net *dev = get_device(vid);\n+\tint ret = 0;\n \n \tif (!dev)\n \t\treturn -ENODEV;\n \n \tif (!(dev->flags & VIRTIO_DEV_READY))\n-\t\treturn -EAGAIN;\n+\t\tret = -EAGAIN;\n \n \tif (!(dev->features & VIRTIO_NET_F_MTU))\n-\t\treturn -ENOTSUP;\n+\t\tret = -ENOTSUP;\n \n \t*mtu = dev->mtu;\n \n-\treturn 0;\n+\tput_device(vid);\n+\n+\treturn ret;\n }\n \n int\n@@ -296,9 +391,11 @@ rte_vhost_get_numa_node(int vid)\n \tif (ret < 0) {\n \t\tRTE_LOG(ERR, VHOST_CONFIG,\n \t\t\t\"(%d) failed to query numa node: %d\\n\", vid, ret);\n-\t\treturn -1;\n+\t\tnuma_node = -1;\n \t}\n \n+\tput_device(vid);\n+\n \treturn numa_node;\n #else\n \tRTE_SET_USED(vid);\n@@ -310,22 +407,32 @@ uint32_t\n rte_vhost_get_queue_num(int vid)\n {\n \tstruct virtio_net *dev = get_device(vid);\n+\tuint32_t queue_num;\n \n \tif (dev == NULL)\n \t\treturn 0;\n \n-\treturn dev->nr_vring / 2;\n+\tqueue_num = dev->nr_vring / 2;\n+\n+\tput_device(vid);\n+\n+\treturn queue_num;\n }\n \n uint16_t\n rte_vhost_get_vring_num(int vid)\n {\n \tstruct virtio_net *dev = get_device(vid);\n+\tuint16_t vring_num;\n \n \tif (dev == NULL)\n \t\treturn 0;\n \n-\treturn dev->nr_vring;\n+\tvring_num = dev->nr_vring;\n+\n+\tput_device(vid);\n+\n+\treturn vring_num;\n }\n \n int\n@@ -341,6 +448,8 @@ rte_vhost_get_ifname(int vid, char *buf, size_t len)\n \tstrncpy(buf, dev->ifname, len);\n \tbuf[len - 1] = '\\0';\n \n+\tput_device(vid);\n+\n \treturn 0;\n }\n \n@@ -354,6 +463,9 @@ rte_vhost_get_negotiated_features(int vid, uint64_t *features)\n \t\treturn -1;\n \n \t*features = dev->features;\n+\n+\tput_device(vid);\n+\n \treturn 0;\n }\n \n@@ -363,6 +475,7 @@ rte_vhost_get_mem_table(int vid, struct rte_vhost_memory **mem)\n \tstruct virtio_net *dev;\n \tstruct rte_vhost_memory *m;\n \tsize_t size;\n+\tint ret = 0;\n \n \tdev = get_device(vid);\n \tif (!dev)\n@@ -370,14 +483,19 @@ rte_vhost_get_mem_table(int vid, struct rte_vhost_memory **mem)\n \n \tsize = dev->mem->nregions * sizeof(struct rte_vhost_mem_region);\n \tm = malloc(sizeof(struct rte_vhost_memory) + size);\n-\tif (!m)\n-\t\treturn -1;\n+\tif (!m) {\n+\t\tret = -1;\n+\t\tgoto out;\n+\t}\n \n \tm->nregions = dev->mem->nregions;\n \tmemcpy(m->regions, dev->mem->regions, size);\n \t*mem = m;\n \n-\treturn 0;\n+out:\n+\tput_device(vid);\n+\n+\treturn ret;\n }\n \n int\n@@ -386,17 +504,22 @@ rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,\n {\n \tstruct virtio_net *dev;\n \tstruct vhost_virtqueue *vq;\n+\tint ret = 0;\n \n \tdev = get_device(vid);\n \tif (!dev)\n \t\treturn -1;\n \n-\tif (vring_idx >= VHOST_MAX_VRING)\n-\t\treturn -1;\n+\tif (vring_idx >= VHOST_MAX_VRING) {\n+\t\tret = -1;\n+\t\tgoto out;\n+\t}\n \n \tvq = dev->virtqueue[vring_idx];\n-\tif (!vq)\n-\t\treturn -1;\n+\tif (!vq) {\n+\t\tret = -1;\n+\t\tgoto out;\n+\t}\n \n \tvring->desc  = vq->desc;\n \tvring->avail = vq->avail;\n@@ -407,7 +530,10 @@ rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,\n \tvring->kickfd  = vq->kickfd;\n \tvring->size    = vq->size;\n \n-\treturn 0;\n+out:\n+\tput_device(vid);\n+\n+\treturn ret;\n }\n \n uint16_t\n@@ -415,6 +541,7 @@ rte_vhost_avail_entries(int vid, uint16_t queue_id)\n {\n \tstruct virtio_net *dev;\n \tstruct vhost_virtqueue *vq;\n+\tuint16_t avail_entries = 0;\n \n \tdev = get_device(vid);\n \tif (!dev)\n@@ -422,15 +549,23 @@ rte_vhost_avail_entries(int vid, uint16_t queue_id)\n \n \tvq = dev->virtqueue[queue_id];\n \tif (!vq->enabled)\n-\t\treturn 0;\n+\t\tgoto out;\n+\n \n-\treturn *(volatile uint16_t *)&vq->avail->idx - vq->last_used_idx;\n+\tavail_entries = *(volatile uint16_t *)&vq->avail->idx;\n+\tavail_entries -= vq->last_used_idx;\n+\n+out:\n+\tput_device(vid);\n+\n+\treturn avail_entries;\n }\n \n int\n rte_vhost_enable_guest_notification(int vid, uint16_t queue_id, int enable)\n {\n \tstruct virtio_net *dev = get_device(vid);\n+\tint ret = 0;\n \n \tif (dev == NULL)\n \t\treturn -1;\n@@ -438,11 +573,16 @@ rte_vhost_enable_guest_notification(int vid, uint16_t queue_id, int enable)\n \tif (enable) {\n \t\tRTE_LOG(ERR, VHOST_CONFIG,\n \t\t\t\"guest notification isn't supported.\\n\");\n-\t\treturn -1;\n+\t\tret = -1;\n+\t\tgoto out;\n \t}\n \n \tdev->virtqueue[queue_id]->used->flags = VRING_USED_F_NO_NOTIFY;\n-\treturn 0;\n+\n+out:\n+\tput_device(vid);\n+\n+\treturn ret;\n }\n \n void\n@@ -454,6 +594,8 @@ rte_vhost_log_write(int vid, uint64_t addr, uint64_t len)\n \t\treturn;\n \n \tvhost_log_write(dev, addr, len);\n+\n+\tput_device(vid);\n }\n \n void\n@@ -468,12 +610,15 @@ rte_vhost_log_used_vring(int vid, uint16_t vring_idx,\n \t\treturn;\n \n \tif (vring_idx >= VHOST_MAX_VRING)\n-\t\treturn;\n+\t\tgoto out;\n \tvq = dev->virtqueue[vring_idx];\n \tif (!vq)\n-\t\treturn;\n+\t\tgoto out;\n \n \tvhost_log_used_vring(dev, vq, offset, len);\n+\n+out:\n+\tput_device(vid);\n }\n \n uint32_t\n@@ -481,6 +626,7 @@ rte_vhost_rx_queue_count(int vid, uint16_t qid)\n {\n \tstruct virtio_net *dev;\n \tstruct vhost_virtqueue *vq;\n+\tuint32_t queue_count;\n \n \tdev = get_device(vid);\n \tif (dev == NULL)\n@@ -489,15 +635,26 @@ rte_vhost_rx_queue_count(int vid, uint16_t qid)\n \tif (unlikely(qid >= dev->nr_vring || (qid & 1) == 0)) {\n \t\tRTE_LOG(ERR, VHOST_DATA, \"(%d) %s: invalid virtqueue idx %d.\\n\",\n \t\t\tdev->vid, __func__, qid);\n-\t\treturn 0;\n+\t\tqueue_count = 0;\n+\t\tgoto out;\n \t}\n \n \tvq = dev->virtqueue[qid];\n-\tif (vq == NULL)\n-\t\treturn 0;\n+\tif (vq == NULL) {\n+\t\tqueue_count = 0;\n+\t\tgoto out;\n+\t}\n \n-\tif (unlikely(vq->enabled == 0 || vq->avail == NULL))\n-\t\treturn 0;\n+\tif (unlikely(vq->enabled == 0 || vq->avail == NULL)) {\n+\t\tqueue_count = 0;\n+\t\tgoto out;\n+\t}\n+\n+\tqueue_count = *((volatile uint16_t *)&vq->avail->idx);\n+\tqueue_count -= vq->last_avail_idx;\n+\n+out:\n+\tput_device(vid);\n \n-\treturn *((volatile uint16_t *)&vq->avail->idx) - vq->last_avail_idx;\n+\treturn queue_count;\n }\ndiff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h\nindex 0f294f3..18ad69c 100644\n--- a/lib/librte_vhost/vhost.h\n+++ b/lib/librte_vhost/vhost.h\n@@ -269,7 +269,6 @@ vhost_log_used_vring(struct virtio_net *dev, struct vhost_virtqueue *vq,\n \n extern uint64_t VHOST_FEATURES;\n #define MAX_VHOST_DEVICE\t1024\n-extern struct virtio_net *vhost_devices[MAX_VHOST_DEVICE];\n \n /* Convert guest physical address to host physical address */\n static __rte_always_inline phys_addr_t\n@@ -292,6 +291,8 @@ gpa_to_hpa(struct virtio_net *dev, uint64_t gpa, uint64_t size)\n }\n \n struct virtio_net *get_device(int vid);\n+void put_device(int vid);\n+int realloc_device(int vid, int vq_index, int node);\n \n int vhost_new_device(void);\n void cleanup_device(struct virtio_net *dev, int destroy);\ndiff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c\nindex ad2e8d3..5b3b881 100644\n--- a/lib/librte_vhost/vhost_user.c\n+++ b/lib/librte_vhost/vhost_user.c\n@@ -241,62 +241,31 @@ vhost_user_set_vring_num(struct virtio_net *dev,\n static struct virtio_net*\n numa_realloc(struct virtio_net *dev, int index)\n {\n-\tint oldnode, newnode;\n-\tstruct virtio_net *old_dev;\n-\tstruct vhost_virtqueue *old_vq, *vq;\n-\tint ret;\n+\tint oldnode, newnode, vid, ret;\n \n-\told_dev = dev;\n-\tvq = old_vq = dev->virtqueue[index];\n+\tvid = dev->vid;\n \n-\tret = get_mempolicy(&newnode, NULL, 0, old_vq->desc,\n+\tret = get_mempolicy(&newnode, NULL, 0, dev->virtqueue[index]->desc,\n \t\t\t    MPOL_F_NODE | MPOL_F_ADDR);\n \n \t/* check if we need to reallocate vq */\n-\tret |= get_mempolicy(&oldnode, NULL, 0, old_vq,\n+\tret |= get_mempolicy(&oldnode, NULL, 0, dev->virtqueue[index],\n \t\t\t     MPOL_F_NODE | MPOL_F_ADDR);\n \tif (ret) {\n \t\tRTE_LOG(ERR, VHOST_CONFIG,\n \t\t\t\"Unable to get vq numa information.\\n\");\n \t\treturn dev;\n \t}\n-\tif (oldnode != newnode) {\n-\t\tRTE_LOG(INFO, VHOST_CONFIG,\n-\t\t\t\"reallocate vq from %d to %d node\\n\", oldnode, newnode);\n-\t\tvq = rte_malloc_socket(NULL, sizeof(*vq), 0, newnode);\n-\t\tif (!vq)\n-\t\t\treturn dev;\n-\n-\t\tmemcpy(vq, old_vq, sizeof(*vq));\n-\t\trte_free(old_vq);\n-\t}\n \n-\t/* check if we need to reallocate dev */\n-\tret = get_mempolicy(&oldnode, NULL, 0, old_dev,\n-\t\t\t    MPOL_F_NODE | MPOL_F_ADDR);\n-\tif (ret) {\n-\t\tRTE_LOG(ERR, VHOST_CONFIG,\n-\t\t\t\"Unable to get dev numa information.\\n\");\n-\t\tgoto out;\n-\t}\n \tif (oldnode != newnode) {\n \t\tRTE_LOG(INFO, VHOST_CONFIG,\n-\t\t\t\"reallocate dev from %d to %d node\\n\",\n-\t\t\toldnode, newnode);\n-\t\tdev = rte_malloc_socket(NULL, sizeof(*dev), 0, newnode);\n-\t\tif (!dev) {\n-\t\t\tdev = old_dev;\n-\t\t\tgoto out;\n-\t\t}\n-\n-\t\tmemcpy(dev, old_dev, sizeof(*dev));\n-\t\trte_free(old_dev);\n+\t\t\t\"reallocate vq from %d to %d node\\n\", oldnode, newnode);\n+\t\tput_device(vid);\n+\t\tif (realloc_device(vid, index, newnode))\n+\t\t\tRTE_LOG(ERR, VHOST_CONFIG, \"Failed to realloc device\\n\");\n+\t\tdev = get_device(vid);\n \t}\n \n-out:\n-\tdev->virtqueue[index] = vq;\n-\tvhost_devices[dev->vid] = dev;\n-\n \treturn dev;\n }\n #else\n@@ -336,9 +305,10 @@ qva_to_vva(struct virtio_net *dev, uint64_t qva)\n  * This function then converts these to our address space.\n  */\n static int\n-vhost_user_set_vring_addr(struct virtio_net *dev, VhostUserMsg *msg)\n+vhost_user_set_vring_addr(struct virtio_net **pdev, VhostUserMsg *msg)\n {\n \tstruct vhost_virtqueue *vq;\n+\tstruct virtio_net *dev = *pdev;\n \n \tif (dev->mem == NULL)\n \t\treturn -1;\n@@ -356,7 +326,7 @@ vhost_user_set_vring_addr(struct virtio_net *dev, VhostUserMsg *msg)\n \t\treturn -1;\n \t}\n \n-\tdev = numa_realloc(dev, msg->payload.addr.index);\n+\t*pdev = dev = numa_realloc(dev, msg->payload.addr.index);\n \tvq = dev->virtqueue[msg->payload.addr.index];\n \n \tvq->avail = (struct vring_avail *)(uintptr_t)qva_to_vva(dev,\n@@ -966,7 +936,7 @@ vhost_user_msg_handler(int vid, int fd)\n {\n \tstruct virtio_net *dev;\n \tstruct VhostUserMsg msg;\n-\tint ret;\n+\tint ret = 0;\n \n \tdev = get_device(vid);\n \tif (dev == NULL)\n@@ -978,7 +948,8 @@ vhost_user_msg_handler(int vid, int fd)\n \t\t\tRTE_LOG(ERR, VHOST_CONFIG,\n \t\t\t\t\"failed to get callback ops for driver %s\\n\",\n \t\t\t\tdev->ifname);\n-\t\t\treturn -1;\n+\t\t\tret = -1;\n+\t\t\tgoto out;\n \t\t}\n \t}\n \n@@ -994,10 +965,10 @@ vhost_user_msg_handler(int vid, int fd)\n \t\t\tRTE_LOG(ERR, VHOST_CONFIG,\n \t\t\t\t\"vhost read incorrect message\\n\");\n \n-\t\treturn -1;\n+\t\tret = -1;\n+\t\tgoto out;\n \t}\n \n-\tret = 0;\n \tRTE_LOG(INFO, VHOST_CONFIG, \"read message %s\\n\",\n \t\tvhost_message_str[msg.request]);\n \n@@ -1005,7 +976,8 @@ vhost_user_msg_handler(int vid, int fd)\n \tif (ret < 0) {\n \t\tRTE_LOG(ERR, VHOST_CONFIG,\n \t\t\t\"failed to alloc queue\\n\");\n-\t\treturn -1;\n+\t\tret = -1;\n+\t\tgoto out;\n \t}\n \n \tswitch (msg.request) {\n@@ -1054,7 +1026,7 @@ vhost_user_msg_handler(int vid, int fd)\n \t\tvhost_user_set_vring_num(dev, &msg);\n \t\tbreak;\n \tcase VHOST_USER_SET_VRING_ADDR:\n-\t\tvhost_user_set_vring_addr(dev, &msg);\n+\t\tvhost_user_set_vring_addr(&dev, &msg);\n \t\tbreak;\n \tcase VHOST_USER_SET_VRING_BASE:\n \t\tvhost_user_set_vring_base(dev, &msg);\n@@ -1122,5 +1094,8 @@ vhost_user_msg_handler(int vid, int fd)\n \t\t}\n \t}\n \n-\treturn 0;\n+out:\n+\tput_device(vid);\n+\n+\treturn ret;\n }\ndiff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c\nindex ebfda1c..726d349 100644\n--- a/lib/librte_vhost/virtio_net.c\n+++ b/lib/librte_vhost/virtio_net.c\n@@ -587,14 +587,19 @@ rte_vhost_enqueue_burst(int vid, uint16_t queue_id,\n \tstruct rte_mbuf **pkts, uint16_t count)\n {\n \tstruct virtio_net *dev = get_device(vid);\n+\tint ret = 0;\n \n \tif (!dev)\n \t\treturn 0;\n \n \tif (dev->features & (1 << VIRTIO_NET_F_MRG_RXBUF))\n-\t\treturn virtio_dev_merge_rx(dev, queue_id, pkts, count);\n+\t\tret = virtio_dev_merge_rx(dev, queue_id, pkts, count);\n \telse\n-\t\treturn virtio_dev_rx(dev, queue_id, pkts, count);\n+\t\tret = virtio_dev_rx(dev, queue_id, pkts, count);\n+\n+\tput_device(vid);\n+\n+\treturn ret;\n }\n \n static inline bool\n@@ -993,12 +998,12 @@ rte_vhost_dequeue_burst(int vid, uint16_t queue_id,\n \tif (unlikely(!is_valid_virt_queue_idx(queue_id, 1, dev->nr_vring))) {\n \t\tRTE_LOG(ERR, VHOST_DATA, \"(%d) %s: invalid virtqueue idx %d.\\n\",\n \t\t\tdev->vid, __func__, queue_id);\n-\t\treturn 0;\n+\t\tgoto out;\n \t}\n \n \tvq = dev->virtqueue[queue_id];\n \tif (unlikely(vq->enabled == 0))\n-\t\treturn 0;\n+\t\tgoto out;\n \n \tif (unlikely(dev->dequeue_zero_copy)) {\n \t\tstruct zcopy_mbuf *zmbuf, *next;\n@@ -1048,7 +1053,7 @@ rte_vhost_dequeue_burst(int vid, uint16_t queue_id,\n \t\tif (rarp_mbuf == NULL) {\n \t\t\tRTE_LOG(ERR, VHOST_DATA,\n \t\t\t\t\"Failed to allocate memory for mbuf.\\n\");\n-\t\t\treturn 0;\n+\t\t\tgoto out;\n \t\t}\n \n \t\tif (make_rarp_packet(rarp_mbuf, &dev->mac)) {\n@@ -1167,5 +1172,7 @@ rte_vhost_dequeue_burst(int vid, uint16_t queue_id,\n \t\ti += 1;\n \t}\n \n+\tput_device(vid);\n+\n \treturn i;\n }\n",
    "prefixes": [
        "dpdk-dev",
        "RFC",
        "01/19"
    ]
}