get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 124899,
    "url": "http://patches.dpdk.org/api/patches/124899/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20230309123752.2237828-4-david.marchand@redhat.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": "<20230309123752.2237828-4-david.marchand@redhat.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230309123752.2237828-4-david.marchand@redhat.com",
    "date": "2023-03-09T12:37:52",
    "name": "[3/3] net/vhost: fix Rx interrupt",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "baafbf1bd3ebcd7342c8b169b0204ec68ff73bf2",
    "submitter": {
        "id": 1173,
        "url": "http://patches.dpdk.org/api/people/1173/?format=api",
        "name": "David Marchand",
        "email": "david.marchand@redhat.com"
    },
    "delegate": {
        "id": 2642,
        "url": "http://patches.dpdk.org/api/users/2642/?format=api",
        "username": "mcoquelin",
        "first_name": "Maxime",
        "last_name": "Coquelin",
        "email": "maxime.coquelin@redhat.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20230309123752.2237828-4-david.marchand@redhat.com/mbox/",
    "series": [
        {
            "id": 27306,
            "url": "http://patches.dpdk.org/api/series/27306/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=27306",
            "date": "2023-03-09T12:37:49",
            "name": "net/vhost pmd fixes for Rx interrupts",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/27306/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/124899/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/124899/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 2B4A841E25;\n\tThu,  9 Mar 2023 13:38:23 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 4A4C942D1D;\n\tThu,  9 Mar 2023 13:38:12 +0100 (CET)",
            "from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.129.124])\n by mails.dpdk.org (Postfix) with ESMTP id D688442BAC\n for <dev@dpdk.org>; Thu,  9 Mar 2023 13:38:10 +0100 (CET)",
            "from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com\n [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n us-mta-283-NDNg7a25NWKSaniu6UHjdw-1; Thu, 09 Mar 2023 07:38:07 -0500",
            "from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com\n [10.11.54.3])\n (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n (No client certificate requested)\n by mimecast-mx02.redhat.com (Postfix) with ESMTPS id EA7E01C12989;\n Thu,  9 Mar 2023 12:38:06 +0000 (UTC)",
            "from dmarchan.redhat.com (unknown [10.45.224.63])\n by smtp.corp.redhat.com (Postfix) with ESMTP id 4FF011121314;\n Thu,  9 Mar 2023 12:38:05 +0000 (UTC)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1678365490;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=7/ybN4hQyRr9WsOgrohI5TGOYFxcV/B9PmDaNJ0EfFs=;\n b=aRV9QC70AURmhZLtCTvqe8fDK6lT+pt5L70rXkvj+f9fwm3oLwVT7Z/E4IH0pbg1q6Aj6g\n oPPldCbf27V4L/yiiihcnuR8mdYMJiCnhOoJJU+wYAY3Q+prf1bsN/fN2pnfIH+Zf6mM/8\n 8wZGD6xcgwGA9Vlrs8j9lKByvTYQl8g=",
        "X-MC-Unique": "NDNg7a25NWKSaniu6UHjdw-1",
        "From": "David Marchand <david.marchand@redhat.com>",
        "To": "dev@dpdk.org",
        "Cc": "stable@dpdk.org, Maxime Coquelin <maxime.coquelin@redhat.com>,\n Chenbo Xia <chenbo.xia@intel.com>, Jianfeng Tan <jianfeng.tan@intel.com>,\n Junjie Chen <junjie.j.chen@intel.com>, Hyong Youb Kim <hyonkim@cisco.com>,\n Harman Kalra <hkalra@marvell.com>",
        "Subject": "[PATCH 3/3] net/vhost: fix Rx interrupt",
        "Date": "Thu,  9 Mar 2023 13:37:52 +0100",
        "Message-Id": "<20230309123752.2237828-4-david.marchand@redhat.com>",
        "In-Reply-To": "<20230309123752.2237828-1-david.marchand@redhat.com>",
        "References": "<20230309123752.2237828-1-david.marchand@redhat.com>",
        "MIME-Version": "1.0",
        "X-Scanned-By": "MIMEDefang 3.1 on 10.11.54.3",
        "X-Mimecast-Spam-Score": "0",
        "X-Mimecast-Originator": "redhat.com",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain; charset=\"US-ASCII\"; x-default=true",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <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 <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "In the situation when a port was started while no virtio driver was\nconnected, Rx interrupts were broken.\nThey were also broken after a virtio driver reconnects.\n\nThere were several issues mixed in:\n- this driver was not exposing a fixed file descriptor per Rx queue,\n  If a virtio driver was not connected yet, each Rx queue vector was\n  pointing at a -1 fd, and an application could interpret this as a lack\n  of Rx interrupt support,\n- when a virtio driver later (re)connected, this net/vhost driver was\n  hacking into the EAL layer epoll fd to remove a old vring kickfd and\n  insert the new vring kickfd. This hack constitutes a layer violation\n  plus users of rte_eth_dev_rx_intr_ctl_q_get_fd() were not notified of\n  this change,\n- in the case of reconnection, because the interrupt handle was\n  reallocated, a 0 fd was failing to be removed from the EAL layer\n  epoll fd, which resulted in never fixing the EAL epoll fd,\n\nTo fix Rx interrupts:\n- allocating (eth_vhost_install_intr) / releasing\n  (eth_vhost_uninstall_intr) the interrupt handle is moved when\n  starting / closing the port, while setting / resetting per rxq fd is\n  triggered by vhost events via some new helpers (see\n  eth_vhost_configure_intr and eth_vhost_unconfigure_intr),\n- a \"proxy\" epoll fd is created per Rx queue at the time the interrupt\n  handle is allocated, so applications can start waiting for events on\n  those fds, even before a virtio driver initialises,\n- when available, vring kickd are populated in the \"proxy\" epoll fd,\n\nFixes: 3f8ff12821e4 (\"vhost: support interrupt mode\")\nFixes: 3d4cd4be577c (\"net/vhost: fix interrupt mode\")\nFixes: d61138d4f0e2 (\"drivers: remove direct access to interrupt handle\")\nCc: stable@dpdk.org\n\nSigned-off-by: David Marchand <david.marchand@redhat.com>\n---\n drivers/net/vhost/rte_eth_vhost.c | 318 ++++++++++++------------------\n 1 file changed, 127 insertions(+), 191 deletions(-)",
    "diff": "diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c\nindex 96deb18d91..62ef955ebc 100644\n--- a/drivers/net/vhost/rte_eth_vhost.c\n+++ b/drivers/net/vhost/rte_eth_vhost.c\n@@ -78,8 +78,9 @@ struct vhost_queue {\n \tuint16_t port;\n \tuint16_t virtqueue_id;\n \tstruct vhost_stats stats;\n-\tint intr_enable;\n \trte_spinlock_t intr_lock;\n+\tstruct epoll_event ev;\n+\tint kickfd;\n };\n \n struct pmd_internal {\n@@ -545,115 +546,68 @@ find_internal_resource(char *ifname)\n \treturn list;\n }\n \n-static int\n+static void\n eth_vhost_update_intr(struct rte_eth_dev *eth_dev, uint16_t rxq_idx)\n {\n-\tstruct rte_intr_handle *handle = eth_dev->intr_handle;\n-\tstruct rte_epoll_event rev, *elist;\n-\tint epfd, ret;\n-\n-\tif (handle == NULL)\n-\t\treturn 0;\n-\n-\telist = rte_intr_elist_index_get(handle, rxq_idx);\n-\tif (rte_intr_efds_index_get(handle, rxq_idx) == elist->fd)\n-\t\treturn 0;\n-\n-\tVHOST_LOG(INFO, \"kickfd for rxq-%d was changed, updating handler.\\n\",\n-\t\t\trxq_idx);\n+\tstruct rte_vhost_vring vring;\n+\tstruct vhost_queue *vq;\n \n-\tif (elist->fd != -1)\n-\t\tVHOST_LOG(ERR, \"Unexpected previous kickfd value (Got %d, expected -1).\\n\",\n-\t\t\telist->fd);\n+\tvq = eth_dev->data->rx_queues[rxq_idx];\n+\tif (vq == NULL || vq->vid < 0)\n+\t\treturn;\n \n-\t/*\n-\t * First remove invalid epoll event, and then install\n-\t * the new one. May be solved with a proper API in the\n-\t * future.\n-\t */\n-\tepfd = elist->epfd;\n-\trev = *elist;\n-\tret = rte_epoll_ctl(epfd, EPOLL_CTL_DEL, rev.fd,\n-\t\t\telist);\n-\tif (ret) {\n-\t\tVHOST_LOG(ERR, \"Delete epoll event failed.\\n\");\n-\t\treturn ret;\n+\tif (rte_vhost_get_vhost_vring(vq->vid, (rxq_idx << 1) + 1, &vring) < 0) {\n+\t\tVHOST_LOG(DEBUG, \"Failed to get rxq-%d's vring, skip!\\n\", rxq_idx);\n+\t\treturn;\n \t}\n \n-\trev.fd = rte_intr_efds_index_get(handle, rxq_idx);\n-\tif (rte_intr_elist_index_set(handle, rxq_idx, rev))\n-\t\treturn -rte_errno;\n+\trte_spinlock_lock(&vq->intr_lock);\n \n-\telist = rte_intr_elist_index_get(handle, rxq_idx);\n-\tret = rte_epoll_ctl(epfd, EPOLL_CTL_ADD, rev.fd, elist);\n-\tif (ret) {\n-\t\tVHOST_LOG(ERR, \"Add epoll event failed.\\n\");\n-\t\treturn ret;\n+\t/* Remove previous kickfd from proxy epoll */\n+\tif (vq->kickfd >= 0 && vq->kickfd != vring.kickfd) {\n+\t\tif (epoll_ctl(vq->ev.data.fd, EPOLL_CTL_DEL, vq->kickfd, &vq->ev) < 0) {\n+\t\t\tVHOST_LOG(DEBUG, \"Failed to unregister %d from rxq-%d epoll: %s\\n\",\n+\t\t\t\tvq->kickfd, rxq_idx, strerror(errno));\n+\t\t} else {\n+\t\t\tVHOST_LOG(DEBUG, \"Unregistered %d from rxq-%d epoll\\n\",\n+\t\t\t\tvq->kickfd, rxq_idx);\n+\t\t}\n+\t\tvq->kickfd = -1;\n+\t}\n+\n+\t/* Add new one, if valid */\n+\tif (vq->kickfd != vring.kickfd && vring.kickfd >= 0) {\n+\t\tif (epoll_ctl(vq->ev.data.fd, EPOLL_CTL_ADD, vring.kickfd, &vq->ev) < 0) {\n+\t\t\tVHOST_LOG(ERR, \"Failed to register %d in rxq-%d epoll: %s\\n\",\n+\t\t\t\tvring.kickfd, rxq_idx, strerror(errno));\n+\t\t} else {\n+\t\t\tvq->kickfd = vring.kickfd;\n+\t\t\tVHOST_LOG(DEBUG, \"Registered %d in rxq-%d epoll\\n\",\n+\t\t\t\tvq->kickfd, rxq_idx);\n+\t\t}\n \t}\n \n-\treturn 0;\n+\trte_spinlock_unlock(&vq->intr_lock);\n }\n \n static int\n eth_rxq_intr_enable(struct rte_eth_dev *dev, uint16_t qid)\n {\n-\tstruct rte_vhost_vring vring;\n-\tstruct vhost_queue *vq;\n-\tint old_intr_enable, ret = 0;\n-\n-\tvq = dev->data->rx_queues[qid];\n-\tif (!vq) {\n-\t\tVHOST_LOG(ERR, \"rxq%d is not setup yet\\n\", qid);\n-\t\treturn -1;\n-\t}\n-\n-\trte_spinlock_lock(&vq->intr_lock);\n-\told_intr_enable = vq->intr_enable;\n-\tvq->intr_enable = 1;\n-\tret = eth_vhost_update_intr(dev, qid);\n-\trte_spinlock_unlock(&vq->intr_lock);\n-\n-\tif (ret < 0) {\n-\t\tVHOST_LOG(ERR, \"Failed to update rxq%d's intr\\n\", qid);\n-\t\tvq->intr_enable = old_intr_enable;\n-\t\treturn ret;\n-\t}\n+\tstruct vhost_queue *vq = dev->data->rx_queues[qid];\n \n-\tret = rte_vhost_get_vhost_vring(vq->vid, (qid << 1) + 1, &vring);\n-\tif (ret < 0) {\n-\t\tVHOST_LOG(ERR, \"Failed to get rxq%d's vring\\n\", qid);\n-\t\treturn ret;\n-\t}\n-\tVHOST_LOG(INFO, \"Enable interrupt for rxq%d\\n\", qid);\n-\trte_vhost_enable_guest_notification(vq->vid, (qid << 1) + 1, 1);\n-\trte_wmb();\n+\tif (vq->vid >= 0)\n+\t\trte_vhost_enable_guest_notification(vq->vid, (qid << 1) + 1, 1);\n \n-\treturn ret;\n+\treturn 0;\n }\n \n static int\n eth_rxq_intr_disable(struct rte_eth_dev *dev, uint16_t qid)\n {\n-\tstruct rte_vhost_vring vring;\n-\tstruct vhost_queue *vq;\n-\tint ret = 0;\n-\n-\tvq = dev->data->rx_queues[qid];\n-\tif (!vq) {\n-\t\tVHOST_LOG(ERR, \"rxq%d is not setup yet\\n\", qid);\n-\t\treturn -1;\n-\t}\n+\tstruct vhost_queue *vq = dev->data->rx_queues[qid];\n \n-\tret = rte_vhost_get_vhost_vring(vq->vid, (qid << 1) + 1, &vring);\n-\tif (ret < 0) {\n-\t\tVHOST_LOG(ERR, \"Failed to get rxq%d's vring\\n\", qid);\n-\t\treturn ret;\n-\t}\n-\tVHOST_LOG(INFO, \"Disable interrupt for rxq%d\\n\", qid);\n-\trte_vhost_enable_guest_notification(vq->vid, (qid << 1) + 1, 0);\n-\trte_wmb();\n-\n-\tvq->intr_enable = 0;\n+\tif (vq->vid >= 0)\n+\t\trte_vhost_enable_guest_notification(vq->vid, (qid << 1) + 1, 0);\n \n \treturn 0;\n }\n@@ -664,6 +618,14 @@ eth_vhost_uninstall_intr(struct rte_eth_dev *dev)\n \tstruct rte_intr_handle *intr_handle = dev->intr_handle;\n \n \tif (intr_handle != NULL) {\n+\t\tint i;\n+\n+\t\tfor (i = 0; i < dev->data->nb_rx_queues; i++) {\n+\t\t\tint epoll_fd = rte_intr_efds_index_get(dev->intr_handle, i);\n+\n+\t\t\tif (epoll_fd >= 0)\n+\t\t\t\tclose(epoll_fd);\n+\t\t}\n \t\trte_intr_vec_list_free(intr_handle);\n \t\trte_intr_instance_free(intr_handle);\n \t}\n@@ -673,15 +635,11 @@ eth_vhost_uninstall_intr(struct rte_eth_dev *dev)\n static int\n eth_vhost_install_intr(struct rte_eth_dev *dev)\n {\n-\tstruct rte_vhost_vring vring;\n-\tstruct vhost_queue *vq;\n \tint nb_rxq = dev->data->nb_rx_queues;\n-\tint i;\n-\tint ret;\n+\tstruct vhost_queue *vq;\n \n-\t/* uninstall firstly if we are reconnecting */\n-\tif (dev->intr_handle != NULL)\n-\t\teth_vhost_uninstall_intr(dev);\n+\tint ret;\n+\tint i;\n \n \tdev->intr_handle = rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE);\n \tif (dev->intr_handle == NULL) {\n@@ -689,7 +647,7 @@ eth_vhost_install_intr(struct rte_eth_dev *dev)\n \t\tret = -ENOMEM;\n \t\tgoto error;\n \t}\n-\tif (rte_intr_efd_counter_size_set(dev->intr_handle, sizeof(uint64_t))) {\n+\tif (rte_intr_efd_counter_size_set(dev->intr_handle, 0)) {\n \t\tret = -rte_errno;\n \t\tgoto error;\n \t}\n@@ -700,40 +658,28 @@ eth_vhost_install_intr(struct rte_eth_dev *dev)\n \t\tgoto error;\n \t}\n \n-\n-\tVHOST_LOG(INFO, \"Prepare intr vec\\n\");\n+\tVHOST_LOG(DEBUG, \"Prepare intr vec\\n\");\n \tfor (i = 0; i < nb_rxq; i++) {\n-\t\tif (rte_intr_vec_list_index_set(dev->intr_handle, i,\n-\t\t\t\tRTE_INTR_VEC_RXTX_OFFSET + i)) {\n-\t\t\tret = -rte_errno;\n+\t\tint epoll_fd = epoll_create1(0);\n+\n+\t\tif (epoll_fd < 0) {\n+\t\t\tVHOST_LOG(ERR, \"Failed to create proxy epoll fd for rxq-%d\\n\", i);\n+\t\t\tret = -errno;\n \t\t\tgoto error;\n \t\t}\n-\t\tif (rte_intr_efds_index_set(dev->intr_handle, i, -1)) {\n+\n+\t\tif (rte_intr_vec_list_index_set(dev->intr_handle, i,\n+\t\t\t\tRTE_INTR_VEC_RXTX_OFFSET + i) ||\n+\t\t\t\trte_intr_efds_index_set(dev->intr_handle, i, epoll_fd)) {\n \t\t\tret = -rte_errno;\n+\t\t\tclose(epoll_fd);\n \t\t\tgoto error;\n \t\t}\n-\t\tvq = dev->data->rx_queues[i];\n-\t\tif (!vq) {\n-\t\t\tVHOST_LOG(INFO, \"rxq-%d not setup yet, skip!\\n\", i);\n-\t\t\tcontinue;\n-\t\t}\n-\n-\t\tret = rte_vhost_get_vhost_vring(vq->vid, (i << 1) + 1, &vring);\n-\t\tif (ret < 0) {\n-\t\t\tVHOST_LOG(INFO,\n-\t\t\t\t\"Failed to get rxq-%d's vring, skip!\\n\", i);\n-\t\t\tcontinue;\n-\t\t}\n-\n-\t\tif (vring.kickfd < 0) {\n-\t\t\tVHOST_LOG(INFO,\n-\t\t\t\t\"rxq-%d's kickfd is invalid, skip!\\n\", i);\n-\t\t\tcontinue;\n-\t\t}\n \n-\t\tif (rte_intr_efds_index_set(dev->intr_handle, i, vring.kickfd))\n-\t\t\tcontinue;\n-\t\tVHOST_LOG(INFO, \"Installed intr vec for rxq-%d\\n\", i);\n+\t\tvq = dev->data->rx_queues[i];\n+\t\tmemset(&vq->ev, 0, sizeof(vq->ev));\n+\t\tvq->ev.events = EPOLLIN;\n+\t\tvq->ev.data.fd = epoll_fd;\n \t}\n \n \tif (rte_intr_nb_efd_set(dev->intr_handle, nb_rxq)) {\n@@ -756,6 +702,46 @@ eth_vhost_install_intr(struct rte_eth_dev *dev)\n \treturn ret;\n }\n \n+static void\n+eth_vhost_configure_intr(struct rte_eth_dev *dev)\n+{\n+\tint i;\n+\n+\tVHOST_LOG(DEBUG, \"Configure intr vec\\n\");\n+\tfor (i = 0; i < dev->data->nb_rx_queues; i++)\n+\t\teth_vhost_update_intr(dev, i);\n+}\n+\n+static void\n+eth_vhost_unconfigure_intr(struct rte_eth_dev *eth_dev)\n+{\n+\tstruct vhost_queue *vq;\n+\tint i;\n+\n+\tVHOST_LOG(DEBUG, \"Unconfigure intr vec\\n\");\n+\tfor (i = 0; i < eth_dev->data->nb_rx_queues; i++) {\n+\t\tvq = eth_dev->data->rx_queues[i];\n+\t\tif (vq == NULL || vq->vid < 0)\n+\t\t\tcontinue;\n+\n+\t\trte_spinlock_lock(&vq->intr_lock);\n+\n+\t\t/* Remove previous kickfd from proxy epoll */\n+\t\tif (vq->kickfd >= 0) {\n+\t\t\tif (epoll_ctl(vq->ev.data.fd, EPOLL_CTL_DEL, vq->kickfd, &vq->ev) < 0) {\n+\t\t\t\tVHOST_LOG(DEBUG, \"Failed to unregister %d from rxq-%d epoll: %s\\n\",\n+\t\t\t\t\tvq->kickfd, i, strerror(errno));\n+\t\t\t} else {\n+\t\t\t\tVHOST_LOG(DEBUG, \"Unregistered %d from rxq-%d epoll\\n\",\n+\t\t\t\t\tvq->kickfd, i);\n+\t\t\t}\n+\t\t\tvq->kickfd = -1;\n+\t\t}\n+\n+\t\trte_spinlock_unlock(&vq->intr_lock);\n+\t}\n+}\n+\n static void\n update_queuing_status(struct rte_eth_dev *dev, bool wait_queuing)\n {\n@@ -862,16 +848,8 @@ new_device(int vid)\n \tinternal->vid = vid;\n \tif (rte_atomic32_read(&internal->started) == 1) {\n \t\tqueue_setup(eth_dev, internal);\n-\n-\t\tif (dev_conf->intr_conf.rxq) {\n-\t\t\tif (eth_vhost_install_intr(eth_dev) < 0) {\n-\t\t\t\tVHOST_LOG(INFO,\n-\t\t\t\t\t\"Failed to install interrupt handler.\\n\");\n-\t\t\t\t\treturn -1;\n-\t\t\t}\n-\t\t}\n-\t} else {\n-\t\tVHOST_LOG(INFO, \"RX/TX queues not exist yet\\n\");\n+\t\tif (dev_conf->intr_conf.rxq)\n+\t\t\teth_vhost_configure_intr(eth_dev);\n \t}\n \n \tfor (i = 0; i < rte_vhost_get_vring_num(vid); i++)\n@@ -915,6 +893,7 @@ destroy_device(int vid)\n \n \trte_atomic32_set(&internal->dev_attached, 0);\n \tupdate_queuing_status(eth_dev, true);\n+\teth_vhost_unconfigure_intr(eth_dev);\n \n \teth_dev->data->dev_link.link_status = RTE_ETH_LINK_DOWN;\n \n@@ -943,55 +922,10 @@ destroy_device(int vid)\n \trte_spinlock_unlock(&state->lock);\n \n \tVHOST_LOG(INFO, \"Vhost device %d destroyed\\n\", vid);\n-\teth_vhost_uninstall_intr(eth_dev);\n \n \trte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL);\n }\n \n-static int\n-vring_conf_update(int vid, struct rte_eth_dev *eth_dev, uint16_t vring_id)\n-{\n-\tstruct rte_eth_conf *dev_conf = &eth_dev->data->dev_conf;\n-\tstruct pmd_internal *internal = eth_dev->data->dev_private;\n-\tstruct vhost_queue *vq;\n-\tstruct rte_vhost_vring vring;\n-\tint rx_idx = vring_id % 2 ? (vring_id - 1) >> 1 : -1;\n-\tint ret = 0;\n-\n-\t/*\n-\t * The vring kickfd may be changed after the new device notification.\n-\t * Update it when the vring state is updated.\n-\t */\n-\tif (rx_idx >= 0 && rx_idx < eth_dev->data->nb_rx_queues &&\n-\t    rte_atomic32_read(&internal->dev_attached) &&\n-\t    rte_atomic32_read(&internal->started) &&\n-\t    dev_conf->intr_conf.rxq) {\n-\t\tret = rte_vhost_get_vhost_vring(vid, vring_id, &vring);\n-\t\tif (ret) {\n-\t\t\tVHOST_LOG(ERR, \"Failed to get vring %d information.\\n\",\n-\t\t\t\t\tvring_id);\n-\t\t\treturn ret;\n-\t\t}\n-\n-\t\tif (rte_intr_efds_index_set(eth_dev->intr_handle, rx_idx,\n-\t\t\t\t\t\t   vring.kickfd))\n-\t\t\treturn -rte_errno;\n-\n-\t\tvq = eth_dev->data->rx_queues[rx_idx];\n-\t\tif (!vq) {\n-\t\t\tVHOST_LOG(ERR, \"rxq%d is not setup yet\\n\", rx_idx);\n-\t\t\treturn -1;\n-\t\t}\n-\n-\t\trte_spinlock_lock(&vq->intr_lock);\n-\t\tif (vq->intr_enable)\n-\t\t\tret = eth_vhost_update_intr(eth_dev, rx_idx);\n-\t\trte_spinlock_unlock(&vq->intr_lock);\n-\t}\n-\n-\treturn ret;\n-}\n-\n static int\n vring_state_changed(int vid, uint16_t vring, int enable)\n {\n@@ -1011,9 +945,8 @@ vring_state_changed(int vid, uint16_t vring, int enable)\n \t/* won't be NULL */\n \tstate = vring_states[eth_dev->data->port_id];\n \n-\tif (enable && vring_conf_update(vid, eth_dev, vring))\n-\t\tVHOST_LOG(INFO, \"Failed to update vring-%d configuration.\\n\",\n-\t\t\t  (int)vring);\n+\tif (eth_dev->data->dev_conf.intr_conf.rxq && vring % 2)\n+\t\teth_vhost_update_intr(eth_dev, (vring - 1) >> 1);\n \n \trte_spinlock_lock(&state->lock);\n \tif (state->cur[vring] == enable) {\n@@ -1200,18 +1133,17 @@ eth_dev_start(struct rte_eth_dev *eth_dev)\n \tstruct pmd_internal *internal = eth_dev->data->dev_private;\n \tstruct rte_eth_conf *dev_conf = &eth_dev->data->dev_conf;\n \n-\tqueue_setup(eth_dev, internal);\n-\n-\tif (rte_atomic32_read(&internal->dev_attached) == 1) {\n-\t\tif (dev_conf->intr_conf.rxq) {\n-\t\t\tif (eth_vhost_install_intr(eth_dev) < 0) {\n-\t\t\t\tVHOST_LOG(INFO,\n-\t\t\t\t\t\"Failed to install interrupt handler.\\n\");\n-\t\t\t\t\treturn -1;\n-\t\t\t}\n-\t\t}\n+\teth_vhost_uninstall_intr(eth_dev);\n+\tif (dev_conf->intr_conf.rxq && eth_vhost_install_intr(eth_dev) < 0) {\n+\t\tVHOST_LOG(ERR, \"Failed to install interrupt handler.\\n\");\n+\t\treturn -1;\n \t}\n \n+\tqueue_setup(eth_dev, internal);\n+\tif (rte_atomic32_read(&internal->dev_attached) == 1 &&\n+\t\t\tdev_conf->intr_conf.rxq)\n+\t\teth_vhost_configure_intr(eth_dev);\n+\n \trte_atomic32_set(&internal->started, 1);\n \tupdate_queuing_status(eth_dev, false);\n \n@@ -1266,6 +1198,8 @@ eth_dev_close(struct rte_eth_dev *dev)\n \trte_free(internal->iface_name);\n \trte_free(internal);\n \n+\teth_vhost_uninstall_intr(dev);\n+\n \tdev->data->dev_private = NULL;\n \n \trte_free(vring_states[dev->data->port_id]);\n@@ -1293,6 +1227,7 @@ eth_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,\n \tvq->mb_pool = mb_pool;\n \tvq->virtqueue_id = rx_queue_id * VIRTIO_QNUM + VIRTIO_TXQ;\n \trte_spinlock_init(&vq->intr_lock);\n+\tvq->kickfd = -1;\n \tdev->data->rx_queues[rx_queue_id] = vq;\n \n \treturn 0;\n@@ -1315,6 +1250,7 @@ eth_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,\n \n \tvq->virtqueue_id = tx_queue_id * VIRTIO_QNUM + VIRTIO_RXQ;\n \trte_spinlock_init(&vq->intr_lock);\n+\tvq->kickfd = -1;\n \tdev->data->tx_queues[tx_queue_id] = vq;\n \n \treturn 0;\n",
    "prefixes": [
        "3/3"
    ]
}