get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 16946,
    "url": "https://patches.dpdk.org/api/patches/16946/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1478338865-26126-5-git-send-email-yuanhan.liu@linux.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": "<1478338865-26126-5-git-send-email-yuanhan.liu@linux.intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1478338865-26126-5-git-send-email-yuanhan.liu@linux.intel.com",
    "date": "2016-11-05T09:40:59",
    "name": "[dpdk-dev,v2,04/10] net/virtio: allocate queue at init stage",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "d57317856fab7d9223d17b14f9da6793807c0a9d",
    "submitter": {
        "id": 307,
        "url": "https://patches.dpdk.org/api/people/307/?format=api",
        "name": "Yuanhan Liu",
        "email": "yuanhan.liu@linux.intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1478338865-26126-5-git-send-email-yuanhan.liu@linux.intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/16946/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/16946/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 1FDF9475E;\n\tSat,  5 Nov 2016 10:41:08 +0100 (CET)",
            "from mga09.intel.com (mga09.intel.com [134.134.136.24])\n\tby dpdk.org (Postfix) with ESMTP id AC3E5137C\n\tfor <dev@dpdk.org>; Sat,  5 Nov 2016 10:40:22 +0100 (CET)",
            "from fmsmga004.fm.intel.com ([10.253.24.48])\n\tby orsmga102.jf.intel.com with ESMTP; 05 Nov 2016 02:40:22 -0700",
            "from yliu-dev.sh.intel.com ([10.239.67.162])\n\tby fmsmga004.fm.intel.com with ESMTP; 05 Nov 2016 02:40:20 -0700"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.31,448,1473145200\"; d=\"scan'208\";a=\"187945115\"",
        "From": "Yuanhan Liu <yuanhan.liu@linux.intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "Thomas Monjalon <thomas.monjalon@6wind.com>,\n\tTan Jianfeng <jianfeng.tan@intel.com>,\n\tKevin Traynor <ktraynor@redhat.com>, \n\tIlya Maximets <i.maximets@samsung.com>,\n\tKyle Larose <klarose@sandvine.com>, \n\tMaxime Coquelin <maxime.coquelin@redhat.com>,\n\tYuanhan Liu <yuanhan.liu@linux.intel.com>",
        "Date": "Sat,  5 Nov 2016 17:40:59 +0800",
        "Message-Id": "<1478338865-26126-5-git-send-email-yuanhan.liu@linux.intel.com>",
        "X-Mailer": "git-send-email 1.9.0",
        "In-Reply-To": "<1478338865-26126-1-git-send-email-yuanhan.liu@linux.intel.com>",
        "References": "<1478189400-14606-1-git-send-email-yuanhan.liu@linux.intel.com>\n\t<1478338865-26126-1-git-send-email-yuanhan.liu@linux.intel.com>",
        "Subject": "[dpdk-dev] [PATCH v2 04/10] net/virtio: allocate queue at init stage",
        "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": "Queue allocation should be done once, since the queue related info (such\nas vring addreess) will only be informed to the vhost-user backend once\nwithout virtio device reset.\n\nThat means, if you allocate queues again after the vhost-user negotiation,\nthe vhost-user backend will not be informed any more. Leading to a state\nthat the vring info mismatches between virtio PMD driver and vhost-backend:\nthe driver switches to the new address has just been allocated, while the\nvhost-backend still sticks to the old address has been assigned in the init\nstage.\n\nUnfortunately, that is exactly how the virtio driver is coded so far: queue\nallocation is done at queue_setup stage (when rte_eth_tx/rx_queue_setup is\ninvoked). This is wrong, because queue_setup can be invoked several times.\nFor example,\n\n    $ start_testpmd.sh ... --txq=1 --rxq=1 ...\n    > port stop 0\n    > port config all txq 1 # just trigger the queue_setup callback again\n    > port config all rxq 1\n    > port start 0\n\nThe right way to do is allocate the queues in the init stage, so that the\nvring info could be persistent with the vhost-user backend.\n\nBesides that, we should allocate max_queue pairs the device supports, but\nnot nr queue pairs firstly configured, to make following case work.\n\n    $ start_testpmd.sh ... --txq=1 --rxq=1 ...\n    > port stop 0\n    > port config all txq 2\n    > port config all rxq 2\n    > port start 0\n\nSince the allocation is switched to init stage, the free should also\nmoved from the rx/tx_queue_release to dev close stage. That leading we\ncould do nothing an empty rx/tx_queue_release() implementation.\n\nSigned-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>\n---\nv2: - free queues on dev close\n---\n drivers/net/virtio/virtio_ethdev.c | 162 +++++++++++++++++++++----------------\n drivers/net/virtio/virtio_ethdev.h |  14 ----\n drivers/net/virtio/virtio_pci.h    |   2 +\n drivers/net/virtio/virtio_rxtx.c   |  83 +++++--------------\n drivers/net/virtio/virtqueue.h     |   1 -\n 5 files changed, 111 insertions(+), 151 deletions(-)",
    "diff": "diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c\nindex 5a2c14b..67a175d 100644\n--- a/drivers/net/virtio/virtio_ethdev.c\n+++ b/drivers/net/virtio/virtio_ethdev.c\n@@ -280,28 +280,36 @@ virtio_set_multiple_queues(struct rte_eth_dev *dev, uint16_t nb_queues)\n \treturn 0;\n }\n \n-void\n-virtio_dev_queue_release(struct virtqueue *vq)\n+static void\n+virtio_dev_queue_release(void *queue __rte_unused)\n {\n-\tstruct virtio_hw *hw;\n+\t/* do nothing */\n+}\n \n-\tif (vq) {\n-\t\thw = vq->hw;\n-\t\tif (vq->configured)\n-\t\t\thw->vtpci_ops->del_queue(hw, vq);\n+static int\n+virtio_get_queue_type(struct virtio_hw *hw, uint16_t vtpci_queue_idx)\n+{\n+\tif (vtpci_queue_idx == hw->max_queue_pairs * 2)\n+\t\treturn VTNET_CQ;\n+\telse if (vtpci_queue_idx % 2 == 0)\n+\t\treturn VTNET_RQ;\n+\telse\n+\t\treturn VTNET_TQ;\n+}\n \n-\t\trte_free(vq->sw_ring);\n-\t\trte_free(vq);\n-\t}\n+static uint16_t\n+virtio_get_nr_vq(struct virtio_hw *hw)\n+{\n+\tuint16_t nr_vq = hw->max_queue_pairs * 2;\n+\n+\tif (vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VQ))\n+\t\tnr_vq += 1;\n+\n+\treturn nr_vq;\n }\n \n-int virtio_dev_queue_setup(struct rte_eth_dev *dev,\n-\t\t\tint queue_type,\n-\t\t\tuint16_t queue_idx,\n-\t\t\tuint16_t vtpci_queue_idx,\n-\t\t\tuint16_t nb_desc,\n-\t\t\tunsigned int socket_id,\n-\t\t\tvoid **pvq)\n+static int\n+virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)\n {\n \tchar vq_name[VIRTQUEUE_MAX_NAME_SZ];\n \tchar vq_hdr_name[VIRTQUEUE_MAX_NAME_SZ];\n@@ -314,6 +322,7 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,\n \tstruct virtqueue *vq;\n \tsize_t sz_hdr_mz = 0;\n \tvoid *sw_ring = NULL;\n+\tint queue_type = virtio_get_queue_type(hw, vtpci_queue_idx);\n \tint ret;\n \n \tPMD_INIT_LOG(DEBUG, \"setting up queue: %u\", vtpci_queue_idx);\n@@ -351,18 +360,18 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,\n \t\tsz_hdr_mz = PAGE_SIZE;\n \t}\n \n-\tvq = rte_zmalloc_socket(vq_name, size, RTE_CACHE_LINE_SIZE, socket_id);\n+\tvq = rte_zmalloc_socket(vq_name, size, RTE_CACHE_LINE_SIZE,\n+\t\t\t\tSOCKET_ID_ANY);\n \tif (vq == NULL) {\n \t\tPMD_INIT_LOG(ERR, \"can not allocate vq\");\n \t\treturn -ENOMEM;\n \t}\n+\thw->vqs[vtpci_queue_idx] = vq;\n+\n \tvq->hw = hw;\n \tvq->vq_queue_index = vtpci_queue_idx;\n \tvq->vq_nentries = vq_size;\n-\n-\tif (nb_desc == 0 || nb_desc > vq_size)\n-\t\tnb_desc = vq_size;\n-\tvq->vq_free_cnt = nb_desc;\n+\tvq->vq_free_cnt = vq_size;\n \n \t/*\n \t * Reserve a memzone for vring elements\n@@ -372,7 +381,8 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,\n \tPMD_INIT_LOG(DEBUG, \"vring_size: %d, rounded_vring_size: %d\",\n \t\t     size, vq->vq_ring_size);\n \n-\tmz = rte_memzone_reserve_aligned(vq_name, vq->vq_ring_size, socket_id,\n+\tmz = rte_memzone_reserve_aligned(vq_name, vq->vq_ring_size,\n+\t\t\t\t\t SOCKET_ID_ANY,\n \t\t\t\t\t 0, VIRTIO_PCI_VRING_ALIGN);\n \tif (mz == NULL) {\n \t\tif (rte_errno == EEXIST)\n@@ -396,7 +406,7 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,\n \t\tsnprintf(vq_hdr_name, sizeof(vq_hdr_name), \"port%d_vq%d_hdr\",\n \t\t\t dev->data->port_id, vtpci_queue_idx);\n \t\thdr_mz = rte_memzone_reserve_aligned(vq_hdr_name, sz_hdr_mz,\n-\t\t\t\t\t\t     socket_id, 0,\n+\t\t\t\t\t\t     SOCKET_ID_ANY, 0,\n \t\t\t\t\t\t     RTE_CACHE_LINE_SIZE);\n \t\tif (hdr_mz == NULL) {\n \t\t\tif (rte_errno == EEXIST)\n@@ -413,7 +423,7 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,\n \t\t\t       sizeof(vq->sw_ring[0]);\n \n \t\tsw_ring = rte_zmalloc_socket(\"sw_ring\", sz_sw,\n-\t\t\t\t\t     RTE_CACHE_LINE_SIZE, socket_id);\n+\t\t\t\tRTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);\n \t\tif (!sw_ring) {\n \t\t\tPMD_INIT_LOG(ERR, \"can not allocate RX soft ring\");\n \t\t\tret = -ENOMEM;\n@@ -424,19 +434,14 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,\n \t\trxvq = &vq->rxq;\n \t\trxvq->vq = vq;\n \t\trxvq->port_id = dev->data->port_id;\n-\t\trxvq->queue_id = queue_idx;\n \t\trxvq->mz = mz;\n-\t\t*pvq = rxvq;\n \t} else if (queue_type == VTNET_TQ) {\n \t\ttxvq = &vq->txq;\n \t\ttxvq->vq = vq;\n \t\ttxvq->port_id = dev->data->port_id;\n-\t\ttxvq->queue_id = queue_idx;\n \t\ttxvq->mz = mz;\n \t\ttxvq->virtio_net_hdr_mz = hdr_mz;\n \t\ttxvq->virtio_net_hdr_mem = hdr_mz->phys_addr;\n-\n-\t\t*pvq = txvq;\n \t} else if (queue_type == VTNET_CQ) {\n \t\tcvq = &vq->cq;\n \t\tcvq->vq = vq;\n@@ -444,7 +449,8 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,\n \t\tcvq->virtio_net_hdr_mz = hdr_mz;\n \t\tcvq->virtio_net_hdr_mem = hdr_mz->phys_addr;\n \t\tmemset(cvq->virtio_net_hdr_mz->addr, 0, PAGE_SIZE);\n-\t\t*pvq = cvq;\n+\n+\t\thw->cvq = cvq;\n \t}\n \n \t/* For virtio_user case (that is when dev->pci_dev is NULL), we use\n@@ -485,11 +491,9 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,\n \n \tif (hw->vtpci_ops->setup_queue(hw, vq) < 0) {\n \t\tPMD_INIT_LOG(ERR, \"setup_queue failed\");\n-\t\tvirtio_dev_queue_release(vq);\n \t\treturn -EINVAL;\n \t}\n \n-\tvq->configured = 1;\n \treturn 0;\n \n fail_q_alloc:\n@@ -501,40 +505,60 @@ fail_q_alloc:\n \treturn ret;\n }\n \n-static int\n-virtio_dev_cq_queue_setup(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx,\n-\t\tuint32_t socket_id)\n+static void\n+virtio_free_queues(struct virtio_hw *hw)\n {\n-\tstruct virtnet_ctl *cvq;\n-\tint ret;\n-\tstruct virtio_hw *hw = dev->data->dev_private;\n+\tuint16_t nr_vq = virtio_get_nr_vq(hw);\n+\tstruct virtqueue *vq;\n+\tint queue_type;\n+\tuint16_t i;\n \n-\tPMD_INIT_FUNC_TRACE();\n-\tret = virtio_dev_queue_setup(dev, VTNET_CQ, VTNET_SQ_CQ_QUEUE_IDX,\n-\t\t\tvtpci_queue_idx, 0, socket_id, (void **)&cvq);\n-\tif (ret < 0) {\n-\t\tPMD_INIT_LOG(ERR, \"control vq initialization failed\");\n-\t\treturn ret;\n+\tfor (i = 0; i < nr_vq; i++) {\n+\t\tvq = hw->vqs[i];\n+\t\tif (!vq)\n+\t\t\tcontinue;\n+\n+\t\tqueue_type = virtio_get_queue_type(hw, i);\n+\t\tif (queue_type == VTNET_RQ) {\n+\t\t\trte_free(vq->sw_ring);\n+\t\t\trte_memzone_free(vq->rxq.mz);\n+\t\t} else if (queue_type == VTNET_TQ) {\n+\t\t\trte_memzone_free(vq->txq.mz);\n+\t\t\trte_memzone_free(vq->txq.virtio_net_hdr_mz);\n+\t\t} else {\n+\t\t\trte_memzone_free(vq->cq.mz);\n+\t\t\trte_memzone_free(vq->cq.virtio_net_hdr_mz);\n+\t\t}\n+\n+\t\trte_free(vq);\n \t}\n \n-\thw->cvq = cvq;\n-\treturn 0;\n+\trte_free(hw->vqs);\n }\n \n-static void\n-virtio_free_queues(struct rte_eth_dev *dev)\n+static int\n+virtio_alloc_queues(struct rte_eth_dev *dev)\n {\n-\tunsigned int i;\n-\n-\tfor (i = 0; i < dev->data->nb_rx_queues; i++)\n-\t\tvirtio_dev_rx_queue_release(dev->data->rx_queues[i]);\n+\tstruct virtio_hw *hw = dev->data->dev_private;\n+\tuint16_t nr_vq = virtio_get_nr_vq(hw);\n+\tuint16_t i;\n+\tint ret;\n \n-\tdev->data->nb_rx_queues = 0;\n+\thw->vqs = rte_zmalloc(NULL, sizeof(struct virtqueue *) * nr_vq, 0);\n+\tif (!hw->vqs) {\n+\t\tPMD_INIT_LOG(ERR, \"failed to allocate vqs\");\n+\t\treturn -ENOMEM;\n+\t}\n \n-\tfor (i = 0; i < dev->data->nb_tx_queues; i++)\n-\t\tvirtio_dev_tx_queue_release(dev->data->tx_queues[i]);\n+\tfor (i = 0; i < nr_vq; i++) {\n+\t\tret = virtio_init_queue(dev, i);\n+\t\tif (ret < 0) {\n+\t\t\tvirtio_free_queues(hw);\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n \n-\tdev->data->nb_tx_queues = 0;\n+\treturn 0;\n }\n \n static void\n@@ -544,16 +568,13 @@ virtio_dev_close(struct rte_eth_dev *dev)\n \n \tPMD_INIT_LOG(DEBUG, \"virtio_dev_close\");\n \n-\tif (hw->cvq)\n-\t\tvirtio_dev_queue_release(hw->cvq->vq);\n-\n \t/* reset the NIC */\n \tif (dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)\n \t\tvtpci_irq_config(hw, VIRTIO_MSI_NO_VECTOR);\n \tvtpci_reset(hw);\n \thw->started = 0;\n \tvirtio_dev_free_mbufs(dev);\n-\tvirtio_free_queues(dev);\n+\tvirtio_free_queues(hw);\n }\n \n static void\n@@ -686,9 +707,9 @@ static const struct eth_dev_ops virtio_eth_dev_ops = {\n \t.xstats_reset            = virtio_dev_stats_reset,\n \t.link_update             = virtio_dev_link_update,\n \t.rx_queue_setup          = virtio_dev_rx_queue_setup,\n-\t.rx_queue_release        = virtio_dev_rx_queue_release,\n+\t.rx_queue_release        = virtio_dev_queue_release,\n \t.tx_queue_setup          = virtio_dev_tx_queue_setup,\n-\t.tx_queue_release        = virtio_dev_tx_queue_release,\n+\t.tx_queue_release        = virtio_dev_queue_release,\n \t/* collect stats per queue */\n \t.queue_stats_mapping_set = virtio_dev_queue_stats_mapping_set,\n \t.vlan_filter_set         = virtio_vlan_filter_set,\n@@ -1141,6 +1162,7 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)\n \tstruct virtio_net_config *config;\n \tstruct virtio_net_config local_config;\n \tstruct rte_pci_device *pci_dev = eth_dev->pci_dev;\n+\tint ret;\n \n \t/* Reset the device although not necessary at startup */\n \tvtpci_reset(hw);\n@@ -1222,6 +1244,10 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)\n \t\thw->max_queue_pairs = 1;\n \t}\n \n+\tret = virtio_alloc_queues(eth_dev);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n \tif (pci_dev)\n \t\tPMD_INIT_LOG(DEBUG, \"port %d vendorID=0x%x deviceID=0x%x\",\n \t\t\teth_dev->data->port_id, pci_dev->id.vendor_id,\n@@ -1390,15 +1416,9 @@ virtio_dev_configure(struct rte_eth_dev *dev)\n \t\treturn -ENOTSUP;\n \t}\n \n-\t/* Setup and start control queue */\n-\tif (vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VQ)) {\n-\t\tret = virtio_dev_cq_queue_setup(dev,\n-\t\t\thw->max_queue_pairs * 2,\n-\t\t\tSOCKET_ID_ANY);\n-\t\tif (ret < 0)\n-\t\t\treturn ret;\n+\t/* start control queue */\n+\tif (vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VQ))\n \t\tvirtio_dev_cq_start(dev);\n-\t}\n \n \thw->vlan_strip = rxmode->hw_vlan_strip;\n \ndiff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h\nindex de33b32..8a3fa6d 100644\n--- a/drivers/net/virtio/virtio_ethdev.h\n+++ b/drivers/net/virtio/virtio_ethdev.h\n@@ -80,29 +80,15 @@ void virtio_dev_cq_start(struct rte_eth_dev *dev);\n  */\n void virtio_dev_rxtx_start(struct rte_eth_dev *dev);\n \n-int virtio_dev_queue_setup(struct rte_eth_dev *dev,\n-\t\t\tint queue_type,\n-\t\t\tuint16_t queue_idx,\n-\t\t\tuint16_t vtpci_queue_idx,\n-\t\t\tuint16_t nb_desc,\n-\t\t\tunsigned int socket_id,\n-\t\t\tvoid **pvq);\n-\n-void virtio_dev_queue_release(struct virtqueue *vq);\n-\n int  virtio_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,\n \t\tuint16_t nb_rx_desc, unsigned int socket_id,\n \t\tconst struct rte_eth_rxconf *rx_conf,\n \t\tstruct rte_mempool *mb_pool);\n \n-void virtio_dev_rx_queue_release(void *rxq);\n-\n int  virtio_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,\n \t\tuint16_t nb_tx_desc, unsigned int socket_id,\n \t\tconst struct rte_eth_txconf *tx_conf);\n \n-void virtio_dev_tx_queue_release(void *txq);\n-\n uint16_t virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,\n \t\tuint16_t nb_pkts);\n \ndiff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h\nindex 0c5ed31..f63f76c 100644\n--- a/drivers/net/virtio/virtio_pci.h\n+++ b/drivers/net/virtio/virtio_pci.h\n@@ -264,6 +264,8 @@ struct virtio_hw {\n \tstruct virtio_net_config *dev_cfg;\n \tconst struct virtio_pci_ops *vtpci_ops;\n \tvoid\t    *virtio_user_dev;\n+\n+\tstruct virtqueue **vqs;\n };\n \n /*\ndiff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c\nindex b4c4aa4..6e7ff27 100644\n--- a/drivers/net/virtio/virtio_rxtx.c\n+++ b/drivers/net/virtio/virtio_rxtx.c\n@@ -530,24 +530,24 @@ int\n virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,\n \t\t\tuint16_t queue_idx,\n \t\t\tuint16_t nb_desc,\n-\t\t\tunsigned int socket_id,\n+\t\t\tunsigned int socket_id __rte_unused,\n \t\t\t__rte_unused const struct rte_eth_rxconf *rx_conf,\n \t\t\tstruct rte_mempool *mp)\n {\n \tuint16_t vtpci_queue_idx = 2 * queue_idx + VTNET_SQ_RQ_QUEUE_IDX;\n+\tstruct virtio_hw *hw = dev->data->dev_private;\n+\tstruct virtqueue *vq = hw->vqs[vtpci_queue_idx];\n \tstruct virtnet_rx *rxvq;\n-\tint ret;\n \n \tPMD_INIT_FUNC_TRACE();\n-\tret = virtio_dev_queue_setup(dev, VTNET_RQ, queue_idx, vtpci_queue_idx,\n-\t\t\tnb_desc, socket_id, (void **)&rxvq);\n-\tif (ret < 0) {\n-\t\tPMD_INIT_LOG(ERR, \"rvq initialization failed\");\n-\t\treturn ret;\n-\t}\n \n-\t/* Create mempool for rx mbuf allocation */\n+\tif (nb_desc == 0 || nb_desc > vq->vq_nentries)\n+\t\tnb_desc = vq->vq_nentries;\n+\tvq->vq_free_cnt = RTE_MIN(vq->vq_free_cnt, nb_desc);\n+\n+\trxvq = &vq->rxq;\n \trxvq->mpool = mp;\n+\trxvq->queue_id = queue_idx;\n \n \tdev->data->rx_queues[queue_idx] = rxvq;\n \n@@ -556,27 +556,6 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,\n \treturn 0;\n }\n \n-void\n-virtio_dev_rx_queue_release(void *rxq)\n-{\n-\tstruct virtnet_rx *rxvq = rxq;\n-\tstruct virtqueue *vq;\n-\tconst struct rte_memzone *mz;\n-\n-\tif (rxvq == NULL)\n-\t\treturn;\n-\n-\t/*\n-\t * rxvq is freed when vq is freed, and as mz should be freed after the\n-\t * del_queue, so we reserve the mz pointer first.\n-\t */\n-\tvq = rxvq->vq;\n-\tmz = rxvq->mz;\n-\n-\tvirtio_dev_queue_release(vq);\n-\trte_memzone_free(mz);\n-}\n-\n static void\n virtio_update_rxtx_handler(struct rte_eth_dev *dev,\n \t\t\t   const struct rte_eth_txconf *tx_conf)\n@@ -613,27 +592,25 @@ int\n virtio_dev_tx_queue_setup(struct rte_eth_dev *dev,\n \t\t\tuint16_t queue_idx,\n \t\t\tuint16_t nb_desc,\n-\t\t\tunsigned int socket_id,\n+\t\t\tunsigned int socket_id __rte_unused,\n \t\t\tconst struct rte_eth_txconf *tx_conf)\n {\n \tuint8_t vtpci_queue_idx = 2 * queue_idx + VTNET_SQ_TQ_QUEUE_IDX;\n+\tstruct virtio_hw *hw = dev->data->dev_private;\n+\tstruct virtqueue *vq = hw->vqs[vtpci_queue_idx];\n \tstruct virtnet_tx *txvq;\n-\tstruct virtqueue *vq;\n \tuint16_t tx_free_thresh;\n-\tint ret;\n \n \tPMD_INIT_FUNC_TRACE();\n \n-\n \tvirtio_update_rxtx_handler(dev, tx_conf);\n \n-\tret = virtio_dev_queue_setup(dev, VTNET_TQ, queue_idx, vtpci_queue_idx,\n-\t\t\tnb_desc, socket_id, (void **)&txvq);\n-\tif (ret < 0) {\n-\t\tPMD_INIT_LOG(ERR, \"tvq initialization failed\");\n-\t\treturn ret;\n-\t}\n-\tvq = txvq->vq;\n+\tif (nb_desc == 0 || nb_desc > vq->vq_nentries)\n+\t\tnb_desc = vq->vq_nentries;\n+\tvq->vq_free_cnt = RTE_MIN(vq->vq_free_cnt, nb_desc);\n+\n+\ttxvq = &vq->txq;\n+\ttxvq->queue_id = queue_idx;\n \n \ttx_free_thresh = tx_conf->tx_free_thresh;\n \tif (tx_free_thresh == 0)\n@@ -655,30 +632,6 @@ virtio_dev_tx_queue_setup(struct rte_eth_dev *dev,\n \treturn 0;\n }\n \n-void\n-virtio_dev_tx_queue_release(void *txq)\n-{\n-\tstruct virtnet_tx *txvq = txq;\n-\tstruct virtqueue *vq;\n-\tconst struct rte_memzone *mz;\n-\tconst struct rte_memzone *hdr_mz;\n-\n-\tif (txvq == NULL)\n-\t\treturn;\n-\n-\t/*\n-\t * txvq is freed when vq is freed, and as mz should be freed after the\n-\t * del_queue, so we reserve the mz pointer first.\n-\t */\n-\tvq = txvq->vq;\n-\tmz = txvq->mz;\n-\thdr_mz = txvq->virtio_net_hdr_mz;\n-\n-\tvirtio_dev_queue_release(vq);\n-\trte_memzone_free(mz);\n-\trte_memzone_free(hdr_mz);\n-}\n-\n static void\n virtio_discard_rxbuf(struct virtqueue *vq, struct rte_mbuf *m)\n {\ndiff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h\nindex bbeb2f2..f0bb089 100644\n--- a/drivers/net/virtio/virtqueue.h\n+++ b/drivers/net/virtio/virtqueue.h\n@@ -211,7 +211,6 @@ struct virtqueue {\n \tuint16_t  vq_queue_index;   /**< PCI queue index */\n \tuint16_t offset; /**< relative offset to obtain addr in mbuf */\n \tuint16_t  *notify_addr;\n-\tint configured;\n \tstruct rte_mbuf **sw_ring;  /**< RX software ring. */\n \tstruct vq_desc_extra vq_descx[0];\n };\n",
    "prefixes": [
        "dpdk-dev",
        "v2",
        "04/10"
    ]
}