List comments

GET /api/patches/159/comments/
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "id": 415,
        "web_url": "http://patches.dpdk.org/comment/415/",
        "msgid": "<F52918179C57134FAEC9EA62FA2F962511839B08@shsmsx102.ccr.corp.intel.com>",
        "date": "2014-08-21T01:23:04",
        "subject": "Re: [dpdk-dev] [PATCH v3] virtio: Support mergeable buffer in\n\tvirtio pmd",
        "submitter": {
            "id": 31,
            "url": "http://patches.dpdk.org/api/people/31/",
            "name": "Ouyang Changchun",
            "email": "changchun.ouyang@intel.com"
        },
        "content": "Hi all,\n\nAny comments for this patch?\nAnd what's the status for merging it into mainline?\n\nThanks in advance\nChangchun\n\n> -----Original Message-----\n> From: Ouyang, Changchun\n> Sent: Thursday, August 14, 2014 4:55 PM\n> To: dev@dpdk.org\n> Cc: Cao, Waterman; Ouyang, Changchun\n> Subject: [PATCH v3] virtio: Support mergeable buffer in virtio pmd\n> \n> v3 change:\n> - Investigate the comments from Huawei and fix one potential issue of\n> wrong offset to\n>   the number of descriptor in buffer; also fix other tiny comments.\n> \n> v2 change:\n> - Resolve conflicts with the tip code;\n> - And resolve 2 issues:\n>    -- fix mbuf leak when discard an uncompleted packet.\n>    -- refine pkt.data to point to actual payload data start point.\n> \n> v1 change:\n> - This patch supports mergeable buffer feature in DPDK based virtio PMD,\n> which can\n>   receive jumbo frame with larger size, like 3K, 4K or even 9K.\n> \n> Signed-off-by: Changchun Ouyang <changchun.ouyang@intel.com>\n> Acked-by: Huawei Xie <huawei.xie@intel.com>\n> ---\n>  lib/librte_pmd_virtio/virtio_ethdev.c |  20 +--\n>  lib/librte_pmd_virtio/virtio_ethdev.h |   3 +\n>  lib/librte_pmd_virtio/virtio_rxtx.c   | 221\n> +++++++++++++++++++++++++++++-----\n>  3 files changed, 207 insertions(+), 37 deletions(-)\n> \n> diff --git a/lib/librte_pmd_virtio/virtio_ethdev.c\n> b/lib/librte_pmd_virtio/virtio_ethdev.c\n> index b9f5529..535d798 100644\n> --- a/lib/librte_pmd_virtio/virtio_ethdev.c\n> +++ b/lib/librte_pmd_virtio/virtio_ethdev.c\n> @@ -337,7 +337,7 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,\n>  \t\tsnprintf(vq_name, sizeof(vq_name),\n> \"port%d_tvq%d_hdrzone\",\n>  \t\t\tdev->data->port_id, queue_idx);\n>  \t\tvq->virtio_net_hdr_mz =\n> rte_memzone_reserve_aligned(vq_name,\n> -\t\t\tvq_size * sizeof(struct virtio_net_hdr),\n> +\t\t\tvq_size * hw->vtnet_hdr_size,\n>  \t\t\tsocket_id, 0, CACHE_LINE_SIZE);\n>  \t\tif (vq->virtio_net_hdr_mz == NULL) {\n>  \t\t\trte_free(vq);\n> @@ -346,7 +346,7 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,\n>  \t\tvq->virtio_net_hdr_mem =\n>  \t\t\tvq->virtio_net_hdr_mz->phys_addr;\n>  \t\tmemset(vq->virtio_net_hdr_mz->addr, 0,\n> -\t\t\tvq_size * sizeof(struct virtio_net_hdr));\n> +\t\t\tvq_size * hw->vtnet_hdr_size);\n>  \t} else if (queue_type == VTNET_CQ) {\n>  \t\t/* Allocate a page for control vq command, data and status\n> */\n>  \t\tsnprintf(vq_name, sizeof(vq_name), \"port%d_cvq_hdrzone\",\n> @@ -571,9 +571,6 @@ virtio_negotiate_features(struct virtio_hw *hw)\n>  \tmask |= VIRTIO_NET_F_GUEST_TSO4 | VIRTIO_NET_F_GUEST_TSO6\n> | VIRTIO_NET_F_GUEST_ECN;\n>  \tmask |= VTNET_LRO_FEATURES;\n> \n> -\t/* rx_mbuf should not be in multiple merged segments */\n> -\tmask |= VIRTIO_NET_F_MRG_RXBUF;\n> -\n>  \t/* not negotiating INDIRECT descriptor table support */\n>  \tmask |= VIRTIO_RING_F_INDIRECT_DESC;\n> \n> @@ -746,7 +743,6 @@ eth_virtio_dev_init(__rte_unused struct eth_driver\n> *eth_drv,\n>  \t}\n> \n>  \teth_dev->dev_ops = &virtio_eth_dev_ops;\n> -\teth_dev->rx_pkt_burst = &virtio_recv_pkts;\n>  \teth_dev->tx_pkt_burst = &virtio_xmit_pkts;\n> \n>  \tif (rte_eal_process_type() == RTE_PROC_SECONDARY)\n> @@ -801,10 +797,13 @@ eth_virtio_dev_init(__rte_unused struct\n> eth_driver *eth_drv,\n>  \tvirtio_negotiate_features(hw);\n> \n>  \t/* Setting up rx_header size for the device */\n> -\tif (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF))\n> +\tif (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) {\n> +\t\teth_dev->rx_pkt_burst = &virtio_recv_mergeable_pkts;\n>  \t\thw->vtnet_hdr_size = sizeof(struct\n> virtio_net_hdr_mrg_rxbuf);\n> -\telse\n> +\t} else {\n> +\t\teth_dev->rx_pkt_burst = &virtio_recv_pkts;\n>  \t\thw->vtnet_hdr_size = sizeof(struct virtio_net_hdr);\n> +\t}\n> \n>  \t/* Allocate memory for storing MAC addresses */\n>  \teth_dev->data->mac_addrs = rte_zmalloc(\"virtio\",\n> ETHER_ADDR_LEN, 0);\n> @@ -1009,7 +1008,7 @@ static void virtio_dev_free_mbufs(struct\n> rte_eth_dev *dev)\n> \n>  \t\twhile ((buf = (struct rte_mbuf *)virtqueue_detatch_unused(\n>  \t\t\t\t\tdev->data->rx_queues[i])) != NULL) {\n> -\t\t\trte_pktmbuf_free_seg(buf);\n> +\t\t\trte_pktmbuf_free(buf);\n>  \t\t\tmbuf_num++;\n>  \t\t}\n> \n> @@ -1028,7 +1027,8 @@ static void virtio_dev_free_mbufs(struct\n> rte_eth_dev *dev)\n>  \t\tmbuf_num = 0;\n>  \t\twhile ((buf = (struct rte_mbuf *)virtqueue_detatch_unused(\n>  \t\t\t\t\tdev->data->tx_queues[i])) != NULL) {\n> -\t\t\trte_pktmbuf_free_seg(buf);\n> +\t\t\trte_pktmbuf_free(buf);\n> +\n>  \t\t\tmbuf_num++;\n>  \t\t}\n> \n> diff --git a/lib/librte_pmd_virtio/virtio_ethdev.h\n> b/lib/librte_pmd_virtio/virtio_ethdev.h\n> index 858e644..d2e1eed 100644\n> --- a/lib/librte_pmd_virtio/virtio_ethdev.h\n> +++ b/lib/librte_pmd_virtio/virtio_ethdev.h\n> @@ -104,6 +104,9 @@ int  virtio_dev_tx_queue_setup(struct rte_eth_dev\n> *dev, uint16_t tx_queue_id,\n>  uint16_t virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,\n>  \t\tuint16_t nb_pkts);\n> \n> +uint16_t virtio_recv_mergeable_pkts(void *rx_queue, struct rte_mbuf\n> **rx_pkts,\n> +\t\tuint16_t nb_pkts);\n> +\n>  uint16_t virtio_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,\n>  \t\tuint16_t nb_pkts);\n> \n> diff --git a/lib/librte_pmd_virtio/virtio_rxtx.c\n> b/lib/librte_pmd_virtio/virtio_rxtx.c\n> index fcd8bd1..0b10108 100644\n> --- a/lib/librte_pmd_virtio/virtio_rxtx.c\n> +++ b/lib/librte_pmd_virtio/virtio_rxtx.c\n> @@ -146,6 +146,7 @@ static inline int\n>  virtqueue_enqueue_recv_refill(struct virtqueue *vq, struct rte_mbuf\n> *cookie)\n>  {\n>  \tstruct vq_desc_extra *dxp;\n> +\tstruct virtio_hw *hw = vq->hw;\n>  \tstruct vring_desc *start_dp;\n>  \tuint16_t needed = 1;\n>  \tuint16_t head_idx, idx;\n> @@ -165,9 +166,11 @@ virtqueue_enqueue_recv_refill(struct virtqueue *vq,\n> struct rte_mbuf *cookie)\n>  \tdxp->ndescs = needed;\n> \n>  \tstart_dp = vq->vq_ring.desc;\n> -\tstart_dp[idx].addr  =\n> -\t\t(uint64_t) (cookie->buf_physaddr +\n> RTE_PKTMBUF_HEADROOM - sizeof(struct virtio_net_hdr));\n> -\tstart_dp[idx].len   = cookie->buf_len - RTE_PKTMBUF_HEADROOM +\n> sizeof(struct virtio_net_hdr);\n> +\tstart_dp[idx].addr =\n> +\t\t(uint64_t)(cookie->buf_physaddr +\n> RTE_PKTMBUF_HEADROOM\n> +\t\t- hw->vtnet_hdr_size);\n> +\tstart_dp[idx].len =\n> +\t\tcookie->buf_len - RTE_PKTMBUF_HEADROOM + hw-\n> >vtnet_hdr_size;\n>  \tstart_dp[idx].flags =  VRING_DESC_F_WRITE;\n>  \tidx = start_dp[idx].next;\n>  \tvq->vq_desc_head_idx = idx;\n> @@ -184,8 +187,10 @@ virtqueue_enqueue_xmit(struct virtqueue *txvq,\n> struct rte_mbuf *cookie)\n>  {\n>  \tstruct vq_desc_extra *dxp;\n>  \tstruct vring_desc *start_dp;\n> -\tuint16_t needed = 2;\n> +\tuint16_t seg_num = cookie->pkt.nb_segs;\n> +\tuint16_t needed = 1 + seg_num;\n>  \tuint16_t head_idx, idx;\n> +\tuint16_t head_size = txvq->hw->vtnet_hdr_size;\n> \n>  \tif (unlikely(txvq->vq_free_cnt == 0))\n>  \t\treturn -ENOSPC;\n> @@ -198,19 +203,25 @@ virtqueue_enqueue_xmit(struct virtqueue *txvq,\n> struct rte_mbuf *cookie)\n>  \tidx = head_idx;\n>  \tdxp = &txvq->vq_descx[idx];\n>  \tif (dxp->cookie != NULL)\n> -\t\trte_pktmbuf_free_seg(dxp->cookie);\n> +\t\trte_pktmbuf_free(dxp->cookie);\n>  \tdxp->cookie = (void *)cookie;\n>  \tdxp->ndescs = needed;\n> \n>  \tstart_dp = txvq->vq_ring.desc;\n> -\tstart_dp[idx].addr  =\n> -\t\ttxvq->virtio_net_hdr_mem + idx * sizeof(struct\n> virtio_net_hdr);\n> -\tstart_dp[idx].len   = sizeof(struct virtio_net_hdr);\n> +\tstart_dp[idx].addr =\n> +\t\ttxvq->virtio_net_hdr_mem + idx * head_size;\n> +\tstart_dp[idx].len = (uint32_t)head_size;\n>  \tstart_dp[idx].flags = VRING_DESC_F_NEXT;\n> -\tidx = start_dp[idx].next;\n> -\tstart_dp[idx].addr  = RTE_MBUF_DATA_DMA_ADDR(cookie);\n> -\tstart_dp[idx].len   = cookie->pkt.data_len;\n> -\tstart_dp[idx].flags = 0;\n> +\n> +\tfor (; ((seg_num > 0) && (cookie != NULL)); seg_num--) {\n> +\t\tidx = start_dp[idx].next;\n> +\t\tstart_dp[idx].addr  = RTE_MBUF_DATA_DMA_ADDR(cookie);\n> +\t\tstart_dp[idx].len   = cookie->pkt.data_len;\n> +\t\tstart_dp[idx].flags = VRING_DESC_F_NEXT;\n> +\t\tcookie = cookie->pkt.next;\n> +\t}\n> +\n> +\tstart_dp[idx].flags &= ~VRING_DESC_F_NEXT;\n>  \tidx = start_dp[idx].next;\n>  \ttxvq->vq_desc_head_idx = idx;\n>  \tif (txvq->vq_desc_head_idx == VQ_RING_DESC_CHAIN_END)\n> @@ -284,7 +295,7 @@ virtio_dev_vring_start(struct virtqueue *vq, int\n> queue_type)\n>  \t\t\terror = virtqueue_enqueue_recv_refill(vq, m);\n> \n>  \t\t\tif (error) {\n> -\t\t\t\trte_pktmbuf_free_seg(m);\n> +\t\t\t\trte_pktmbuf_free(m);\n>  \t\t\t\tbreak;\n>  \t\t\t}\n>  \t\t\tnbufs++;\n> @@ -423,7 +434,7 @@ virtio_discard_rxbuf(struct virtqueue *vq, struct\n> rte_mbuf *m)\n>  \terror = virtqueue_enqueue_recv_refill(vq, m);\n>  \tif (unlikely(error)) {\n>  \t\tRTE_LOG(ERR, PMD, \"cannot requeue discarded mbuf\");\n> -\t\trte_pktmbuf_free_seg(m);\n> +\t\trte_pktmbuf_free(m);\n>  \t}\n>  }\n> \n> @@ -433,13 +444,13 @@ uint16_t\n>  virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t\n> nb_pkts)\n>  {\n>  \tstruct virtqueue *rxvq = rx_queue;\n> -\tstruct virtio_hw *hw = rxvq->hw;\n>  \tstruct rte_mbuf *rxm, *new_mbuf;\n>  \tuint16_t nb_used, num, nb_rx = 0;\n>  \tuint32_t len[VIRTIO_MBUF_BURST_SZ];\n>  \tstruct rte_mbuf *rcv_pkts[VIRTIO_MBUF_BURST_SZ];\n>  \tint error;\n>  \tuint32_t i, nb_enqueued = 0;\n> +\tconst uint32_t hdr_size = sizeof(struct virtio_net_hdr);\n> \n>  \tnb_used = VIRTQUEUE_NUSED(rxvq);\n> \n> @@ -460,8 +471,7 @@ virtio_recv_pkts(void *rx_queue, struct rte_mbuf\n> **rx_pkts, uint16_t nb_pkts)\n> \n>  \t\tPMD_RX_LOG(DEBUG, \"packet len:%d\", len[i]);\n> \n> -\t\tif (unlikely(len[i]\n> -\t\t\t     < (uint32_t)hw->vtnet_hdr_size +\n> ETHER_HDR_LEN)) {\n> +\t\tif (unlikely(len[i] < hdr_size + ETHER_HDR_LEN)) {\n>  \t\t\tPMD_RX_LOG(ERR, \"Packet drop\");\n>  \t\t\tnb_enqueued++;\n>  \t\t\tvirtio_discard_rxbuf(rxvq, rxm);\n> @@ -471,17 +481,16 @@ virtio_recv_pkts(void *rx_queue, struct rte_mbuf\n> **rx_pkts, uint16_t nb_pkts)\n> \n>  \t\trxm->pkt.in_port = rxvq->port_id;\n>  \t\trxm->pkt.data = (char *)rxm->buf_addr +\n> RTE_PKTMBUF_HEADROOM;\n> +\n>  \t\trxm->pkt.nb_segs = 1;\n>  \t\trxm->pkt.next = NULL;\n> -\t\trxm->pkt.pkt_len  = (uint32_t)(len[i]\n> -\t\t\t\t\t       - sizeof(struct virtio_net_hdr));\n> -\t\trxm->pkt.data_len = (uint16_t)(len[i]\n> -\t\t\t\t\t       - sizeof(struct virtio_net_hdr));\n> +\t\trxm->pkt.pkt_len = (uint32_t)(len[i] - hdr_size);\n> +\t\trxm->pkt.data_len = (uint16_t)(len[i] - hdr_size);\n> \n>  \t\tVIRTIO_DUMP_PACKET(rxm, rxm->pkt.data_len);\n> \n>  \t\trx_pkts[nb_rx++] = rxm;\n> -\t\trxvq->bytes += len[i] - sizeof(struct virtio_net_hdr);\n> +\t\trxvq->bytes += rx_pkts[nb_rx - 1]->pkt.pkt_len;\n>  \t}\n> \n>  \trxvq->packets += nb_rx;\n> @@ -498,11 +507,165 @@ virtio_recv_pkts(void *rx_queue, struct rte_mbuf\n> **rx_pkts, uint16_t nb_pkts)\n>  \t\t}\n>  \t\terror = virtqueue_enqueue_recv_refill(rxvq, new_mbuf);\n>  \t\tif (unlikely(error)) {\n> -\t\t\trte_pktmbuf_free_seg(new_mbuf);\n> +\t\t\trte_pktmbuf_free(new_mbuf);\n>  \t\t\tbreak;\n>  \t\t}\n>  \t\tnb_enqueued++;\n>  \t}\n> +\n> +\tif (likely(nb_enqueued)) {\n> +\t\tif (unlikely(virtqueue_kick_prepare(rxvq))) {\n> +\t\t\tvirtqueue_notify(rxvq);\n> +\t\t\tPMD_RX_LOG(DEBUG, \"Notified\\n\");\n> +\t\t}\n> +\t}\n> +\n> +\tvq_update_avail_idx(rxvq);\n> +\n> +\treturn nb_rx;\n> +}\n> +\n> +uint16_t\n> +virtio_recv_mergeable_pkts(void *rx_queue,\n> +\t\t\tstruct rte_mbuf **rx_pkts,\n> +\t\t\tuint16_t nb_pkts)\n> +{\n> +\tstruct virtqueue *rxvq = rx_queue;\n> +\tstruct rte_mbuf *rxm, *new_mbuf;\n> +\tuint16_t nb_used, num, nb_rx = 0;\n> +\tuint32_t len[VIRTIO_MBUF_BURST_SZ];\n> +\tstruct rte_mbuf *rcv_pkts[VIRTIO_MBUF_BURST_SZ];\n> +\tstruct rte_mbuf *prev;\n> +\tint error;\n> +\tuint32_t i = 0, nb_enqueued = 0;\n> +\tuint32_t seg_num = 0;\n> +\tuint16_t extra_idx = 0;\n> +\tuint32_t seg_res = 0;\n> +\tconst uint32_t hdr_size = sizeof(struct virtio_net_hdr_mrg_rxbuf);\n> +\n> +\tnb_used = VIRTQUEUE_NUSED(rxvq);\n> +\n> +\trmb();\n> +\n> +\tif (nb_used == 0)\n> +\t\treturn 0;\n> +\n> +\tPMD_RX_LOG(DEBUG, \"used:%d\\n\", nb_used);\n> +\n> +\twhile (i < nb_used) {\n> +\t\tstruct virtio_net_hdr_mrg_rxbuf *header;\n> +\n> +\t\tif (nb_rx == nb_pkts)\n> +\t\t\tbreak;\n> +\n> +\t\tnum = virtqueue_dequeue_burst_rx(rxvq, rcv_pkts, len, 1);\n> +\t\tif (num != 1)\n> +\t\t\tcontinue;\n> +\n> +\t\ti++;\n> +\n> +\t\tPMD_RX_LOG(DEBUG, \"dequeue:%d\\n\", num);\n> +\t\tPMD_RX_LOG(DEBUG, \"packet len:%d\\n\", len[0]);\n> +\n> +\t\trxm = rcv_pkts[0];\n> +\n> +\t\tif (unlikely(len[0] < hdr_size + ETHER_HDR_LEN)) {\n> +\t\t\tPMD_RX_LOG(ERR, \"Packet drop\\n\");\n> +\t\t\tnb_enqueued++;\n> +\t\t\tvirtio_discard_rxbuf(rxvq, rxm);\n> +\t\t\trxvq->errors++;\n> +\t\t\tcontinue;\n> +\t\t}\n> +\n> +\t\theader = (struct virtio_net_hdr_mrg_rxbuf *)((char *)rxm-\n> >buf_addr +\n> +\t\t\tRTE_PKTMBUF_HEADROOM - hdr_size);\n> +\t\tseg_num = header->num_buffers;\n> +\n> +\t\tif (seg_num == 0)\n> +\t\t\tseg_num = 1;\n> +\n> +\t\trxm->pkt.data = (char *)rxm->buf_addr +\n> RTE_PKTMBUF_HEADROOM;\n> +\t\trxm->pkt.nb_segs = seg_num;\n> +\t\trxm->pkt.next = NULL;\n> +\t\trxm->pkt.pkt_len = (uint32_t)(len[0] - hdr_size);\n> +\t\trxm->pkt.data_len = (uint16_t)(len[0] - hdr_size);\n> +\n> +\t\trxm->pkt.in_port = rxvq->port_id;\n> +\t\trx_pkts[nb_rx] = rxm;\n> +\t\tprev = rxm;\n> +\n> +\t\tseg_res = seg_num - 1;\n> +\n> +\t\twhile (seg_res != 0) {\n> +\t\t\t/*\n> +\t\t\t * Get extra segments for current uncompleted\n> packet.\n> +\t\t\t */\n> +\t\t\tuint32_t  rcv_cnt =\n> +\t\t\t\tRTE_MIN(seg_res, RTE_DIM(rcv_pkts));\n> +\t\t\tif (likely(VIRTQUEUE_NUSED(rxvq) >= rcv_cnt)) {\n> +\t\t\t\tuint32_t rx_num =\n> +\t\t\t\t\tvirtqueue_dequeue_burst_rx(rxvq,\n> +\t\t\t\t\trcv_pkts, len, rcv_cnt);\n> +\t\t\t\ti += rx_num;\n> +\t\t\t\trcv_cnt = rx_num;\n> +\t\t\t} else {\n> +\t\t\t\tPMD_RX_LOG(ERR,\n> +\t\t\t\t\t\"No enough segments for\n> packet.\\n\");\n> +\t\t\t\tnb_enqueued++;\n> +\t\t\t\tvirtio_discard_rxbuf(rxvq, rxm);\n> +\t\t\t\trxvq->errors++;\n> +\t\t\t\tbreak;\n> +\t\t\t}\n> +\n> +\t\t\textra_idx = 0;\n> +\n> +\t\t\twhile (extra_idx < rcv_cnt) {\n> +\t\t\t\trxm = rcv_pkts[extra_idx];\n> +\n> +\t\t\t\trxm->pkt.data =\n> +\t\t\t\t\t(char *)rxm->buf_addr +\n> +\t\t\t\t\tRTE_PKTMBUF_HEADROOM -\n> hdr_size;\n> +\t\t\t\trxm->pkt.next = NULL;\n> +\t\t\t\trxm->pkt.pkt_len =\n> (uint32_t)(len[extra_idx]);\n> +\t\t\t\trxm->pkt.data_len =\n> (uint16_t)(len[extra_idx]);\n> +\n> +\t\t\t\tif (prev)\n> +\t\t\t\t\tprev->pkt.next = rxm;\n> +\n> +\t\t\t\tprev = rxm;\n> +\t\t\t\trx_pkts[nb_rx]->pkt.pkt_len += rxm-\n> >pkt.pkt_len;\n> +\t\t\t\textra_idx++;\n> +\t\t\t};\n> +\t\t\tseg_res -= rcv_cnt;\n> +\t\t}\n> +\n> +\t\tVIRTIO_DUMP_PACKET(rx_pkts[nb_rx],\n> +\t\t\trx_pkts[nb_rx]->pkt.data_len);\n> +\n> +\t\trxvq->bytes += rx_pkts[nb_rx]->pkt.pkt_len;\n> +\t\tnb_rx++;\n> +\t}\n> +\n> +\trxvq->packets += nb_rx;\n> +\n> +\t/* Allocate new mbuf for the used descriptor */\n> +\terror = ENOSPC;\n> +\twhile (likely(!virtqueue_full(rxvq))) {\n> +\t\tnew_mbuf = rte_rxmbuf_alloc(rxvq->mpool);\n> +\t\tif (unlikely(new_mbuf == NULL)) {\n> +\t\t\tstruct rte_eth_dev *dev\n> +\t\t\t\t= &rte_eth_devices[rxvq->port_id];\n> +\t\t\tdev->data->rx_mbuf_alloc_failed++;\n> +\t\t\tbreak;\n> +\t\t}\n> +\t\terror = virtqueue_enqueue_recv_refill(rxvq, new_mbuf);\n> +\t\tif (unlikely(error)) {\n> +\t\t\trte_pktmbuf_free(new_mbuf);\n> +\t\t\tbreak;\n> +\t\t}\n> +\t\tnb_enqueued++;\n> +\t}\n> +\n>  \tif (likely(nb_enqueued)) {\n>  \t\tif (unlikely(virtqueue_kick_prepare(rxvq))) {\n>  \t\t\tvirtqueue_notify(rxvq);\n> @@ -536,12 +699,16 @@ virtio_xmit_pkts(void *tx_queue, struct rte_mbuf\n> **tx_pkts, uint16_t nb_pkts)\n>  \tnum = (uint16_t)(likely(nb_used < VIRTIO_MBUF_BURST_SZ) ?\n> nb_used : VIRTIO_MBUF_BURST_SZ);\n> \n>  \twhile (nb_tx < nb_pkts) {\n> -\t\tif (virtqueue_full(txvq) && num) {\n> +\t\tint need = tx_pkts[nb_tx]->pkt.nb_segs - txvq->vq_free_cnt;\n> +\t\tint deq_cnt = RTE_MIN(need, (int)num);\n> +\n> +\t\tnum -= (deq_cnt > 0) ? deq_cnt : 0;\n> +\t\twhile (deq_cnt > 0) {\n>  \t\t\tvirtqueue_dequeue_pkt_tx(txvq);\n> -\t\t\tnum--;\n> +\t\t\tdeq_cnt--;\n>  \t\t}\n> \n> -\t\tif (!virtqueue_full(txvq)) {\n> +\t\tif (tx_pkts[nb_tx]->pkt.nb_segs <= txvq->vq_free_cnt) {\n>  \t\t\ttxm = tx_pkts[nb_tx];\n>  \t\t\t/* Enqueue Packet buffers */\n>  \t\t\terror = virtqueue_enqueue_xmit(txvq, txm);\n> @@ -555,7 +722,7 @@ virtio_xmit_pkts(void *tx_queue, struct rte_mbuf\n> **tx_pkts, uint16_t nb_pkts)\n>  \t\t\t\tbreak;\n>  \t\t\t}\n>  \t\t\tnb_tx++;\n> -\t\t\ttxvq->bytes += txm->pkt.data_len;\n> +\t\t\ttxvq->bytes += txm->pkt.pkt_len;\n>  \t\t} else {\n>  \t\t\tPMD_TX_LOG(ERR, \"No free tx descriptors to\n> transmit\");\n>  \t\t\tbreak;\n> --\n> 1.8.4.2",
        "headers": {
            "Return-Path": "<changchun.ouyang@intel.com>",
            "References": "<1408006475-17606-1-git-send-email-changchun.ouyang@intel.com>",
            "X-Mailman-Version": "2.1.15",
            "X-IronPort-AV": "E=Sophos;i=\"4.97,862,1389772800\"; d=\"scan'208\";a=\"375051104\"",
            "From": "\"Ouyang, Changchun\" <changchun.ouyang@intel.com>",
            "x-originating-ip": "[10.239.127.40]",
            "List-Post": "<mailto:dev@dpdk.org>",
            "Thread-Index": "AQHPt51tb6N+uds10kqyddSCE1Jkx5vaTGTQ",
            "Content-Type": "text/plain; charset=\"us-ascii\"",
            "Thread-Topic": "[PATCH v3] virtio: Support mergeable buffer in virtio pmd",
            "Accept-Language": "zh-CN, en-US",
            "X-List-Received-Date": "Thu, 21 Aug 2014 01:19:36 -0000",
            "Received": [
                "from mga11.intel.com (mga11.intel.com [192.55.52.93])\n\tby dpdk.org (Postfix) with ESMTP id 536AF590C\n\tfor <dev@dpdk.org>; Thu, 21 Aug 2014 03:19:35 +0200 (CEST)",
                "from fmsmga003.fm.intel.com ([10.253.24.29])\n\tby fmsmga102.fm.intel.com with ESMTP; 20 Aug 2014 18:23:08 -0700",
                "from fmsmsx105.amr.corp.intel.com ([10.18.124.203])\n\tby FMSMGA003.fm.intel.com with ESMTP; 20 Aug 2014 18:19:19 -0700",
                "from fmsmsx117.amr.corp.intel.com (10.18.116.17) by\n\tFMSMSX105.amr.corp.intel.com (10.18.124.203) with Microsoft SMTP\n\tServer (TLS) id 14.3.195.1; Wed, 20 Aug 2014 18:23:07 -0700",
                "from shsmsx151.ccr.corp.intel.com (10.239.6.50) by\n\tfmsmsx117.amr.corp.intel.com (10.18.116.17) with Microsoft SMTP\n\tServer (TLS) id 14.3.195.1; Wed, 20 Aug 2014 18:23:06 -0700",
                "from shsmsx102.ccr.corp.intel.com ([169.254.2.246]) by\n\tSHSMSX151.ccr.corp.intel.com ([169.254.3.174]) with mapi id\n\t14.03.0195.001; Thu, 21 Aug 2014 09:23:05 +0800"
            ],
            "Subject": "Re: [dpdk-dev] [PATCH v3] virtio: Support mergeable buffer in\n\tvirtio pmd",
            "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
            "Content-Language": "en-US",
            "Message-ID": "<F52918179C57134FAEC9EA62FA2F962511839B08@shsmsx102.ccr.corp.intel.com>",
            "X-MS-Has-Attach": "",
            "X-BeenThere": "dev@dpdk.org",
            "Date": "Thu, 21 Aug 2014 01:23:04 +0000",
            "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
            "X-ExtLoop1": "1",
            "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
            "List-Id": "patches and discussions about DPDK <dev.dpdk.org>",
            "Precedence": "list",
            "In-Reply-To": "<1408006475-17606-1-git-send-email-changchun.ouyang@intel.com>",
            "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
            "MIME-Version": "1.0",
            "Content-Transfer-Encoding": "quoted-printable",
            "To": "\"dev@dpdk.org\" <dev@dpdk.org>",
            "X-MS-TNEF-Correlator": ""
        }
    },
    {
        "id": 442,
        "web_url": "http://patches.dpdk.org/comment/442/",
        "msgid": "<1507514.aMceMbYRTN@xps13>",
        "date": "2014-08-25T15:16:08",
        "subject": "Re: [dpdk-dev] [PATCH v3] virtio: Support mergeable buffer in\n\tvirtio pmd",
        "submitter": {
            "id": 1,
            "url": "http://patches.dpdk.org/api/people/1/",
            "name": "Thomas Monjalon",
            "email": "thomas.monjalon@6wind.com"
        },
        "content": "2014-08-14 16:54, Ouyang Changchun:\n> v3 change:\n> - Investigate the comments from Huawei and fix one potential issue of wrong offset to\n>   the number of descriptor in buffer; also fix other tiny comments.\n> \n> v2 change:\n> - Resolve conflicts with the tip code;\n> - And resolve 2 issues:\n>    -- fix mbuf leak when discard an uncompleted packet.\n>    -- refine pkt.data to point to actual payload data start point.\n>  \n> v1 change:\n> - This patch supports mergeable buffer feature in DPDK based virtio PMD, which can\n>   receive jumbo frame with larger size, like 3K, 4K or even 9K.\n> \n> Signed-off-by: Changchun Ouyang <changchun.ouyang@intel.com>\n> Acked-by: Huawei Xie <huawei.xie@intel.com>\n\nApplied for version 1.7.1.\n\nThanks",
        "headers": {
            "Return-Path": "<thomas.monjalon@6wind.com>",
            "References": "<1408006475-17606-1-git-send-email-changchun.ouyang@intel.com>",
            "X-Mailman-Version": "2.1.15",
            "From": "Thomas Monjalon <thomas.monjalon@6wind.com>",
            "X-List-Received-Date": "Mon, 25 Aug 2014 15:12:18 -0000",
            "User-Agent": "KMail/4.13.3 (Linux/3.15.8-1-ARCH; KDE/4.13.3; x86_64; ; )",
            "List-Post": "<mailto:dev@dpdk.org>",
            "X-BeenThere": "dev@dpdk.org",
            "Content-Type": "text/plain; charset=\"us-ascii\"",
            "To": "Ouyang Changchun <changchun.ouyang@intel.com>",
            "MIME-Version": "1.0",
            "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20130820;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:organization\n\t:user-agent:in-reply-to:references:mime-version\n\t:content-transfer-encoding:content-type;\n\tbh=VsXIOYdhpfjPO/T9x+J+Dz8vnL9W3wCdCq5+JeUYD98=;\n\tb=i6pR8HLK3rA6ZC4R4zr4mC4x1hOP1MAccfxT45lOYkuVGdV9BezgY9Yjn7ZH12UbGk\n\taQl0kfM/u/2+GWRRnCfcyvksRK00QqNVCj3EzVlvBZInBUXo/of7MhpiZOBZTr6/rQeY\n\toHHI5bxbOhz2ifCXfHJAWmiyPQqDufJNgAfUdt4t2QEHyDbFN8mtgsVplI3eE8XcpBbB\n\tNeqCAd7ApIQTZU0bMvgbyxmZ96HNS2t0zv0giIyQeJ+cKxIhvJ9fzTtWNQ6/2lJgYOS6\n\t9tBQ+JjwPnSu6ecpmq0Tkp+zDttn47mDOzuzUUEKczF3ljKYV5yqpmgJ+ogWh5a6ipGQ\n\tCD5Q==",
            "Received": [
                "from mail-wi0-f169.google.com (mail-wi0-f169.google.com\n\t[209.85.212.169]) by dpdk.org (Postfix) with ESMTP id 1B839B392\n\tfor <dev@dpdk.org>; Mon, 25 Aug 2014 17:12:18 +0200 (CEST)",
                "by mail-wi0-f169.google.com with SMTP id n3so3847411wiv.0\n\tfor <dev@dpdk.org>; Mon, 25 Aug 2014 08:16:13 -0700 (PDT)",
                "from xps13.localnet (136-92-190-109.dsl.ovh.fr. [109.190.92.136])\n\tby mx.google.com with ESMTPSA id\n\tz5sm1529936wib.20.2014.08.25.08.16.12 for <multiple recipients>\n\t(version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tMon, 25 Aug 2014 08:16:12 -0700 (PDT)"
            ],
            "Subject": "Re: [dpdk-dev] [PATCH v3] virtio: Support mergeable buffer in\n\tvirtio pmd",
            "X-Received": "by 10.194.205.196 with SMTP id li4mr22974388wjc.46.1408979773549;\n\tMon, 25 Aug 2014 08:16:13 -0700 (PDT)",
            "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
            "Message-ID": "<1507514.aMceMbYRTN@xps13>",
            "Precedence": "list",
            "X-Gm-Message-State": "ALoCoQllUFIWZ/d+nrGuyQ39QLH0VxzMtiWl6Sq1+ugvPjHJ7ABZ/Lg7vayMGrr9aNsQcm436FCW",
            "Date": "Mon, 25 Aug 2014 17:16:08 +0200",
            "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
            "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
            "Cc": "dev@dpdk.org",
            "List-Id": "patches and discussions about DPDK <dev.dpdk.org>",
            "In-Reply-To": "<1408006475-17606-1-git-send-email-changchun.ouyang@intel.com>",
            "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
            "Content-Transfer-Encoding": "7Bit",
            "Organization": "6WIND"
        }
    }
]