get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 16225,
    "url": "http://patches.dpdk.org/api/patches/16225/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1475152549-12295-3-git-send-email-zhiyong.yang@intel.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": "<1475152549-12295-3-git-send-email-zhiyong.yang@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1475152549-12295-3-git-send-email-zhiyong.yang@intel.com",
    "date": "2016-09-29T12:35:49",
    "name": "[dpdk-dev,v8,2/2] net/vhost: add pmd xstats",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "86b3f2c887fdc6c315eeb990ba051fdd51715837",
    "submitter": {
        "id": 540,
        "url": "http://patches.dpdk.org/api/people/540/?format=api",
        "name": "Yang, Zhiyong",
        "email": "zhiyong.yang@intel.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/1475152549-12295-3-git-send-email-zhiyong.yang@intel.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/16225/comments/",
    "check": "pending",
    "checks": "http://patches.dpdk.org/api/patches/16225/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 79FE556A8;\n\tThu, 29 Sep 2016 14:38:17 +0200 (CEST)",
            "from mga06.intel.com (mga06.intel.com [134.134.136.31])\n\tby dpdk.org (Postfix) with ESMTP id 3A7045589\n\tfor <dev@dpdk.org>; Thu, 29 Sep 2016 14:38:10 +0200 (CEST)",
            "from orsmga003.jf.intel.com ([10.7.209.27])\n\tby orsmga104.jf.intel.com with ESMTP; 29 Sep 2016 05:38:10 -0700",
            "from dpdk2.bj.intel.com ([172.16.182.65])\n\tby orsmga003.jf.intel.com with ESMTP; 29 Sep 2016 05:38:09 -0700"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.30,415,1470726000\"; d=\"scan'208\";a=\"885063294\"",
        "From": "Zhiyong Yang <zhiyong.yang@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "yuanhan.liu@linux.intel.com, ciara.loftus@intel.com,\n\tZhiyong Yang <zhiyong.yang@intel.com>",
        "Date": "Thu, 29 Sep 2016 20:35:49 +0800",
        "Message-Id": "<1475152549-12295-3-git-send-email-zhiyong.yang@intel.com>",
        "X-Mailer": "git-send-email 2.5.5",
        "In-Reply-To": "<1475152549-12295-1-git-send-email-zhiyong.yang@intel.com>",
        "References": "<1475069208-137698-2-git-send-email-zhiyong.yang@intel.com>\n\t<1475152549-12295-1-git-send-email-zhiyong.yang@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v8 2/2] net/vhost: add pmd xstats",
        "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": "This feature adds vhost pmd extended statistics from per port perspective\nin order to meet the requirements of the applications such as OVS etc.\nRX/TX xstats count the bytes without CRC. This is different from physical\nNIC stats with CRC.\n\nThe statistics counters are based on RFC 2819 and RFC 2863 as follows:\n\nrx/tx_good_packets\nrx/tx_total_bytes\nrx/tx_missed_pkts\nrx/tx_broadcast_packets\nrx/tx_multicast_packets\nrx/tx_unicast_packets\nrx/tx_undersize_errors\nrx/tx_size_64_packets\nrx/tx_size_65_to_127_packets;\nrx/tx_size_128_to_255_packets;\nrx/tx_size_256_to_511_packets;\nrx/tx_size_512_to_1023_packets;\nrx/tx_size_1024_to_1522_packets;\nrx/tx_1523_to_max_packets;\nrx/tx_errors\nrx_fragmented_errors\nrx_jabber_errors\nrx_unknown_protos_packets;\n\nNo API is changed or added.\nrte_eth_xstats_get_names() to retrieve what kinds of vhost xstats are\nsupported,\nrte_eth_xstats_get() to retrieve vhost extended statistics,\nrte_eth_xstats_reset() to reset vhost extended statistics. \n\nThe usage of vhost pmd xstats is the same as virtio pmd xstats.\nfor example, when test-pmd application is running in interactive mode\nvhost pmd xstats will support the two following commands:\n\nshow port xstats all | port_id will show vhost xstats\nclear port xstats all | port_id will reset vhost xstats\n\nnet/virtio pmd xstats(the function virtio_update_packet_stats) is used\nas reference when implementing the feature. \n\nThanks for the patches Zhiyong. I've tested the size stats and they look\ngood to me.\nTested-by: Ciara Loftus <ciara.loftus@intel.com>\n\nSigned-off-by: Zhiyong Yang <zhiyong.yang@intel.com>\n---\n\nChanges in V7:\n\nRemoved the \"_portX\" prepended to the xstat names. Keep vhost xstats name\nconsistent with physical NIC i40e, ixgbe, etc.\n\nChanges in V6:\n\n1. Change xstats from per queue to per port. Keep vhost consistent with\nphysical NIC i40e, ixgbe, etc.\n2. Added the release note.\n\nChanges in V5:\nfor vhost_count_multicast_broadcast, passing struct rte_mbuf *buf instead\nof struct rte_mbuf **buf and remove the 3th parameter uint16_t count;.\n\nChanges in v4:\n1. add a member VHOST_XSTATS_MAX in enum vhost_xstats_pkts, So, we can\ndefine uint64_t xstats[VHOST_XSTATS_MAX]; instead of xstats[16].\n2. restore unicast_packets and update it in the function\nvhost_dev_xstats_get\n3. move the loop out of function vhost_count_multicast_broadcast in order\nto reduce the computation.\n\nChanges in v3:\n1. rework the vhost_update_packet_xstats and separate it into two parts.\n   One function deals with the generic packets update, another one deals\n   with increasing the broadcast and multicast with failure packets sent\n   according to RFC2863 page42 ifHCOutMulticastPkts ifHCOutBroadcastPkts.\n2. define enum vhost_stat_pkts to replace the magic numbers and enhance\n   the code readability.\n3. remove some unnecessary type casts and fix one format issue.\n\nChanges in v2:\n1. remove the compiling switch.\n2. fix two code bugs.\n\n doc/guides/rel_notes/release_16_11.rst |   3 +\n drivers/net/vhost/rte_eth_vhost.c      | 270 +++++++++++++++++++++++++++++++++\n 2 files changed, 273 insertions(+)",
    "diff": "diff --git a/doc/guides/rel_notes/release_16_11.rst b/doc/guides/rel_notes/release_16_11.rst\nindex 1e37e48..5fc93e3 100644\n--- a/doc/guides/rel_notes/release_16_11.rst\n+++ b/doc/guides/rel_notes/release_16_11.rst\n@@ -50,6 +50,9 @@ New Features\n \n     * **Added virtio NEON support for ARM.**\n \n+   * **Added vhost pmd xstats support.**\n+\n+     Added vhost pmd extended statistics from per port perspective.\n \n Resolved Issues\n ---------------\ndiff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c\nindex c4af0f7..6943ac9 100644\n--- a/drivers/net/vhost/rte_eth_vhost.c\n+++ b/drivers/net/vhost/rte_eth_vhost.c\n@@ -72,10 +72,30 @@ static struct ether_addr base_eth_addr = {\n \t}\n };\n \n+enum vhost_xstats_pkts {\n+\tVHOST_UNDERSIZE_PKT = 0,\n+\tVHOST_64_PKT,\n+\tVHOST_65_TO_127_PKT,\n+\tVHOST_128_TO_255_PKT,\n+\tVHOST_256_TO_511_PKT,\n+\tVHOST_512_TO_1023_PKT,\n+\tVHOST_1024_TO_1522_PKT,\n+\tVHOST_1523_TO_MAX_PKT,\n+\tVHOST_BROADCAST_PKT,\n+\tVHOST_MULTICAST_PKT,\n+\tVHOST_UNICAST_PKT,\n+\tVHOST_ERRORS_PKT,\n+\tVHOST_ERRORS_FRAGMENTED,\n+\tVHOST_ERRORS_JABBER,\n+\tVHOST_UNKNOWN_PROTOCOL,\n+\tVHOST_XSTATS_MAX,\n+};\n+\n struct vhost_stats {\n \tuint64_t pkts;\n \tuint64_t bytes;\n \tuint64_t missed_pkts;\n+\tuint64_t xstats[VHOST_XSTATS_MAX];\n };\n \n struct vhost_queue {\n@@ -129,6 +149,242 @@ struct rte_vhost_vring_state {\n \n static struct rte_vhost_vring_state *vring_states[RTE_MAX_ETHPORTS];\n \n+#define VHOST_XSTATS_NAME_SIZE 64\n+\n+struct vhost_xstats_name_off {\n+\tchar name[VHOST_XSTATS_NAME_SIZE];\n+\tuint64_t offset;\n+};\n+\n+/* [rx]_is prepended to the name string here */\n+static const struct vhost_xstats_name_off vhost_rxport_stat_strings[] = {\n+\t{\"good_packets\",\n+\t offsetof(struct vhost_queue, stats.pkts)},\n+\t{\"total_bytes\",\n+\t offsetof(struct vhost_queue, stats.bytes)},\n+\t{\"missed_pkts\",\n+\t offsetof(struct vhost_queue, stats.missed_pkts)},\n+\t{\"broadcast_packets\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_BROADCAST_PKT])},\n+\t{\"multicast_packets\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_MULTICAST_PKT])},\n+\t{\"unicast_packets\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_UNICAST_PKT])},\n+\t {\"undersize_packets\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_UNDERSIZE_PKT])},\n+\t{\"size_64_packets\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_64_PKT])},\n+\t{\"size_65_to_127_packets\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_65_TO_127_PKT])},\n+\t{\"size_128_to_255_packets\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_128_TO_255_PKT])},\n+\t{\"size_256_to_511_packets\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_256_TO_511_PKT])},\n+\t{\"size_512_to_1023_packets\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_512_TO_1023_PKT])},\n+\t{\"size_1024_to_1522_packets\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_1024_TO_1522_PKT])},\n+\t{\"size_1523_to_max_packets\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_1523_TO_MAX_PKT])},\n+\t{\"errors_with_bad_CRC\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_ERRORS_PKT])},\n+\t{\"fragmented_errors\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_ERRORS_FRAGMENTED])},\n+\t{\"jabber_errors\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_ERRORS_JABBER])},\n+\t{\"unknown_protos_packets\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_UNKNOWN_PROTOCOL])},\n+};\n+\n+/* [tx]_ is prepended to the name string here */\n+static const struct vhost_xstats_name_off vhost_txport_stat_strings[] = {\n+\t{\"good_packets\",\n+\t offsetof(struct vhost_queue, stats.pkts)},\n+\t{\"total_bytes\",\n+\t offsetof(struct vhost_queue, stats.bytes)},\n+\t{\"missed_pkts\",\n+\t offsetof(struct vhost_queue, stats.missed_pkts)},\n+\t{\"broadcast_packets\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_BROADCAST_PKT])},\n+\t{\"multicast_packets\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_MULTICAST_PKT])},\n+\t{\"unicast_packets\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_UNICAST_PKT])},\n+\t{\"undersize_packets\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_UNDERSIZE_PKT])},\n+\t{\"size_64_packets\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_64_PKT])},\n+\t{\"size_65_to_127_packets\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_65_TO_127_PKT])},\n+\t{\"size_128_to_255_packets\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_128_TO_255_PKT])},\n+\t{\"size_256_to_511_packets\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_256_TO_511_PKT])},\n+\t{\"size_512_to_1023_packets\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_512_TO_1023_PKT])},\n+\t{\"size_1024_to_1522_packets\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_1024_TO_1522_PKT])},\n+\t{\"size_1523_to_max_packets\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_1523_TO_MAX_PKT])},\n+\t{\"errors_with_bad_CRC\",\n+\t offsetof(struct vhost_queue, stats.xstats[VHOST_ERRORS_PKT])},\n+};\n+\n+#define VHOST_NB_XSTATS_RXPORT (sizeof(vhost_rxport_stat_strings) / \\\n+\t\t\t\tsizeof(vhost_rxport_stat_strings[0]))\n+\n+#define VHOST_NB_XSTATS_TXPORT (sizeof(vhost_txport_stat_strings) / \\\n+\t\t\t\tsizeof(vhost_txport_stat_strings[0]))\n+\n+static void\n+vhost_dev_xstats_reset(struct rte_eth_dev *dev)\n+{\n+\tstruct vhost_queue *vq = NULL;\n+\tunsigned int i = 0;\n+\n+\tfor (i = 0; i < dev->data->nb_rx_queues; i++) {\n+\t\tvq = dev->data->rx_queues[i];\n+\t\tif (!vq)\n+\t\t\tcontinue;\n+\t\tmemset(&vq->stats, 0, sizeof(vq->stats));\n+\t}\n+\tfor (i = 0; i < dev->data->nb_tx_queues; i++) {\n+\t\tvq = dev->data->tx_queues[i];\n+\t\tif (!vq)\n+\t\t\tcontinue;\n+\t\tmemset(&vq->stats, 0, sizeof(vq->stats));\n+\t}\n+}\n+\n+static int\n+vhost_dev_xstats_get_names(struct rte_eth_dev *dev __rte_unused,\n+\t\t\t   struct rte_eth_xstat_name *xstats_names,\n+\t\t\t   unsigned int limit __rte_unused)\n+{\n+\tunsigned int t = 0;\n+\tint count = 0;\n+\tint nstats = VHOST_NB_XSTATS_RXPORT + VHOST_NB_XSTATS_TXPORT;\n+\n+\tif (!xstats_names)\n+\t\treturn nstats;\n+\tfor (t = 0; t < VHOST_NB_XSTATS_RXPORT; t++) {\n+\t\tsnprintf(xstats_names[count].name,\n+\t\t\t sizeof(xstats_names[count].name),\n+\t\t\t \"rx_%s\", vhost_rxport_stat_strings[t].name);\n+\t\tcount++;\n+\t}\n+\tfor (t = 0; t < VHOST_NB_XSTATS_TXPORT; t++) {\n+\t\tsnprintf(xstats_names[count].name,\n+\t\t\t sizeof(xstats_names[count].name),\n+\t\t\t \"tx_%s\", vhost_txport_stat_strings[t].name);\n+\t\tcount++;\n+\t}\n+\treturn count;\n+}\n+\n+static int\n+vhost_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,\n+\t\t     unsigned int n)\n+{\n+\tunsigned int i;\n+\tunsigned int t;\n+\tunsigned int count = 0;\n+\tstruct vhost_queue *vq = NULL;\n+\tunsigned int nxstats = VHOST_NB_XSTATS_RXPORT + VHOST_NB_XSTATS_TXPORT;\n+\n+\tif (n < nxstats)\n+\t\treturn nxstats;\n+\n+\tfor (i = 0; i < dev->data->nb_rx_queues; i++) {\n+\t\tvq = dev->data->rx_queues[i];\n+\t\tif (!vq)\n+\t\t\tcontinue;\n+\t\tvq->stats.xstats[VHOST_UNICAST_PKT] = vq->stats.pkts\n+\t\t\t\t- (vq->stats.xstats[VHOST_BROADCAST_PKT]\n+\t\t\t\t+ vq->stats.xstats[VHOST_MULTICAST_PKT]);\n+\t}\n+\tfor (i = 0; i < dev->data->nb_tx_queues; i++) {\n+\t\tvq = dev->data->tx_queues[i];\n+\t\tif (!vq)\n+\t\t\tcontinue;\n+\t\tvq->stats.xstats[VHOST_UNICAST_PKT] = vq->stats.pkts\n+\t\t\t\t+ vq->stats.missed_pkts\n+\t\t\t\t- (vq->stats.xstats[VHOST_BROADCAST_PKT]\n+\t\t\t\t+ vq->stats.xstats[VHOST_MULTICAST_PKT]);\n+\t}\n+\tfor (t = 0; t < VHOST_NB_XSTATS_RXPORT; t++) {\n+\t\txstats[count].value = 0;\n+\t\tfor (i = 0; i < dev->data->nb_rx_queues; i++) {\n+\t\t\tvq = dev->data->rx_queues[i];\n+\t\t\tif (!vq)\n+\t\t\t\tcontinue;\n+\t\t\txstats[count].value +=\n+\t\t\t\t*(uint64_t *)(((char *)vq)\n+\t\t\t\t+ vhost_rxport_stat_strings[t].offset);\n+\t\t}\n+\t\tcount++;\n+\t}\n+\tfor (t = 0; t < VHOST_NB_XSTATS_TXPORT; t++) {\n+\t\txstats[count].value = 0;\n+\t\tfor (i = 0; i < dev->data->nb_tx_queues; i++) {\n+\t\t\tvq = dev->data->tx_queues[i];\n+\t\t\tif (!vq)\n+\t\t\t\tcontinue;\n+\t\t\txstats[count].value +=\n+\t\t\t\t*(uint64_t *)(((char *)vq)\n+\t\t\t\t+ vhost_txport_stat_strings[t].offset);\n+\t\t}\n+\t\tcount++;\n+\t}\n+\treturn count;\n+}\n+\n+static inline void\n+vhost_count_multicast_broadcast(struct vhost_queue *vq,\n+\t\t\t\tstruct rte_mbuf *mbuf)\n+{\n+\tstruct ether_addr *ea = NULL;\n+\tstruct vhost_stats *pstats = &vq->stats;\n+\n+\tea = rte_pktmbuf_mtod(mbuf, struct ether_addr *);\n+\tif (is_multicast_ether_addr(ea)) {\n+\t\tif (is_broadcast_ether_addr(ea))\n+\t\t\tpstats->xstats[VHOST_BROADCAST_PKT]++;\n+\t\telse\n+\t\t\tpstats->xstats[VHOST_MULTICAST_PKT]++;\n+\t}\n+}\n+\n+static void\n+vhost_update_packet_xstats(struct vhost_queue *vq,\n+\t\t\t   struct rte_mbuf **bufs,\n+\t\t\t   uint16_t count)\n+{\n+\tuint32_t pkt_len = 0;\n+\tuint64_t i = 0;\n+\tuint64_t index;\n+\tstruct vhost_stats *pstats = &vq->stats;\n+\n+\tfor (i = 0; i < count ; i++) {\n+\t\tpkt_len = bufs[i]->pkt_len;\n+\t\tif (pkt_len == 64) {\n+\t\t\tpstats->xstats[VHOST_64_PKT]++;\n+\t\t} else if (pkt_len > 64 && pkt_len < 1024) {\n+\t\t\tindex = (sizeof(pkt_len) * 8)\n+\t\t\t\t- __builtin_clz(pkt_len) - 5;\n+\t\t\tpstats->xstats[index]++;\n+\t\t} else {\n+\t\t\tif (pkt_len < 64)\n+\t\t\t\tpstats->xstats[VHOST_UNDERSIZE_PKT]++;\n+\t\t\telse if (pkt_len <= 1522)\n+\t\t\t\tpstats->xstats[VHOST_1024_TO_1522_PKT]++;\n+\t\t\telse if (pkt_len > 1522)\n+\t\t\t\tpstats->xstats[VHOST_1523_TO_MAX_PKT]++;\n+\t\t}\n+\t\tvhost_count_multicast_broadcast(vq, bufs[i]);\n+\t}\n+}\n+\n static uint16_t\n eth_vhost_rx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)\n {\n@@ -154,6 +410,8 @@ eth_vhost_rx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)\n \t\tr->stats.bytes += bufs[i]->pkt_len;\n \t}\n \n+\tvhost_update_packet_xstats(r, bufs, nb_rx);\n+\n out:\n \trte_atomic32_set(&r->while_queuing, 0);\n \n@@ -184,6 +442,15 @@ eth_vhost_tx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)\n \tfor (i = 0; likely(i < nb_tx); i++)\n \t\tr->stats.bytes += bufs[i]->pkt_len;\n \n+\tvhost_update_packet_xstats(r, bufs, nb_tx);\n+\n+\t/* According to RFC2863 page42 section ifHCOutMulticastPkts and\n+\t * ifHCOutBroadcastPkts, the counters \"multicast\" and \"broadcast\"\n+\t * are increased when packets are not transmitted successfully.\n+\t */\n+\tfor (i = nb_tx; i < nb_bufs; i++)\n+\t\tvhost_count_multicast_broadcast(r, bufs[i]);\n+\n \tfor (i = 0; likely(i < nb_tx); i++)\n \t\trte_pktmbuf_free(bufs[i]);\n out:\n@@ -684,6 +951,9 @@ static const struct eth_dev_ops ops = {\n \t.link_update = eth_link_update,\n \t.stats_get = eth_stats_get,\n \t.stats_reset = eth_stats_reset,\n+\t.xstats_reset = vhost_dev_xstats_reset,\n+\t.xstats_get = vhost_dev_xstats_get,\n+\t.xstats_get_names = vhost_dev_xstats_get_names,\n };\n \n static int\n",
    "prefixes": [
        "dpdk-dev",
        "v8",
        "2/2"
    ]
}