get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 58618,
    "url": "http://patchwork.dpdk.org/api/patches/58618/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20190905161421.55981-10-yong.liu@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.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": "<20190905161421.55981-10-yong.liu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20190905161421.55981-10-yong.liu@intel.com",
    "date": "2019-09-05T16:14:16",
    "name": "[v1,09/14] vhost: split enqueue and dequeue flush functions",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "da3384804cf7f65f901b4d2a326d0000979b5371",
    "submitter": {
        "id": 17,
        "url": "http://patchwork.dpdk.org/api/people/17/?format=api",
        "name": "Marvin Liu",
        "email": "yong.liu@intel.com"
    },
    "delegate": {
        "id": 2642,
        "url": "http://patchwork.dpdk.org/api/users/2642/?format=api",
        "username": "mcoquelin",
        "first_name": "Maxime",
        "last_name": "Coquelin",
        "email": "maxime.coquelin@redhat.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20190905161421.55981-10-yong.liu@intel.com/mbox/",
    "series": [
        {
            "id": 6248,
            "url": "http://patchwork.dpdk.org/api/series/6248/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=6248",
            "date": "2019-09-05T16:14:07",
            "name": "vhost packed ring performance optimization",
            "version": 1,
            "mbox": "http://patchwork.dpdk.org/series/6248/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/58618/comments/",
    "check": "success",
    "checks": "http://patchwork.dpdk.org/api/patches/58618/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 72D011EF25;\n\tThu,  5 Sep 2019 10:34:54 +0200 (CEST)",
            "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n\tby dpdk.org (Postfix) with ESMTP id DDE481EE1A\n\tfor <dev@dpdk.org>; Thu,  5 Sep 2019 10:34:41 +0200 (CEST)",
            "from fmsmga006.fm.intel.com ([10.253.24.20])\n\tby orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t05 Sep 2019 01:34:41 -0700",
            "from npg-dpdk-virtual-marvin-dev.sh.intel.com ([10.67.119.142])\n\tby fmsmga006.fm.intel.com with ESMTP; 05 Sep 2019 01:34:40 -0700"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.64,470,1559545200\"; d=\"scan'208\";a=\"383781582\"",
        "From": "Marvin Liu <yong.liu@intel.com>",
        "To": "tiwei.bie@intel.com,\n\tmaxime.coquelin@redhat.com,\n\tdev@dpdk.org",
        "Cc": "Marvin Liu <yong.liu@intel.com>",
        "Date": "Fri,  6 Sep 2019 00:14:16 +0800",
        "Message-Id": "<20190905161421.55981-10-yong.liu@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20190905161421.55981-1-yong.liu@intel.com>",
        "References": "<20190905161421.55981-1-yong.liu@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v1 09/14] vhost: split enqueue and dequeue flush\n\tfunctions",
        "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": "Vhost enqueue descriptors are updated by burst number, while vhost\ndequeue descriptors are buffered. Meanwhile in dequeue function only\nfirst descriptor is buffered. Due to these differences, split vhost\nenqueue and dequeue flush functions.\n\nSigned-off-by: Marvin Liu <yong.liu@intel.com>",
    "diff": "diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c\nindex f8ad54e18..8d09e1611 100644\n--- a/lib/librte_vhost/virtio_net.c\n+++ b/lib/librte_vhost/virtio_net.c\n@@ -92,7 +92,7 @@ update_shadow_split(struct vhost_virtqueue *vq,\n }\n \n static __rte_always_inline void\n-flush_shadow_packed(struct virtio_net *dev, struct vhost_virtqueue *vq)\n+flush_enqueue_shadow_packed(struct virtio_net *dev, struct vhost_virtqueue *vq)\n {\n \tint i;\n \tuint16_t used_idx = vq->last_used_idx;\n@@ -157,6 +157,33 @@ flush_shadow_packed(struct virtio_net *dev, struct vhost_virtqueue *vq)\n \tvhost_log_cache_sync(dev, vq);\n }\n \n+static __rte_always_inline void\n+flush_dequeue_shadow_packed(struct virtio_net *dev, struct vhost_virtqueue *vq)\n+{\n+\tuint16_t head_idx = vq->dequeue_shadow_head;\n+\tuint16_t head_flags;\n+\n+\tif (vq->shadow_used_packed[0].used_wrap_counter)\n+\t\thead_flags = VIRTIO_TX_USED_FLAG;\n+\telse\n+\t\thead_flags = VIRTIO_TX_USED_WRAP_FLAG;\n+\n+\tif (vq->shadow_used_packed[0].len)\n+\t\thead_flags |= VRING_DESC_F_WRITE;\n+\n+\tvq->desc_packed[head_idx].id = vq->shadow_used_packed[0].id;\n+\n+\trte_smp_wmb();\n+\tvq->desc_packed[head_idx].flags = head_flags;\n+\n+\tvhost_log_cache_used_vring(dev, vq, head_idx *\n+\t\t\t\t   sizeof(struct vring_packed_desc),\n+\t\t\t\t   sizeof(struct vring_packed_desc));\n+\n+\tvq->shadow_used_idx = 0;\n+\tvhost_log_cache_sync(dev, vq);\n+}\n+\n static __rte_always_inline void\n flush_burst_packed(struct virtio_net *dev, struct vhost_virtqueue *vq,\n \tuint64_t len, uint64_t len1, uint64_t len2, uint64_t len3, uint16_t id,\n@@ -195,6 +222,52 @@ flush_burst_packed(struct virtio_net *dev, struct vhost_virtqueue *vq,\n \t}\n }\n \n+static __rte_always_inline void\n+update_dequeue_burst_packed(struct virtio_net *dev, struct vhost_virtqueue *vq,\n+\tuint16_t id, uint16_t id1, uint16_t id2, uint16_t id3)\n+{\n+\tuint16_t flags = 0;\n+\n+\tif (vq->used_wrap_counter)\n+\t\tflags = VIRTIO_TX_USED_FLAG;\n+\telse\n+\t\tflags = VIRTIO_TX_USED_WRAP_FLAG;\n+\n+\tif (!vq->shadow_used_idx) {\n+\t\tvq->dequeue_shadow_head = vq->last_used_idx;\n+\n+\t\tvq->shadow_used_packed[0].id  = id;\n+\t\tvq->shadow_used_packed[0].len = 0;\n+\t\tvq->shadow_used_packed[0].count = 1;\n+\t\tvq->shadow_used_packed[0].used_idx = vq->last_used_idx;\n+\t\tvq->shadow_used_packed[0].used_wrap_counter =\n+\t\t\tvq->used_wrap_counter;\n+\n+\t\tvq->desc_packed[vq->last_used_idx + 1].id = id1;\n+\t\tvq->desc_packed[vq->last_used_idx + 2].id = id2;\n+\t\tvq->desc_packed[vq->last_used_idx + 3].id = id3;\n+\n+\t\trte_smp_wmb();\n+\t\tvq->desc_packed[vq->last_used_idx + 1].flags = flags;\n+\t\trte_smp_wmb();\n+\t\tvq->desc_packed[vq->last_used_idx + 2].flags = flags;\n+\t\trte_smp_wmb();\n+\t\tvq->desc_packed[vq->last_used_idx + 3].flags = flags;\n+\n+\t\tvq->shadow_used_idx = 1;\n+\n+\t\tvq->last_used_idx += PACKED_DESCS_BURST;\n+\t\tif (vq->last_used_idx >= vq->size) {\n+\t\t\tvq->used_wrap_counter ^= 1;\n+\t\t\tvq->last_used_idx -= vq->size;\n+\t\t}\n+\t} else {\n+\n+\t\tflush_burst_packed(dev, vq, 0, 0, 0, 0, id, id1, id2, id3,\n+\t\t\t\t   flags);\n+\t}\n+}\n+\n static __rte_always_inline void\n flush_enqueue_burst_packed(struct virtio_net *dev, struct vhost_virtqueue *vq,\n \tuint64_t len, uint64_t len1, uint64_t len2, uint64_t len3, uint16_t id,\n@@ -316,11 +389,29 @@ flush_enqueue_packed(struct virtio_net *dev,\n \n \t\tif (vq->enqueue_shadow_count >= PACKED_DESCS_BURST) {\n \t\t\tdo_data_copy_enqueue(dev, vq);\n-\t\t\tflush_shadow_packed(dev, vq);\n+\t\t\tflush_enqueue_shadow_packed(dev, vq);\n \t\t}\n \t}\n }\n \n+static __rte_unused void\n+flush_dequeue_packed(struct virtio_net *dev, struct vhost_virtqueue *vq)\n+{\n+\tif (!vq->shadow_used_idx)\n+\t\treturn;\n+\n+\tint16_t shadow_count = vq->last_used_idx - vq->dequeue_shadow_head;\n+\tif (shadow_count <= 0)\n+\t\tshadow_count += vq->size;\n+\n+\t/* buffer used descs as many as possible when doing dequeue */\n+\tif ((uint16_t)shadow_count >= (vq->size >> 1)) {\n+\t\tdo_data_copy_dequeue(vq);\n+\t\tflush_dequeue_shadow_packed(dev, vq);\n+\t\tvhost_vring_call_packed(dev, vq);\n+\t}\n+}\n+\n /* avoid write operation when necessary, to lessen cache issues */\n #define ASSIGN_UNLESS_EQUAL(var, val) do {\t\\\n \tif ((var) != (val))\t\t\t\\\n@@ -1211,7 +1302,7 @@ virtio_dev_rx_packed(struct virtio_net *dev, struct vhost_virtqueue *vq,\n \tdo_data_copy_enqueue(dev, vq);\n \n \tif (likely(vq->shadow_used_idx)) {\n-\t\tflush_shadow_packed(dev, vq);\n+\t\tflush_enqueue_shadow_packed(dev, vq);\n \t\tvhost_vring_call_packed(dev, vq);\n \t}\n \n@@ -1869,6 +1960,8 @@ virtio_dev_tx_burst_packed(struct virtio_net *dev, struct vhost_virtqueue *vq,\n \t\t(void *)(uintptr_t)(desc_addr[3] + buf_offset),\n \t\tpkts[3]->pkt_len);\n \n+\tupdate_dequeue_burst_packed(dev, vq, ids[0], ids[1], ids[2], ids[3]);\n+\n \tif (virtio_net_with_host_offload(dev)) {\n \t\thdr = (struct virtio_net_hdr *)((uintptr_t)desc_addr[0]);\n \t\thdr1 = (struct virtio_net_hdr *)((uintptr_t)desc_addr[1]);\n@@ -1972,7 +2065,7 @@ virtio_dev_tx_packed(struct virtio_net *dev, struct vhost_virtqueue *vq,\n \t\t}\n \n \t\tif (likely(vq->shadow_used_idx)) {\n-\t\t\tflush_shadow_packed(dev, vq);\n+\t\t\tflush_dequeue_shadow_packed(dev, vq);\n \t\t\tvhost_vring_call_packed(dev, vq);\n \t\t}\n \t}\n@@ -2050,7 +2143,7 @@ virtio_dev_tx_packed(struct virtio_net *dev, struct vhost_virtqueue *vq,\n \t\tif (unlikely(i < count))\n \t\t\tvq->shadow_used_idx = i;\n \t\tif (likely(vq->shadow_used_idx)) {\n-\t\t\tflush_shadow_packed(dev, vq);\n+\t\t\tflush_dequeue_shadow_packed(dev, vq);\n \t\t\tvhost_vring_call_packed(dev, vq);\n \t\t}\n \t}\n",
    "prefixes": [
        "v1",
        "09/14"
    ]
}