get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 7279,
    "url": "https://patches.dpdk.org/api/patches/7279/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1443537953-23917-7-git-send-email-huawei.xie@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": "<1443537953-23917-7-git-send-email-huawei.xie@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1443537953-23917-7-git-send-email-huawei.xie@intel.com",
    "date": "2015-09-29T14:45:51",
    "name": "[dpdk-dev,6/8] virtio: virtio vec rx",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "c5d1018e351a973ca3a95bfac407c3a464c5e879",
    "submitter": {
        "id": 16,
        "url": "https://patches.dpdk.org/api/people/16/?format=api",
        "name": "Huawei Xie",
        "email": "huawei.xie@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1443537953-23917-7-git-send-email-huawei.xie@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/7279/comments/",
    "check": "pending",
    "checks": "https://patches.dpdk.org/api/patches/7279/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 8CC758E68;\n\tTue, 29 Sep 2015 16:46:51 +0200 (CEST)",
            "from mga14.intel.com (mga14.intel.com [192.55.52.115])\n\tby dpdk.org (Postfix) with ESMTP id B639C8DB2\n\tfor <dev@dpdk.org>; Tue, 29 Sep 2015 16:46:49 +0200 (CEST)",
            "from fmsmga002.fm.intel.com ([10.253.24.26])\n\tby fmsmga103.fm.intel.com with ESMTP; 29 Sep 2015 07:46:48 -0700",
            "from shvmail01.sh.intel.com ([10.239.29.42])\n\tby fmsmga002.fm.intel.com with ESMTP; 29 Sep 2015 07:46:47 -0700",
            "from shecgisg003.sh.intel.com (shecgisg003.sh.intel.com\n\t[10.239.29.90])\n\tby shvmail01.sh.intel.com with ESMTP id t8TEkifp024596;\n\tTue, 29 Sep 2015 22:46:44 +0800",
            "from shecgisg003.sh.intel.com (localhost [127.0.0.1])\n\tby shecgisg003.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP\n\tid t8TEkgOT023996; Tue, 29 Sep 2015 22:46:44 +0800",
            "(from hxie5@localhost)\n\tby shecgisg003.sh.intel.com (8.13.6/8.13.6/Submit) id t8TEkgPB023991; \n\tTue, 29 Sep 2015 22:46:42 +0800"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.17,608,1437462000\"; d=\"scan'208\";a=\"815356172\"",
        "From": "Huawei Xie <huawei.xie@intel.com>",
        "To": "dev@dpdk.org",
        "Date": "Tue, 29 Sep 2015 22:45:51 +0800",
        "Message-Id": "<1443537953-23917-7-git-send-email-huawei.xie@intel.com>",
        "X-Mailer": "git-send-email 1.7.4.1",
        "In-Reply-To": "<1443537953-23917-1-git-send-email-huawei.xie@intel.com>",
        "References": "<1443537953-23917-1-git-send-email-huawei.xie@intel.com>",
        "Subject": "[dpdk-dev] [PATCH 6/8] virtio: virtio vec rx",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <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": "With fixed avail ring, we don't need to get desc idx from avail ring.\nvirtio driver only has to deal with desc ring.\nThis patch uses vector instruction to accelerate processing desc ring.\n\nSigned-off-by: Huawei Xie <huawei.xie@intel.com>\n---\n drivers/net/virtio/virtio_ethdev.h      |   2 +\n drivers/net/virtio/virtio_rxtx.c        |  17 +++\n drivers/net/virtio/virtio_rxtx.h        |   2 +\n drivers/net/virtio/virtio_rxtx_simple.c | 224 ++++++++++++++++++++++++++++++++\n drivers/net/virtio/virtqueue.h          |   1 +\n 5 files changed, 246 insertions(+)",
    "diff": "diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h\nindex 9026d42..d7797ab 100644\n--- a/drivers/net/virtio/virtio_ethdev.h\n+++ b/drivers/net/virtio/virtio_ethdev.h\n@@ -108,6 +108,8 @@ uint16_t virtio_recv_mergeable_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,\n uint16_t virtio_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,\n \t\tuint16_t nb_pkts);\n \n+uint16_t virtio_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,\n+\t\tuint16_t nb_pkts);\n \n /*\n  * The VIRTIO_NET_F_GUEST_TSO[46] features permit the host to send us\ndiff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c\nindex aab6724..b721336 100644\n--- a/drivers/net/virtio/virtio_rxtx.c\n+++ b/drivers/net/virtio/virtio_rxtx.c\n@@ -430,6 +430,9 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,\n \tvq->mpool = mp;\n \n \tdev->data->rx_queues[queue_idx] = vq;\n+\n+\tvirtio_rxq_vec_setup(vq);\n+\n \treturn 0;\n }\n \n@@ -858,6 +861,20 @@ virtio_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)\n \treturn nb_tx;\n }\n \n+uint16_t __attribute__((weak))\n+virtio_recv_pkts_vec(\n+\tvoid __rte_unused *rx_queue,\n+\tstruct rte_mbuf __rte_unused **rx_pkts,\n+\tuint16_t __rte_unused nb_pkts)\n+{\n+\treturn 0;\n+}\n+\n+int __attribute__((weak))\n+virtio_rxq_vec_setup(struct virtqueue __rte_unused *rxq)\n+{\n+\treturn -1;\n+}\n \n int __attribute__((weak))\n virtqueue_enqueue_recv_refill_simple(struct virtqueue __rte_unused *vq,\ndiff --git a/drivers/net/virtio/virtio_rxtx.h b/drivers/net/virtio/virtio_rxtx.h\nindex 7d2d8fe..19c871c 100644\n--- a/drivers/net/virtio/virtio_rxtx.h\n+++ b/drivers/net/virtio/virtio_rxtx.h\n@@ -33,5 +33,7 @@\n \n #define RTE_PMD_VIRTIO_RX_MAX_BURST 64\n \n+int virtio_rxq_vec_setup(struct virtqueue __rte_unused *rxq);\n+\n int virtqueue_enqueue_recv_refill_simple(struct virtqueue *vq,\n \tstruct rte_mbuf *m);\ndiff --git a/drivers/net/virtio/virtio_rxtx_simple.c b/drivers/net/virtio/virtio_rxtx_simple.c\nindex cac5b9f..3d57038 100644\n--- a/drivers/net/virtio/virtio_rxtx_simple.c\n+++ b/drivers/net/virtio/virtio_rxtx_simple.c\n@@ -58,6 +58,10 @@\n #include \"virtqueue.h\"\n #include \"virtio_rxtx.h\"\n \n+#define RTE_VIRTIO_VPMD_RX_BURST 32\n+#define RTE_VIRTIO_DESC_PER_LOOP 8\n+#define RTE_VIRTIO_VPMD_RX_REARM_THRESH RTE_VIRTIO_VPMD_RX_BURST\n+\n int __attribute__((cold))\n virtqueue_enqueue_recv_refill_simple(struct virtqueue *vq,\n \tstruct rte_mbuf *cookie)\n@@ -82,3 +86,223 @@ virtqueue_enqueue_recv_refill_simple(struct virtqueue *vq,\n \n \treturn 0;\n }\n+\n+static inline void\n+virtio_rxq_rearm_vec(struct virtqueue *rxvq)\n+{\n+\tint i;\n+\tuint16_t desc_idx;\n+\tstruct rte_mbuf **sw_ring;\n+\tstruct vring_desc *start_dp;\n+\tint ret;\n+\n+\tdesc_idx = rxvq->vq_avail_idx & (rxvq->vq_nentries - 1);\n+\tsw_ring = &rxvq->sw_ring[desc_idx];\n+\tstart_dp = &rxvq->vq_ring.desc[desc_idx];\n+\n+\tret = rte_mempool_get_bulk(rxvq->mpool, (void **)sw_ring,\n+\t\tRTE_VIRTIO_VPMD_RX_REARM_THRESH);\n+\tif (unlikely(ret)) {\n+\t\trte_eth_devices[rxvq->port_id].data->rx_mbuf_alloc_failed +=\n+\t\t\tRTE_VIRTIO_VPMD_RX_REARM_THRESH;\n+\t\treturn;\n+\t}\n+\n+\tfor (i = 0; i < RTE_VIRTIO_VPMD_RX_REARM_THRESH; i++) {\n+\t\tuintptr_t p;\n+\n+\t\tp = (uintptr_t)&sw_ring[i]->rearm_data;\n+\t\t*(uint64_t *)p = rxvq->mbuf_initializer;\n+\n+\t\tstart_dp[i].addr =\n+\t\t\t(uint64_t)((uintptr_t)sw_ring[i]->buf_physaddr +\n+\t\t\tRTE_PKTMBUF_HEADROOM - sizeof(struct virtio_net_hdr));\n+\t\tstart_dp[i].len = sw_ring[i]->buf_len -\n+\t\t\tRTE_PKTMBUF_HEADROOM + sizeof(struct virtio_net_hdr);\n+\t}\n+\n+\trxvq->vq_avail_idx += RTE_VIRTIO_VPMD_RX_REARM_THRESH;\n+\trxvq->vq_free_cnt -= RTE_VIRTIO_VPMD_RX_REARM_THRESH;\n+\tvq_update_avail_idx(rxvq);\n+}\n+\n+/*\n+ * virtio vPMD receive routine, only accept(nb_pkts >= RTE_VIRTIO_DESC_PER_LOOP)\n+ *\n+ * This routine is for non-mergable RX, one desc for each guest buffer.\n+ * This routine is based on the RX ring layout optimization. Each entry in the\n+ * avail ring points to the desc with the same index in the desc ring and this\n+ * will never be changed in the driver.\n+ *\n+ * - nb_pkts < RTE_VIRTIO_DESC_PER_LOOP, just return no packet\n+ */\n+uint16_t\n+virtio_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,\n+\tuint16_t nb_pkts)\n+{\n+\tstruct virtqueue *rxvq = rx_queue;\n+\tuint16_t nb_used;\n+\tuint16_t desc_idx;\n+\tstruct vring_used_elem *rused;\n+\tstruct rte_mbuf **sw_ring;\n+\tstruct rte_mbuf **sw_ring_end;\n+\tuint16_t nb_pkts_received;\n+\t__m128i shuf_msk1, shuf_msk2, len_adjust;\n+\n+\tshuf_msk1 = _mm_set_epi8(\n+\t\t0xFF, 0xFF, 0xFF, 0xFF,\n+\t\t0xFF, 0xFF,\t\t/* vlan tci */\n+\t\t5, 4,\t\t\t/* dat len */\n+\t\t0xFF, 0xFF, 5, 4,\t/* pkt len */\n+\t\t0xFF, 0xFF, 0xFF, 0xFF\t/* packet type */\n+\n+\t);\n+\n+\tshuf_msk2 = _mm_set_epi8(\n+\t\t0xFF, 0xFF, 0xFF, 0xFF,\n+\t\t0xFF, 0xFF,\t\t/* vlan tci */\n+\t\t13, 12,\t\t\t/* dat len */\n+\t\t0xFF, 0xFF, 13, 12,\t/* pkt len */\n+\t\t0xFF, 0xFF, 0xFF, 0xFF\t/* packet type */\n+\t);\n+\n+\t/* Substract the header length.\n+\t*  In which case do we need the header length in used->len ? */\n+\tlen_adjust = _mm_set_epi16(\n+\t\t0, 0,\n+\t\t0,\n+\t\t(uint16_t) -sizeof(struct virtio_net_hdr),\n+\t\t0, (uint16_t) -sizeof(struct virtio_net_hdr),\n+\t\t0, 0);\n+\n+\tif (unlikely(nb_pkts < RTE_VIRTIO_DESC_PER_LOOP))\n+\t\treturn 0;\n+\n+\tnb_used = *(volatile uint16_t *)&rxvq->vq_ring.used->idx -\n+\t\trxvq->vq_used_cons_idx;\n+\n+\trte_compiler_barrier();\n+\n+\tif (unlikely(nb_used == 0))\n+\t\treturn 0;\n+\n+\tnb_pkts = RTE_ALIGN_FLOOR(nb_pkts, RTE_VIRTIO_DESC_PER_LOOP);\n+\tnb_used = RTE_MIN(nb_used, nb_pkts);\n+\n+\tdesc_idx = (uint16_t)(rxvq->vq_used_cons_idx & (rxvq->vq_nentries - 1));\n+\trused = &rxvq->vq_ring.used->ring[desc_idx];\n+\tsw_ring  = &rxvq->sw_ring[desc_idx];\n+\tsw_ring_end = &rxvq->sw_ring[rxvq->vq_nentries];\n+\n+\t_mm_prefetch((const void *)rused, _MM_HINT_T0);\n+\n+\tif (rxvq->vq_free_cnt >= RTE_VIRTIO_VPMD_RX_REARM_THRESH) {\n+\t\tvirtio_rxq_rearm_vec(rxvq);\n+\t\tif (unlikely(virtqueue_kick_prepare(rxvq)))\n+\t\t\tvirtqueue_notify(rxvq);\n+\t}\n+\n+\tfor (nb_pkts_received = 0;\n+\t\tnb_pkts_received < nb_used;) {\n+\t\t__m128i desc[RTE_VIRTIO_DESC_PER_LOOP / 2];\n+\t\t__m128i mbp[RTE_VIRTIO_DESC_PER_LOOP / 2];\n+\t\t__m128i pkt_mb[RTE_VIRTIO_DESC_PER_LOOP];\n+\n+\t\tmbp[0] = _mm_loadu_si128((__m128i *)(sw_ring + 0));\n+\t\tdesc[0] = _mm_loadu_si128((__m128i *)(rused + 0));\n+\t\t_mm_storeu_si128((__m128i *)&rx_pkts[0], mbp[0]);\n+\n+\t\tmbp[1] = _mm_loadu_si128((__m128i *)(sw_ring + 2));\n+\t\tdesc[1] = _mm_loadu_si128((__m128i *)(rused + 2));\n+\t\t_mm_storeu_si128((__m128i *)&rx_pkts[2], mbp[1]);\n+\n+\t\tmbp[2] = _mm_loadu_si128((__m128i *)(sw_ring + 4));\n+\t\tdesc[2] = _mm_loadu_si128((__m128i *)(rused + 4));\n+\t\t_mm_storeu_si128((__m128i *)&rx_pkts[4], mbp[2]);\n+\n+\t\tmbp[3] = _mm_loadu_si128((__m128i *)(sw_ring + 6));\n+\t\tdesc[3] = _mm_loadu_si128((__m128i *)(rused + 6));\n+\t\t_mm_storeu_si128((__m128i *)&rx_pkts[6], mbp[3]);\n+\n+\t\tpkt_mb[1] = _mm_shuffle_epi8(desc[0], shuf_msk2);\n+\t\tpkt_mb[0] = _mm_shuffle_epi8(desc[0], shuf_msk1);\n+\t\tpkt_mb[1] = _mm_add_epi16(pkt_mb[1], len_adjust);\n+\t\tpkt_mb[0] = _mm_add_epi16(pkt_mb[0], len_adjust);\n+\t\t_mm_storeu_si128((void *)&rx_pkts[1]->rx_descriptor_fields1,\n+\t\t\tpkt_mb[1]);\n+\t\t_mm_storeu_si128((void *)&rx_pkts[0]->rx_descriptor_fields1,\n+\t\t\tpkt_mb[0]);\n+\n+\t\tpkt_mb[3] = _mm_shuffle_epi8(desc[1], shuf_msk2);\n+\t\tpkt_mb[2] = _mm_shuffle_epi8(desc[1], shuf_msk1);\n+\t\tpkt_mb[3] = _mm_add_epi16(pkt_mb[3], len_adjust);\n+\t\tpkt_mb[2] = _mm_add_epi16(pkt_mb[2], len_adjust);\n+\t\t_mm_storeu_si128((void *)&rx_pkts[3]->rx_descriptor_fields1,\n+\t\t\tpkt_mb[3]);\n+\t\t_mm_storeu_si128((void *)&rx_pkts[2]->rx_descriptor_fields1,\n+\t\t\tpkt_mb[2]);\n+\n+\t\tpkt_mb[5] = _mm_shuffle_epi8(desc[2], shuf_msk2);\n+\t\tpkt_mb[4] = _mm_shuffle_epi8(desc[2], shuf_msk1);\n+\t\tpkt_mb[5] = _mm_add_epi16(pkt_mb[5], len_adjust);\n+\t\tpkt_mb[4] = _mm_add_epi16(pkt_mb[4], len_adjust);\n+\t\t_mm_storeu_si128((void *)&rx_pkts[5]->rx_descriptor_fields1,\n+\t\t\tpkt_mb[5]);\n+\t\t_mm_storeu_si128((void *)&rx_pkts[4]->rx_descriptor_fields1,\n+\t\t\tpkt_mb[4]);\n+\n+\t\tpkt_mb[7] = _mm_shuffle_epi8(desc[3], shuf_msk2);\n+\t\tpkt_mb[6] = _mm_shuffle_epi8(desc[3], shuf_msk1);\n+\t\tpkt_mb[7] = _mm_add_epi16(pkt_mb[7], len_adjust);\n+\t\tpkt_mb[6] = _mm_add_epi16(pkt_mb[6], len_adjust);\n+\t\t_mm_storeu_si128((void *)&rx_pkts[7]->rx_descriptor_fields1,\n+\t\t\tpkt_mb[7]);\n+\t\t_mm_storeu_si128((void *)&rx_pkts[6]->rx_descriptor_fields1,\n+\t\t\tpkt_mb[6]);\n+\n+\t\tif (unlikely(nb_used <= RTE_VIRTIO_DESC_PER_LOOP)) {\n+\t\t\tif (sw_ring + nb_used <= sw_ring_end)\n+\t\t\t\tnb_pkts_received += nb_used;\n+\t\t\telse\n+\t\t\t\tnb_pkts_received += sw_ring_end - sw_ring;\n+\t\t\tbreak;\n+\t\t} else {\n+\t\t\tif (unlikely(sw_ring + RTE_VIRTIO_DESC_PER_LOOP >=\n+\t\t\t\tsw_ring_end)) {\n+\t\t\t\tnb_pkts_received += sw_ring_end - sw_ring;\n+\t\t\t\tbreak;\n+\t\t\t} else {\n+\t\t\t\tnb_pkts_received += RTE_VIRTIO_DESC_PER_LOOP;\n+\n+\t\t\t\trx_pkts += RTE_VIRTIO_DESC_PER_LOOP;\n+\t\t\t\tsw_ring += RTE_VIRTIO_DESC_PER_LOOP;\n+\t\t\t\trused   += RTE_VIRTIO_DESC_PER_LOOP;\n+\t\t\t\tnb_used -= RTE_VIRTIO_DESC_PER_LOOP;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\trxvq->vq_used_cons_idx += nb_pkts_received;\n+\trxvq->vq_free_cnt += nb_pkts_received;\n+\trxvq->packets += nb_pkts_received;\n+\treturn nb_pkts_received;\n+}\n+\n+int __attribute__((cold))\n+virtio_rxq_vec_setup(struct virtqueue *rxq)\n+{\n+\tuintptr_t p;\n+\tstruct rte_mbuf mb_def = { .buf_addr = 0 }; /* zeroed mbuf */\n+\n+\tmb_def.nb_segs = 1;\n+\tmb_def.data_off = RTE_PKTMBUF_HEADROOM;\n+\tmb_def.port = rxq->port_id;\n+\trte_mbuf_refcnt_set(&mb_def, 1);\n+\n+\t/* prevent compiler reordering: rearm_data covers previous fields */\n+\trte_compiler_barrier();\n+\tp = (uintptr_t)&mb_def.rearm_data;\n+\trxq->mbuf_initializer = *(uint64_t *)p;\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h\nindex dd63285..363fb99 100644\n--- a/drivers/net/virtio/virtqueue.h\n+++ b/drivers/net/virtio/virtqueue.h\n@@ -188,6 +188,7 @@ struct virtqueue {\n \t */\n \tuint16_t vq_used_cons_idx;\n \tuint16_t vq_avail_idx;\n+\tuint64_t mbuf_initializer; /**< value to init mbufs. */\n \tphys_addr_t virtio_net_hdr_mem; /**< hdr for each xmit packet */\n \n \tstruct rte_mbuf **sw_ring; /**< RX software ring. */\n",
    "prefixes": [
        "dpdk-dev",
        "6/8"
    ]
}