get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 71266,
    "url": "https://patches.dpdk.org/api/patches/71266/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1591869725-13331-2-git-send-email-patrick.fu@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": "<1591869725-13331-2-git-send-email-patrick.fu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1591869725-13331-2-git-send-email-patrick.fu@intel.com",
    "date": "2020-06-11T10:02:04",
    "name": "[v1,1/2] vhost: introduce async data path registration API",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "bf74f2f85aa68f14ebab826cb78ca1f86b417fb1",
    "submitter": {
        "id": 1781,
        "url": "https://patches.dpdk.org/api/people/1781/?format=api",
        "name": "Patrick Fu",
        "email": "patrick.fu@intel.com"
    },
    "delegate": {
        "id": 2642,
        "url": "https://patches.dpdk.org/api/users/2642/?format=api",
        "username": "mcoquelin",
        "first_name": "Maxime",
        "last_name": "Coquelin",
        "email": "maxime.coquelin@redhat.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1591869725-13331-2-git-send-email-patrick.fu@intel.com/mbox/",
    "series": [
        {
            "id": 10407,
            "url": "https://patches.dpdk.org/api/series/10407/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=10407",
            "date": "2020-06-11T10:02:03",
            "name": "introduce asynchronous data path for vhost",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/10407/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/71266/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/71266/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 596FBA00C5;\n\tThu, 11 Jun 2020 12:14:04 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id A4AE81BDF8;\n\tThu, 11 Jun 2020 12:14:03 +0200 (CEST)",
            "from mga01.intel.com (mga01.intel.com [192.55.52.88])\n by dpdk.org (Postfix) with ESMTP id B84BF1BDF8\n for <dev@dpdk.org>; Thu, 11 Jun 2020 12:14:01 +0200 (CEST)",
            "from fmsmga004.fm.intel.com ([10.253.24.48])\n by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 11 Jun 2020 03:14:00 -0700",
            "from npg-dpdk-patrickfu-sl1.sh.intel.com ([10.67.117.45])\n by fmsmga004.fm.intel.com with ESMTP; 11 Jun 2020 03:13:58 -0700"
        ],
        "IronPort-SDR": [
            "\n zVsjiQT8vgkYHeae/9k0Ap9ZLEMxP7TYD08U7H0ppklMrSiL7rla2GpUGLbO1VJHlZEOOcDyxD\n 21UagHlw/VyA==",
            "\n tcQORwqLzyvtKuhYUmoNrl688G6IvyZn1q6yVRu/J/HqYe3+9nujCVY7VFaV0+0iVzO3ympH7q\n ns+iI2hOp32A=="
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.73,499,1583222400\"; d=\"scan'208\";a=\"296542271\"",
        "From": "patrick.fu@intel.com",
        "To": "dev@dpdk.org, maxime.coquelin@redhat.com, chenbo.xia@intel.com,\n zhihong.wang@intel.com, xiaolong.ye@intel.com",
        "Cc": "patrick.fu@intel.com,\n\tcheng1.jiang@intel.com,\n\tcunming.liang@intel.com",
        "Date": "Thu, 11 Jun 2020 18:02:04 +0800",
        "Message-Id": "<1591869725-13331-2-git-send-email-patrick.fu@intel.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1591869725-13331-1-git-send-email-patrick.fu@intel.com>",
        "References": "<1591869725-13331-1-git-send-email-patrick.fu@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v1 1/2] vhost: introduce async data path\n\tregistration API",
        "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 <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 <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Patrick <patrick.fu@intel.com>\n\nThis patch introduces registration/un-registration APIs\nfor async data path together with all required data\nstructures and DMA callback function proto-types.\n\nSigned-off-by: Patrick <patrick.fu@intel.com>\n---\n lib/librte_vhost/Makefile          |   3 +-\n lib/librte_vhost/rte_vhost.h       |   1 +\n lib/librte_vhost/rte_vhost_async.h | 134 +++++++++++++++++++++++++++++++++++++\n lib/librte_vhost/socket.c          |  20 ++++++\n lib/librte_vhost/vhost.c           |  74 +++++++++++++++++++-\n lib/librte_vhost/vhost.h           |  30 ++++++++-\n lib/librte_vhost/vhost_user.c      |  28 ++++++--\n 7 files changed, 283 insertions(+), 7 deletions(-)\n create mode 100644 lib/librte_vhost/rte_vhost_async.h",
    "diff": "diff --git a/lib/librte_vhost/Makefile b/lib/librte_vhost/Makefile\nindex e592795..3aed094 100644\n--- a/lib/librte_vhost/Makefile\n+++ b/lib/librte_vhost/Makefile\n@@ -41,7 +41,8 @@ SRCS-$(CONFIG_RTE_LIBRTE_VHOST) := fd_man.c iotlb.c socket.c vhost.c \\\n \t\t\t\t\tvhost_user.c virtio_net.c vdpa.c\n \n # install includes\n-SYMLINK-$(CONFIG_RTE_LIBRTE_VHOST)-include += rte_vhost.h rte_vdpa.h\n+SYMLINK-$(CONFIG_RTE_LIBRTE_VHOST)-include += rte_vhost.h rte_vdpa.h \\\n+\t\t\t\t\t\trte_vhost_async.h\n \n # only compile vhost crypto when cryptodev is enabled\n ifeq ($(CONFIG_RTE_LIBRTE_CRYPTODEV),y)\ndiff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h\nindex d43669f..cec4d07 100644\n--- a/lib/librte_vhost/rte_vhost.h\n+++ b/lib/librte_vhost/rte_vhost.h\n@@ -35,6 +35,7 @@\n #define RTE_VHOST_USER_EXTBUF_SUPPORT\t(1ULL << 5)\n /* support only linear buffers (no chained mbufs) */\n #define RTE_VHOST_USER_LINEARBUF_SUPPORT\t(1ULL << 6)\n+#define RTE_VHOST_USER_ASYNC_COPY\t(1ULL << 7)\n \n /** Protocol features. */\n #ifndef VHOST_USER_PROTOCOL_F_MQ\ndiff --git a/lib/librte_vhost/rte_vhost_async.h b/lib/librte_vhost/rte_vhost_async.h\nnew file mode 100644\nindex 0000000..82f2ebe\n--- /dev/null\n+++ b/lib/librte_vhost/rte_vhost_async.h\n@@ -0,0 +1,134 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2018 Intel Corporation\n+ */\n+\n+#ifndef _RTE_VHOST_ASYNC_H_\n+#define _RTE_VHOST_ASYNC_H_\n+\n+#include \"rte_vhost.h\"\n+\n+/**\n+ * iovec iterator\n+ */\n+struct iov_it {\n+\t/** offset to the first byte of interesting data */\n+\tsize_t offset;\n+\t/** total bytes of data in this iterator */\n+\tsize_t count;\n+\t/** pointer to the iovec array */\n+\tstruct iovec *iov;\n+\t/** number of iovec in this iterator */\n+\tunsigned long nr_segs;\n+};\n+\n+/**\n+ * dma transfer descriptor pair\n+ */\n+struct dma_trans_desc {\n+\t/** source memory iov_it */\n+\tstruct iov_it *src;\n+\t/** destination memory iov_it */\n+\tstruct iov_it *dst;\n+};\n+\n+/**\n+ * dma transfer status\n+ */\n+struct dma_trans_status {\n+\t/** An array of application specific data for source memory */\n+\tuintptr_t *src_opaque_data;\n+\t/** An array of application specific data for destination memory */\n+\tuintptr_t *dst_opaque_data;\n+};\n+\n+/**\n+ * dma operation callbacks to be implemented by applications\n+ */\n+struct rte_vhost_async_channel_ops {\n+\t/**\n+\t * instruct a DMA channel to perform copies for a batch of packets\n+\t *\n+\t * @param vid\n+\t *  id of vhost device to perform data copies\n+\t * @param queue_id\n+\t *  queue id to perform data copies\n+\t * @param descs\n+\t *  an array of DMA transfer memory descriptors\n+\t * @param opaque_data\n+\t *  opaque data pair sending to DMA engine\n+\t * @param count\n+\t *  number of elements in the \"descs\" array\n+\t * @return\n+\t *  -1 on failure, number of descs processed on success\n+\t */\n+\tint (*transfer_data)(int vid, uint16_t queue_id,\n+\t\tstruct dma_trans_desc *descs,\n+\t\tstruct dma_trans_status *opaque_data,\n+\t\tuint16_t count);\n+\t/**\n+\t * check copy-completed packets from a DMA channel\n+\t * @param vid\n+\t *  id of vhost device to check copy completion\n+\t * @param queue_id\n+\t *  queue id to check copyp completion\n+\t * @param opaque_data\n+\t *  buffer to receive the opaque data pair from DMA engine\n+\t * @param max_packets\n+\t *  max number of packets could be completed\n+\t * @return\n+\t *  -1 on failure, number of iov segments completed on success\n+\t */\n+\tint (*check_completed_copies)(int vid, uint16_t queue_id,\n+\t\tstruct dma_trans_status *opaque_data,\n+\t\tuint16_t max_packets);\n+};\n+\n+/**\n+ *  dma channel feature bit definition\n+ */\n+struct dma_channel_features {\n+\tunion {\n+\t\tuint32_t intval;\n+\t\tstruct {\n+\t\t\tuint32_t inorder:1;\n+\t\t\tuint32_t resvd0115:15;\n+\t\t\tuint32_t threshold:12;\n+\t\t\tuint32_t resvd2831:4;\n+\t\t};\n+\t};\n+};\n+\n+/**\n+ * register a dma channel for vhost\n+ *\n+ * @param vid\n+ *  vhost device id DMA channel to be attached to\n+ * @param queue_id\n+ *  vhost queue id DMA channel to be attached to\n+ * @param features\n+ *  DMA channel feature bit\n+ *    b0       : DMA supports inorder data transfer\n+ *    b1  - b15: reserved\n+ *    b16 - b27: Packet length threshold for DMA transfer\n+ *    b28 - b31: reserved\n+ * @param ops\n+ *  DMA operation callbacks\n+ * @return\n+ *  0 on success, -1 on failures\n+ */\n+int rte_vhost_async_channel_register(int vid, uint16_t queue_id,\n+\tuint32_t features, struct rte_vhost_async_channel_ops *ops);\n+\n+/**\n+ * unregister a dma channel for vhost\n+ *\n+ * @param vid\n+ *  vhost device id DMA channel to be detached\n+ * @param queue_id\n+ *  vhost queue id DMA channel to be detached\n+ * @return\n+ *  0 on success, -1 on failures\n+ */\n+int rte_vhost_async_channel_unregister(int vid, uint16_t queue_id);\n+\n+#endif /* _RTE_VDPA_H_ */\ndiff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c\nindex 0a66ef9..f817783 100644\n--- a/lib/librte_vhost/socket.c\n+++ b/lib/librte_vhost/socket.c\n@@ -42,6 +42,7 @@ struct vhost_user_socket {\n \tbool use_builtin_virtio_net;\n \tbool extbuf;\n \tbool linearbuf;\n+\tbool async_copy;\n \n \t/*\n \t * The \"supported_features\" indicates the feature bits the\n@@ -210,6 +211,7 @@ struct vhost_user {\n \tsize_t size;\n \tstruct vhost_user_connection *conn;\n \tint ret;\n+\tstruct virtio_net *dev;\n \n \tif (vsocket == NULL)\n \t\treturn;\n@@ -241,6 +243,13 @@ struct vhost_user {\n \tif (vsocket->linearbuf)\n \t\tvhost_enable_linearbuf(vid);\n \n+\tif (vsocket->async_copy) {\n+\t\tdev = get_device(vid);\n+\n+\t\tif (dev)\n+\t\t\tdev->async_copy = 1;\n+\t}\n+\n \tVHOST_LOG_CONFIG(INFO, \"new device, handle is %d\\n\", vid);\n \n \tif (vsocket->notify_ops->new_connection) {\n@@ -891,6 +900,17 @@ struct vhost_user_reconnect_list {\n \t\tgoto out_mutex;\n \t}\n \n+\tvsocket->async_copy = flags & RTE_VHOST_USER_ASYNC_COPY;\n+\n+\tif (vsocket->async_copy &&\n+\t\t(flags & (RTE_VHOST_USER_IOMMU_SUPPORT |\n+\t\tRTE_VHOST_USER_POSTCOPY_SUPPORT))) {\n+\t\tVHOST_LOG_CONFIG(ERR, \"error: enabling async copy and IOMMU \"\n+\t\t\t\"or post-copy feature simultaneously is not \"\n+\t\t\t\"supported\\n\");\n+\t\tgoto out_mutex;\n+\t}\n+\n \t/*\n \t * Set the supported features correctly for the builtin vhost-user\n \t * net driver.\ndiff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c\nindex 0266318..e6b688a 100644\n--- a/lib/librte_vhost/vhost.c\n+++ b/lib/librte_vhost/vhost.c\n@@ -332,8 +332,13 @@\n {\n \tif (vq_is_packed(dev))\n \t\trte_free(vq->shadow_used_packed);\n-\telse\n+\telse {\n \t\trte_free(vq->shadow_used_split);\n+\t\tif (vq->async_pkts_pending)\n+\t\t\trte_free(vq->async_pkts_pending);\n+\t\tif (vq->async_pending_info)\n+\t\t\trte_free(vq->async_pending_info);\n+\t}\n \trte_free(vq->batch_copy_elems);\n \trte_mempool_free(vq->iotlb_pool);\n \trte_free(vq);\n@@ -1527,3 +1532,70 @@ int rte_vhost_extern_callback_register(int vid,\n \tif (vhost_data_log_level >= 0)\n \t\trte_log_set_level(vhost_data_log_level, RTE_LOG_WARNING);\n }\n+\n+int rte_vhost_async_channel_register(int vid, uint16_t queue_id,\n+\t\t\t\t\tuint32_t features,\n+\t\t\t\t\tstruct rte_vhost_async_channel_ops *ops)\n+{\n+\tstruct vhost_virtqueue *vq;\n+\tstruct virtio_net *dev = get_device(vid);\n+\tstruct dma_channel_features f;\n+\n+\tif (dev == NULL || ops == NULL)\n+\t\treturn -1;\n+\n+\tf.intval = features;\n+\n+\tvq = dev->virtqueue[queue_id];\n+\n+\tif (vq == NULL)\n+\t\treturn -1;\n+\n+\t/** packed queue is not supported */\n+\tif (vq_is_packed(dev) || !f.inorder)\n+\t\treturn -1;\n+\n+\tif (ops->check_completed_copies == NULL ||\n+\t\tops->transfer_data == NULL)\n+\t\treturn -1;\n+\n+\trte_spinlock_lock(&vq->access_lock);\n+\n+\tvq->async_ops.check_completed_copies = ops->check_completed_copies;\n+\tvq->async_ops.transfer_data = ops->transfer_data;\n+\n+\tvq->async_inorder = f.inorder;\n+\tvq->async_threshold = f.threshold;\n+\n+\tvq->async_registered = true;\n+\n+\trte_spinlock_unlock(&vq->access_lock);\n+\n+\treturn 0;\n+}\n+\n+int rte_vhost_async_channel_unregister(int vid, uint16_t queue_id)\n+{\n+\tstruct vhost_virtqueue *vq;\n+\tstruct virtio_net *dev = get_device(vid);\n+\n+\tif (dev == NULL)\n+\t\treturn -1;\n+\n+\tvq = dev->virtqueue[queue_id];\n+\n+\tif (vq == NULL)\n+\t\treturn -1;\n+\n+\trte_spinlock_lock(&vq->access_lock);\n+\n+\tvq->async_ops.transfer_data = NULL;\n+\tvq->async_ops.check_completed_copies = NULL;\n+\n+\tvq->async_registered = false;\n+\n+\trte_spinlock_unlock(&vq->access_lock);\n+\n+\treturn 0;\n+}\n+\ndiff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h\nindex df98d15..a7fbe23 100644\n--- a/lib/librte_vhost/vhost.h\n+++ b/lib/librte_vhost/vhost.h\n@@ -23,6 +23,8 @@\n #include \"rte_vhost.h\"\n #include \"rte_vdpa.h\"\n \n+#include \"rte_vhost_async.h\"\n+\n /* Used to indicate that the device is running on a data core */\n #define VIRTIO_DEV_RUNNING 1\n /* Used to indicate that the device is ready to operate */\n@@ -39,6 +41,11 @@\n \n #define VHOST_LOG_CACHE_NR 32\n \n+#define MAX_PKT_BURST 32\n+\n+#define VHOST_MAX_ASYNC_IT (MAX_PKT_BURST * 2)\n+#define VHOST_MAX_ASYNC_VEC (BUF_VECTOR_MAX * 2)\n+\n #define PACKED_DESC_ENQUEUE_USED_FLAG(w)\t\\\n \t((w) ? (VRING_DESC_F_AVAIL | VRING_DESC_F_USED | VRING_DESC_F_WRITE) : \\\n \t\tVRING_DESC_F_WRITE)\n@@ -200,6 +207,25 @@ struct vhost_virtqueue {\n \tTAILQ_HEAD(, vhost_iotlb_entry) iotlb_list;\n \tint\t\t\t\tiotlb_cache_nr;\n \tTAILQ_HEAD(, vhost_iotlb_entry) iotlb_pending_list;\n+\n+\t/* operation callbacks for async dma */\n+\tstruct rte_vhost_async_channel_ops\tasync_ops;\n+\n+\tstruct iov_it it_pool[VHOST_MAX_ASYNC_IT];\n+\tstruct iovec vec_pool[VHOST_MAX_ASYNC_VEC];\n+\n+\t/* async data transfer status */\n+\tuintptr_t\t**async_pkts_pending;\n+\t#define\t\tASYNC_PENDING_INFO_N_MSK 0xFFFF\n+\t#define\t\tASYNC_PENDING_INFO_N_SFT 16\n+\tuint64_t\t*async_pending_info;\n+\tuint16_t\tasync_pkts_idx;\n+\tuint16_t\tasync_pkts_inflight_n;\n+\n+\t/* vq async features */\n+\tbool\t\tasync_inorder;\n+\tbool\t\tasync_registered;\n+\tuint16_t\tasync_threshold;\n } __rte_cache_aligned;\n \n /* Old kernels have no such macros defined */\n@@ -353,6 +379,7 @@ struct virtio_net {\n \tint16_t\t\t\tbroadcast_rarp;\n \tuint32_t\t\tnr_vring;\n \tint\t\t\tdequeue_zero_copy;\n+\tint\t\t\tasync_copy;\n \tint\t\t\textbuf;\n \tint\t\t\tlinearbuf;\n \tstruct vhost_virtqueue\t*virtqueue[VHOST_MAX_QUEUE_PAIRS * 2];\n@@ -702,7 +729,8 @@ uint64_t translate_log_addr(struct virtio_net *dev, struct vhost_virtqueue *vq,\n \t/* Don't kick guest if we don't reach index specified by guest. */\n \tif (dev->features & (1ULL << VIRTIO_RING_F_EVENT_IDX)) {\n \t\tuint16_t old = vq->signalled_used;\n-\t\tuint16_t new = vq->last_used_idx;\n+\t\tuint16_t new = vq->async_pkts_inflight_n ?\n+\t\t\t\t\tvq->used->idx:vq->last_used_idx;\n \t\tbool signalled_used_valid = vq->signalled_used_valid;\n \n \t\tvq->signalled_used = new;\ndiff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c\nindex 84bebad..d7600bf 100644\n--- a/lib/librte_vhost/vhost_user.c\n+++ b/lib/librte_vhost/vhost_user.c\n@@ -464,12 +464,25 @@\n \t} else {\n \t\tif (vq->shadow_used_split)\n \t\t\trte_free(vq->shadow_used_split);\n+\t\tif (vq->async_pkts_pending)\n+\t\t\trte_free(vq->async_pkts_pending);\n+\t\tif (vq->async_pending_info)\n+\t\t\trte_free(vq->async_pending_info);\n+\n \t\tvq->shadow_used_split = rte_malloc(NULL,\n \t\t\t\tvq->size * sizeof(struct vring_used_elem),\n \t\t\t\tRTE_CACHE_LINE_SIZE);\n-\t\tif (!vq->shadow_used_split) {\n+\t\tvq->async_pkts_pending = rte_malloc(NULL,\n+\t\t\t\tvq->size * sizeof(uintptr_t),\n+\t\t\t\tRTE_CACHE_LINE_SIZE);\n+\t\tvq->async_pending_info = rte_malloc(NULL,\n+\t\t\t\tvq->size * sizeof(uint64_t),\n+\t\t\t\tRTE_CACHE_LINE_SIZE);\n+\t\tif (!vq->shadow_used_split ||\n+\t\t\t!vq->async_pkts_pending ||\n+\t\t\t!vq->async_pending_info) {\n \t\t\tVHOST_LOG_CONFIG(ERR,\n-\t\t\t\t\t\"failed to allocate memory for shadow used ring.\\n\");\n+\t\t\t\t\t\"failed to allocate memory for vq internal data.\\n\");\n \t\t\treturn RTE_VHOST_MSG_RESULT_ERR;\n \t\t}\n \t}\n@@ -1147,7 +1160,8 @@\n \t\t\tgoto err_mmap;\n \t\t}\n \n-\t\tpopulate = (dev->dequeue_zero_copy) ? MAP_POPULATE : 0;\n+\t\tpopulate = (dev->dequeue_zero_copy || dev->async_copy) ?\n+\t\t\tMAP_POPULATE : 0;\n \t\tmmap_addr = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE,\n \t\t\t\t MAP_SHARED | populate, fd, 0);\n \n@@ -1162,7 +1176,7 @@\n \t\treg->host_user_addr = (uint64_t)(uintptr_t)mmap_addr +\n \t\t\t\t      mmap_offset;\n \n-\t\tif (dev->dequeue_zero_copy)\n+\t\tif (dev->dequeue_zero_copy || dev->async_copy)\n \t\t\tif (add_guest_pages(dev, reg, alignment) < 0) {\n \t\t\t\tVHOST_LOG_CONFIG(ERR,\n \t\t\t\t\t\"adding guest pages to region %u failed.\\n\",\n@@ -1945,6 +1959,12 @@ static int vhost_user_set_vring_err(struct virtio_net **pdev __rte_unused,\n \t} else {\n \t\trte_free(vq->shadow_used_split);\n \t\tvq->shadow_used_split = NULL;\n+\t\tif (vq->async_pkts_pending)\n+\t\t\trte_free(vq->async_pkts_pending);\n+\t\tif (vq->async_pending_info)\n+\t\t\trte_free(vq->async_pending_info);\n+\t\tvq->async_pkts_pending = NULL;\n+\t\tvq->async_pending_info = NULL;\n \t}\n \n \trte_free(vq->batch_copy_elems);\n",
    "prefixes": [
        "v1",
        "1/2"
    ]
}