From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 6AA1D41E3A; Fri, 10 Mar 2023 08:35:24 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 4713D40685; Fri, 10 Mar 2023 08:35:24 +0100 (CET) Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by mails.dpdk.org (Postfix) with ESMTP id E928140150; Fri, 10 Mar 2023 08:35:21 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1678433722; x=1709969722; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=c6lSv2Wzc5EEeqiiyyavQWixGGLFR0c69DarNp25Hps=; b=cmtGSZidiqH3I5nVyO8Vz7QqFr3SNNhIJNv/m1b811vjOOamaKtXUZsJ O+zlvJDMdwl09o8NHadWNcAIUWBG6hP8ML1ZRASAqKWn+vTZgk3Z1iEZ9 NVgtWUcgjp+yFDE80BpXqwGbv1/yzW3QZIg5ST92a623fnZm6r47wMY07 QxZcEhvZeffP0ZKqA0gHIsGyv8jIqB3Bq4fUMJb1nxZfBx5p1LZnp/7k6 ByDYkkkysVEz3txUF9hwW6sOvZ+KuvaR+XIMrNJBe+6pF+KfwORrqQNXu gWQPPXDgpu7SA0kq/PzpKuv4VNA8XY18XkUhjulKT3ECvz/2aeqVsRdmK w==; X-IronPort-AV: E=McAfee;i="6500,9779,10644"; a="422936641" X-IronPort-AV: E=Sophos;i="5.98,249,1673942400"; d="scan'208";a="422936641" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Mar 2023 23:35:20 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10644"; a="923563937" X-IronPort-AV: E=Sophos;i="5.98,249,1673942400"; d="scan'208";a="923563937" Received: from fmsmsx603.amr.corp.intel.com ([10.18.126.83]) by fmsmga006.fm.intel.com with ESMTP; 09 Mar 2023 23:35:20 -0800 Received: from fmsmsx611.amr.corp.intel.com (10.18.126.91) by fmsmsx603.amr.corp.intel.com (10.18.126.83) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.21; Thu, 9 Mar 2023 23:35:20 -0800 Received: from fmsmsx601.amr.corp.intel.com (10.18.126.81) by fmsmsx611.amr.corp.intel.com (10.18.126.91) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.21; Thu, 9 Mar 2023 23:35:20 -0800 Received: from fmsedg602.ED.cps.intel.com (10.1.192.136) by fmsmsx601.amr.corp.intel.com (10.18.126.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.21 via Frontend Transport; Thu, 9 Mar 2023 23:35:20 -0800 Received: from NAM10-BN7-obe.outbound.protection.outlook.com (104.47.70.104) by edgegateway.intel.com (192.55.55.71) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.21; Thu, 9 Mar 2023 23:35:19 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=QWbVZJBFw4xVMN6pptIRPLZZmpm/KrcrpgjWPiFXPzGGfULqU0PQwi5z51jeNGi1CPL1Tk0nI+xBX0qGXbcBaIav1nQh0h4K+dIFpM9v9188m8AO0FUQRy7anKef9HLEA5DK77ty0ova97i9txIYH8D5hzAifSFTy8C1G53R0LV71dkhy7Ldi2BGBTCQRmf3v15b3XaXeHmWINj+PhHEePefK6qKxNu3OUayiVr0FRDZrd0Xxqkj+ILCsuPCH2+ft5+/wIkOgtofFjPpk6r0KTAZSJy58OGz59Ir/aQxL6lmi2cTBwq6Z79LyWSA9wR/5cHjKkApwgM/96X5N0fxig== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=HU8e9NBI8sAiLe74Bx9JFXOMhFXwxatnZX1bn493r5Q=; b=N4djsVIHeBmbe5nZ939qBrt82d8au+E0XIYbNhHPBvN1VlBXuF1Z5m1Ncfdug0zA+mIoJdBFD8DUq6WN6RVlT8SlC6d8/VnayemiRZvXKEZGm8f+CXzX4CzJKbXACpsyHE0YZfLxBBZ2tx8t33xJUDPGrDEpH40VpVQATBoOeaurH38D+gquxPi8y9rzFYlLrHBoOq9sbPmb5h7+2fiBZ8SacR3c757FMAyxxyQh24qQXNbzEWPksplgoAePxDs2yAlOpw7XyBwg0KF8b4OXKrNRL9DNpe1/PB4VcR3kFrmaXfeV5xY4YYXKJ17b7yMJYBMeyL5fFFTdDC+rvDFmmw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Received: from SN6PR11MB3504.namprd11.prod.outlook.com (2603:10b6:805:d0::17) by MW3PR11MB4553.namprd11.prod.outlook.com (2603:10b6:303:2c::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6178.19; Fri, 10 Mar 2023 07:35:14 +0000 Received: from SN6PR11MB3504.namprd11.prod.outlook.com ([fe80::930b:6671:e4f0:4ebc]) by SN6PR11MB3504.namprd11.prod.outlook.com ([fe80::930b:6671:e4f0:4ebc%3]) with mapi id 15.20.6178.019; Fri, 10 Mar 2023 07:35:14 +0000 From: "Xia, Chenbo" To: David Marchand , "dev@dpdk.org" CC: "stable@dpdk.org" , Maxime Coquelin , Jianfeng Tan , "Junjie Chen" , Hyong Youb Kim , "Harman Kalra" Subject: RE: [PATCH 3/3] net/vhost: fix Rx interrupt Thread-Topic: [PATCH 3/3] net/vhost: fix Rx interrupt Thread-Index: AQHZUoQOVCOqlgXkc0CB4ABkvbZFr67zoJaw Date: Fri, 10 Mar 2023 07:35:14 +0000 Message-ID: References: <20230309123752.2237828-1-david.marchand@redhat.com> <20230309123752.2237828-4-david.marchand@redhat.com> In-Reply-To: <20230309123752.2237828-4-david.marchand@redhat.com> Accept-Language: en-US, zh-CN Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: SN6PR11MB3504:EE_|MW3PR11MB4553:EE_ x-ms-office365-filtering-correlation-id: 7c15ddf6-6116-4722-823c-08db2139fcf3 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: v+D/BaKhhZQ6p/nG4AhBIGVB+Y+lDRhadvR9LNl+fEWjZ8G5yFRWXbDim5cQbv515mz8dwqj+jx5ME+/S44SEcTgrzjbJ0Q74eOA/2hEE4xgrkJl9LLB/P1rJwjz1w1dvf1tf0ZpJe8eqGDWPgS4p+zx39MSKTBDbz6nd55tMmEkaP9WDNIkZ8IiE2Iz6D4y7XsOWfMv6YIxe2B1ELS2sjo/WSYhg5j5Z6VKIgqB/S7y33rG8PDoVQYgSWCoEhy6cZvwiF4U3TDHxd49CJ642x47W6dNf2ccRjcHTDl1246NSAwlnLndinC1FhdT1RyRwbt9K0NPgs0nlXGftbjMo/X9JoWmkPUj11Hw17SrFYwQP6oftnrnlUP4JUMGOePqUZZ18ePFwadXhlvKBLENB5arwgP7IDjesbMYuXUdsdhdy8bxb5qq1YzagITroINuk99US6/as3RSr0oIe5HpkAR4J+6uLzLuNDSOldm967NkoEowqZF6DBC2HtmoAbeaYqTXh0d1SNrNbLuC681I/tqNLmOmsFT5P0iQZ/0EuNyPPgvsgIYwnzflkVjDoBeRUpBtKzQaaXjV6iJm68XRBd21yY8dre7Dk461AclbbVSoOBAZUreiGY1a24Xp+5zU589xRZPqCUI0gXeClhVt/HK9z6UqSR04QadZaYPZTEYtxivZclI4qFmMxGVRIUPIuBhxPMFEVwiUzfWsaLKwSA== x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:SN6PR11MB3504.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230025)(136003)(396003)(366004)(39860400002)(346002)(376002)(451199018)(110136005)(54906003)(33656002)(6506007)(122000001)(38100700002)(55016003)(86362001)(186003)(71200400001)(82960400001)(26005)(53546011)(83380400001)(9686003)(38070700005)(7696005)(52536014)(316002)(66946007)(478600001)(5660300002)(41300700001)(8936002)(4326008)(2906002)(30864003)(66476007)(64756008)(76116006)(66556008)(8676002)(66446008)(579004); DIR:OUT; SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?jSzi6m8QkhXdvGOP1Uy8HPprkDTuoP9MiPeNFGwWYpkEuyzZPPh+euhOm4KZ?= =?us-ascii?Q?oTDUePc6SLPbzrlRx4X/5DnGw7qmnyfdupaxSvmC5eworeb3Sd3pkbSoDDpH?= =?us-ascii?Q?LRzz2b2LV0wCQMvkMCGztKAcBFKixN5B/x/YX9fHSxjPvzjvoNep6pSc+SIK?= =?us-ascii?Q?rjRe/CgFi6U/34DyfzssXf9qtIVhWrkTbU6vwXXjQD8rdzw8HRfEkbhXmHos?= =?us-ascii?Q?KGqBrySrq7Q7bfuhPG/Jey6C8x5kR+e2OCJ19+Agdq7bSgGK5/3/+xp2gFeH?= =?us-ascii?Q?xSRzwhkol7uf9tsxMxBlOgEhS9yRmL6hp2sLu1MrC98h0unboBygJoTEBvBg?= =?us-ascii?Q?RlL+dVanYNtWwAlBg+aBAK2jAvvcmaP2p5vu6enr8rmWztPq3cLNrObyCmmQ?= =?us-ascii?Q?xFL+AkiYXnhYL4egJNVJhCXRzBV8FRg8KlcoIY9GfrcgDSNpMiSzdp8Civ17?= =?us-ascii?Q?Sq2jjTi69s+xjghqAElQYiYTN12u5udDTubCcyTs53H7lpaDaQbrIaiL/SFG?= =?us-ascii?Q?aQA/J9WWKCMtatyohCdByTKuBj+O7G6Q6Jh9/41FEs8D3MI/ZARQTabQFbZz?= =?us-ascii?Q?xUrkWtxZnkW3v7c2Knnf/HzLq+oMd3iMBhS3KoFACvR/AIF+hGqBxmaofmPX?= =?us-ascii?Q?8NunQp2uHrA+eUieDRjjKBnI4xA+LmgxAn7OZaAfESQK+CHuZjVHHfDpcli1?= =?us-ascii?Q?yajQXLDOVRyBzwcwJyl1PVSoByk7Kp+paeqM+ve4ZJly/kNKKlzaO46ehPUA?= =?us-ascii?Q?UtdbWgqm33vvBcyN81frg1HKSQsG5CtDur0b+EuMvPijHUmu21th/EOtZGuS?= =?us-ascii?Q?QZq/Q8wEa8Fz7PaALdVd4slDGrLWu5ewksL/kLYAvriQuO7Is38RQUtI/AvW?= =?us-ascii?Q?j/4xMAN42b189VQ8MYv0pYgshvt0OBbJqhh2j5PPu1Xln+6F8OUVYfsKnQHG?= =?us-ascii?Q?zgCPHcybdyeXiyjiemaifFeTLrKiHePQSJJ+uvvwnJuk+7mHQrHrg5YQnxIU?= =?us-ascii?Q?8xgbB4dJ3yQIuKzVp0K/rkpimPbxFTKG7c7Qq1QJxybfsY9VcMUpbls0pyhu?= =?us-ascii?Q?KbXrUx4XauW3l1KgKBJKhMt52s7LKdiQmHjyosYys0YjjasKrDbuxWT1dXvM?= =?us-ascii?Q?Ccrilb7+mm7YK6KDnJS0S5wt9YRMJSnR/aI9tYL/3VeJT9+ap7jaQlQoowN0?= =?us-ascii?Q?wnnx0UcZ5OpZQ5ShyjpedgFKwjBmYBt9uUKWr3Q3kjhF3I9UUa6EpV6WUo7e?= =?us-ascii?Q?QFQRbiOH/scTheENESU+xT7x03FwX2J+uW8zSQgFNydSDeAg+PlrOdgPsgIn?= =?us-ascii?Q?JiLVJqCIao6LpObmL/B5ZFJhLGuKQ/ipj7TuWX+be+pVoCl1EixU4g97GrRi?= =?us-ascii?Q?oK75m3EjR+YXlYM5ZsuFelyssgHyjd5uArVEjrtVUdUbDVavUjDjOVrJwK0u?= =?us-ascii?Q?tSXlYkd7Wkt+rchDyQyDizCtcECZ0dOK/2n5k8r017SPgFgfLV/qAJZWmeM8?= =?us-ascii?Q?x/cvwQ+f+WaaqCUFqKIxEpuPSJYcgOaYPNZTjeikg2O6y5imzHwEaRtouYAZ?= =?us-ascii?Q?knHJkWwqf+SPC/Yfw9S5wgDmh2t9roIOqXbn6ALt?= Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: SN6PR11MB3504.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 7c15ddf6-6116-4722-823c-08db2139fcf3 X-MS-Exchange-CrossTenant-originalarrivaltime: 10 Mar 2023 07:35:14.3101 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: n5v0FikM22leWnUUhIFLeX2b5PEOR5lyQ9I12YErBdIhi3a+KGDeqihxxgFjtqmwmScO+vZq2S1TYlDcUoX79g== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MW3PR11MB4553 X-OriginatorOrg: intel.com X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org > -----Original Message----- > From: David Marchand > Sent: Thursday, March 9, 2023 8:38 PM > To: dev@dpdk.org > Cc: stable@dpdk.org; Maxime Coquelin ; Xia, > Chenbo ; Jianfeng Tan ; > Junjie Chen ; Hyong Youb Kim = ; > Harman Kalra > Subject: [PATCH 3/3] net/vhost: fix Rx interrupt >=20 > In the situation when a port was started while no virtio driver was > connected, Rx interrupts were broken. > They were also broken after a virtio driver reconnects. >=20 > There were several issues mixed in: > - this driver was not exposing a fixed file descriptor per Rx queue, > If a virtio driver was not connected yet, each Rx queue vector was > pointing at a -1 fd, and an application could interpret this as a lack > of Rx interrupt support, > - when a virtio driver later (re)connected, this net/vhost driver was > hacking into the EAL layer epoll fd to remove a old vring kickfd and > insert the new vring kickfd. This hack constitutes a layer violation > plus users of rte_eth_dev_rx_intr_ctl_q_get_fd() were not notified of > this change, > - in the case of reconnection, because the interrupt handle was > reallocated, a 0 fd was failing to be removed from the EAL layer > epoll fd, which resulted in never fixing the EAL epoll fd, >=20 > To fix Rx interrupts: > - allocating (eth_vhost_install_intr) / releasing > (eth_vhost_uninstall_intr) the interrupt handle is moved when > starting / closing the port, while setting / resetting per rxq fd is > triggered by vhost events via some new helpers (see > eth_vhost_configure_intr and eth_vhost_unconfigure_intr), > - a "proxy" epoll fd is created per Rx queue at the time the interrupt > handle is allocated, so applications can start waiting for events on > those fds, even before a virtio driver initialises, > - when available, vring kickd are populated in the "proxy" epoll fd, >=20 > Fixes: 3f8ff12821e4 ("vhost: support interrupt mode") > Fixes: 3d4cd4be577c ("net/vhost: fix interrupt mode") > Fixes: d61138d4f0e2 ("drivers: remove direct access to interrupt handle") > Cc: stable@dpdk.org >=20 > Signed-off-by: David Marchand > --- > drivers/net/vhost/rte_eth_vhost.c | 318 ++++++++++++------------------ > 1 file changed, 127 insertions(+), 191 deletions(-) >=20 > diff --git a/drivers/net/vhost/rte_eth_vhost.c > b/drivers/net/vhost/rte_eth_vhost.c > index 96deb18d91..62ef955ebc 100644 > --- a/drivers/net/vhost/rte_eth_vhost.c > +++ b/drivers/net/vhost/rte_eth_vhost.c > @@ -78,8 +78,9 @@ struct vhost_queue { > uint16_t port; > uint16_t virtqueue_id; > struct vhost_stats stats; > - int intr_enable; > rte_spinlock_t intr_lock; > + struct epoll_event ev; > + int kickfd; > }; >=20 > struct pmd_internal { > @@ -545,115 +546,68 @@ find_internal_resource(char *ifname) > return list; > } >=20 > -static int > +static void > eth_vhost_update_intr(struct rte_eth_dev *eth_dev, uint16_t rxq_idx) > { > - struct rte_intr_handle *handle =3D eth_dev->intr_handle; > - struct rte_epoll_event rev, *elist; > - int epfd, ret; > - > - if (handle =3D=3D NULL) > - return 0; > - > - elist =3D rte_intr_elist_index_get(handle, rxq_idx); > - if (rte_intr_efds_index_get(handle, rxq_idx) =3D=3D elist->fd) > - return 0; > - > - VHOST_LOG(INFO, "kickfd for rxq-%d was changed, updating handler.\n", > - rxq_idx); > + struct rte_vhost_vring vring; > + struct vhost_queue *vq; >=20 > - if (elist->fd !=3D -1) > - VHOST_LOG(ERR, "Unexpected previous kickfd value (Got %d, > expected -1).\n", > - elist->fd); > + vq =3D eth_dev->data->rx_queues[rxq_idx]; > + if (vq =3D=3D NULL || vq->vid < 0) > + return; >=20 > - /* > - * First remove invalid epoll event, and then install > - * the new one. May be solved with a proper API in the > - * future. > - */ > - epfd =3D elist->epfd; > - rev =3D *elist; > - ret =3D rte_epoll_ctl(epfd, EPOLL_CTL_DEL, rev.fd, > - elist); > - if (ret) { > - VHOST_LOG(ERR, "Delete epoll event failed.\n"); > - return ret; > + if (rte_vhost_get_vhost_vring(vq->vid, (rxq_idx << 1) + 1, &vring) < > 0) { > + VHOST_LOG(DEBUG, "Failed to get rxq-%d's vring, skip!\n", > rxq_idx); > + return; > } >=20 > - rev.fd =3D rte_intr_efds_index_get(handle, rxq_idx); > - if (rte_intr_elist_index_set(handle, rxq_idx, rev)) > - return -rte_errno; > + rte_spinlock_lock(&vq->intr_lock); >=20 > - elist =3D rte_intr_elist_index_get(handle, rxq_idx); > - ret =3D rte_epoll_ctl(epfd, EPOLL_CTL_ADD, rev.fd, elist); > - if (ret) { > - VHOST_LOG(ERR, "Add epoll event failed.\n"); > - return ret; > + /* Remove previous kickfd from proxy epoll */ > + if (vq->kickfd >=3D 0 && vq->kickfd !=3D vring.kickfd) { > + if (epoll_ctl(vq->ev.data.fd, EPOLL_CTL_DEL, vq->kickfd, &vq- > >ev) < 0) { > + VHOST_LOG(DEBUG, "Failed to unregister %d from rxq-%d > epoll: %s\n", > + vq->kickfd, rxq_idx, strerror(errno)); > + } else { > + VHOST_LOG(DEBUG, "Unregistered %d from rxq-%d epoll\n", > + vq->kickfd, rxq_idx); > + } > + vq->kickfd =3D -1; > + } > + > + /* Add new one, if valid */ > + if (vq->kickfd !=3D vring.kickfd && vring.kickfd >=3D 0) { > + if (epoll_ctl(vq->ev.data.fd, EPOLL_CTL_ADD, vring.kickfd, > &vq->ev) < 0) { > + VHOST_LOG(ERR, "Failed to register %d in rxq-%d > epoll: %s\n", > + vring.kickfd, rxq_idx, strerror(errno)); > + } else { > + vq->kickfd =3D vring.kickfd; > + VHOST_LOG(DEBUG, "Registered %d in rxq-%d epoll\n", > + vq->kickfd, rxq_idx); > + } > } >=20 > - return 0; > + rte_spinlock_unlock(&vq->intr_lock); > } >=20 > static int > eth_rxq_intr_enable(struct rte_eth_dev *dev, uint16_t qid) > { > - struct rte_vhost_vring vring; > - struct vhost_queue *vq; > - int old_intr_enable, ret =3D 0; > - > - vq =3D dev->data->rx_queues[qid]; > - if (!vq) { > - VHOST_LOG(ERR, "rxq%d is not setup yet\n", qid); > - return -1; > - } > - > - rte_spinlock_lock(&vq->intr_lock); > - old_intr_enable =3D vq->intr_enable; > - vq->intr_enable =3D 1; > - ret =3D eth_vhost_update_intr(dev, qid); > - rte_spinlock_unlock(&vq->intr_lock); > - > - if (ret < 0) { > - VHOST_LOG(ERR, "Failed to update rxq%d's intr\n", qid); > - vq->intr_enable =3D old_intr_enable; > - return ret; > - } > + struct vhost_queue *vq =3D dev->data->rx_queues[qid]; >=20 > - ret =3D rte_vhost_get_vhost_vring(vq->vid, (qid << 1) + 1, &vring); > - if (ret < 0) { > - VHOST_LOG(ERR, "Failed to get rxq%d's vring\n", qid); > - return ret; > - } > - VHOST_LOG(INFO, "Enable interrupt for rxq%d\n", qid); > - rte_vhost_enable_guest_notification(vq->vid, (qid << 1) + 1, 1); > - rte_wmb(); > + if (vq->vid >=3D 0) > + rte_vhost_enable_guest_notification(vq->vid, (qid << 1) + 1, > 1); >=20 > - return ret; > + return 0; > } >=20 > static int > eth_rxq_intr_disable(struct rte_eth_dev *dev, uint16_t qid) > { > - struct rte_vhost_vring vring; > - struct vhost_queue *vq; > - int ret =3D 0; > - > - vq =3D dev->data->rx_queues[qid]; > - if (!vq) { > - VHOST_LOG(ERR, "rxq%d is not setup yet\n", qid); > - return -1; > - } > + struct vhost_queue *vq =3D dev->data->rx_queues[qid]; >=20 > - ret =3D rte_vhost_get_vhost_vring(vq->vid, (qid << 1) + 1, &vring); > - if (ret < 0) { > - VHOST_LOG(ERR, "Failed to get rxq%d's vring\n", qid); > - return ret; > - } > - VHOST_LOG(INFO, "Disable interrupt for rxq%d\n", qid); > - rte_vhost_enable_guest_notification(vq->vid, (qid << 1) + 1, 0); > - rte_wmb(); > - > - vq->intr_enable =3D 0; > + if (vq->vid >=3D 0) > + rte_vhost_enable_guest_notification(vq->vid, (qid << 1) + 1, > 0); >=20 > return 0; > } > @@ -664,6 +618,14 @@ eth_vhost_uninstall_intr(struct rte_eth_dev *dev) > struct rte_intr_handle *intr_handle =3D dev->intr_handle; >=20 > if (intr_handle !=3D NULL) { > + int i; > + > + for (i =3D 0; i < dev->data->nb_rx_queues; i++) { > + int epoll_fd =3D rte_intr_efds_index_get(dev->intr_handle, > i); > + > + if (epoll_fd >=3D 0) > + close(epoll_fd); > + } > rte_intr_vec_list_free(intr_handle); > rte_intr_instance_free(intr_handle); > } > @@ -673,15 +635,11 @@ eth_vhost_uninstall_intr(struct rte_eth_dev *dev) > static int > eth_vhost_install_intr(struct rte_eth_dev *dev) > { > - struct rte_vhost_vring vring; > - struct vhost_queue *vq; > int nb_rxq =3D dev->data->nb_rx_queues; > - int i; > - int ret; > + struct vhost_queue *vq; >=20 > - /* uninstall firstly if we are reconnecting */ > - if (dev->intr_handle !=3D NULL) > - eth_vhost_uninstall_intr(dev); > + int ret; > + int i; >=20 > dev->intr_handle =3D > rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE); > if (dev->intr_handle =3D=3D NULL) { > @@ -689,7 +647,7 @@ eth_vhost_install_intr(struct rte_eth_dev *dev) > ret =3D -ENOMEM; > goto error; > } > - if (rte_intr_efd_counter_size_set(dev->intr_handle, > sizeof(uint64_t))) { > + if (rte_intr_efd_counter_size_set(dev->intr_handle, 0)) { > ret =3D -rte_errno; > goto error; > } > @@ -700,40 +658,28 @@ eth_vhost_install_intr(struct rte_eth_dev *dev) > goto error; > } >=20 > - > - VHOST_LOG(INFO, "Prepare intr vec\n"); > + VHOST_LOG(DEBUG, "Prepare intr vec\n"); > for (i =3D 0; i < nb_rxq; i++) { > - if (rte_intr_vec_list_index_set(dev->intr_handle, i, > - RTE_INTR_VEC_RXTX_OFFSET + i)) { > - ret =3D -rte_errno; > + int epoll_fd =3D epoll_create1(0); > + > + if (epoll_fd < 0) { > + VHOST_LOG(ERR, "Failed to create proxy epoll fd for rxq- > %d\n", i); > + ret =3D -errno; > goto error; > } > - if (rte_intr_efds_index_set(dev->intr_handle, i, -1)) { > + > + if (rte_intr_vec_list_index_set(dev->intr_handle, i, > + RTE_INTR_VEC_RXTX_OFFSET + i) || > + rte_intr_efds_index_set(dev->intr_handle, i, > epoll_fd)) { > ret =3D -rte_errno; > + close(epoll_fd); > goto error; > } > - vq =3D dev->data->rx_queues[i]; > - if (!vq) { > - VHOST_LOG(INFO, "rxq-%d not setup yet, skip!\n", i); > - continue; > - } > - > - ret =3D rte_vhost_get_vhost_vring(vq->vid, (i << 1) + 1, &vring); > - if (ret < 0) { > - VHOST_LOG(INFO, > - "Failed to get rxq-%d's vring, skip!\n", i); > - continue; > - } > - > - if (vring.kickfd < 0) { > - VHOST_LOG(INFO, > - "rxq-%d's kickfd is invalid, skip!\n", i); > - continue; > - } >=20 > - if (rte_intr_efds_index_set(dev->intr_handle, i, vring.kickfd)) > - continue; > - VHOST_LOG(INFO, "Installed intr vec for rxq-%d\n", i); > + vq =3D dev->data->rx_queues[i]; > + memset(&vq->ev, 0, sizeof(vq->ev)); > + vq->ev.events =3D EPOLLIN; > + vq->ev.data.fd =3D epoll_fd; > } >=20 > if (rte_intr_nb_efd_set(dev->intr_handle, nb_rxq)) { > @@ -756,6 +702,46 @@ eth_vhost_install_intr(struct rte_eth_dev *dev) > return ret; > } >=20 > +static void > +eth_vhost_configure_intr(struct rte_eth_dev *dev) > +{ > + int i; > + > + VHOST_LOG(DEBUG, "Configure intr vec\n"); > + for (i =3D 0; i < dev->data->nb_rx_queues; i++) > + eth_vhost_update_intr(dev, i); > +} > + > +static void > +eth_vhost_unconfigure_intr(struct rte_eth_dev *eth_dev) > +{ > + struct vhost_queue *vq; > + int i; > + > + VHOST_LOG(DEBUG, "Unconfigure intr vec\n"); > + for (i =3D 0; i < eth_dev->data->nb_rx_queues; i++) { > + vq =3D eth_dev->data->rx_queues[i]; > + if (vq =3D=3D NULL || vq->vid < 0) > + continue; > + > + rte_spinlock_lock(&vq->intr_lock); > + > + /* Remove previous kickfd from proxy epoll */ > + if (vq->kickfd >=3D 0) { > + if (epoll_ctl(vq->ev.data.fd, EPOLL_CTL_DEL, vq->kickfd, > &vq->ev) < 0) { > + VHOST_LOG(DEBUG, "Failed to unregister %d from > rxq-%d epoll: %s\n", > + vq->kickfd, i, strerror(errno)); > + } else { > + VHOST_LOG(DEBUG, "Unregistered %d from rxq-%d > epoll\n", > + vq->kickfd, i); > + } > + vq->kickfd =3D -1; > + } > + > + rte_spinlock_unlock(&vq->intr_lock); > + } > +} > + > static void > update_queuing_status(struct rte_eth_dev *dev, bool wait_queuing) > { > @@ -862,16 +848,8 @@ new_device(int vid) > internal->vid =3D vid; > if (rte_atomic32_read(&internal->started) =3D=3D 1) { > queue_setup(eth_dev, internal); > - > - if (dev_conf->intr_conf.rxq) { > - if (eth_vhost_install_intr(eth_dev) < 0) { > - VHOST_LOG(INFO, > - "Failed to install interrupt handler.\n"); > - return -1; > - } > - } > - } else { > - VHOST_LOG(INFO, "RX/TX queues not exist yet\n"); > + if (dev_conf->intr_conf.rxq) > + eth_vhost_configure_intr(eth_dev); > } >=20 > for (i =3D 0; i < rte_vhost_get_vring_num(vid); i++) > @@ -915,6 +893,7 @@ destroy_device(int vid) >=20 > rte_atomic32_set(&internal->dev_attached, 0); > update_queuing_status(eth_dev, true); > + eth_vhost_unconfigure_intr(eth_dev); >=20 > eth_dev->data->dev_link.link_status =3D RTE_ETH_LINK_DOWN; >=20 > @@ -943,55 +922,10 @@ destroy_device(int vid) > rte_spinlock_unlock(&state->lock); >=20 > VHOST_LOG(INFO, "Vhost device %d destroyed\n", vid); > - eth_vhost_uninstall_intr(eth_dev); >=20 > rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL); > } >=20 > -static int > -vring_conf_update(int vid, struct rte_eth_dev *eth_dev, uint16_t vring_i= d) > -{ > - struct rte_eth_conf *dev_conf =3D ð_dev->data->dev_conf; > - struct pmd_internal *internal =3D eth_dev->data->dev_private; > - struct vhost_queue *vq; > - struct rte_vhost_vring vring; > - int rx_idx =3D vring_id % 2 ? (vring_id - 1) >> 1 : -1; > - int ret =3D 0; > - > - /* > - * The vring kickfd may be changed after the new device notification. > - * Update it when the vring state is updated. > - */ > - if (rx_idx >=3D 0 && rx_idx < eth_dev->data->nb_rx_queues && > - rte_atomic32_read(&internal->dev_attached) && > - rte_atomic32_read(&internal->started) && > - dev_conf->intr_conf.rxq) { > - ret =3D rte_vhost_get_vhost_vring(vid, vring_id, &vring); > - if (ret) { > - VHOST_LOG(ERR, "Failed to get vring %d information.\n", > - vring_id); > - return ret; > - } > - > - if (rte_intr_efds_index_set(eth_dev->intr_handle, rx_idx, > - vring.kickfd)) > - return -rte_errno; > - > - vq =3D eth_dev->data->rx_queues[rx_idx]; > - if (!vq) { > - VHOST_LOG(ERR, "rxq%d is not setup yet\n", rx_idx); > - return -1; > - } > - > - rte_spinlock_lock(&vq->intr_lock); > - if (vq->intr_enable) > - ret =3D eth_vhost_update_intr(eth_dev, rx_idx); > - rte_spinlock_unlock(&vq->intr_lock); > - } > - > - return ret; > -} > - > static int > vring_state_changed(int vid, uint16_t vring, int enable) > { > @@ -1011,9 +945,8 @@ vring_state_changed(int vid, uint16_t vring, int > enable) > /* won't be NULL */ > state =3D vring_states[eth_dev->data->port_id]; >=20 > - if (enable && vring_conf_update(vid, eth_dev, vring)) > - VHOST_LOG(INFO, "Failed to update vring-%d configuration.\n", > - (int)vring); > + if (eth_dev->data->dev_conf.intr_conf.rxq && vring % 2) > + eth_vhost_update_intr(eth_dev, (vring - 1) >> 1); >=20 > rte_spinlock_lock(&state->lock); > if (state->cur[vring] =3D=3D enable) { > @@ -1200,18 +1133,17 @@ eth_dev_start(struct rte_eth_dev *eth_dev) > struct pmd_internal *internal =3D eth_dev->data->dev_private; > struct rte_eth_conf *dev_conf =3D ð_dev->data->dev_conf; >=20 > - queue_setup(eth_dev, internal); > - > - if (rte_atomic32_read(&internal->dev_attached) =3D=3D 1) { > - if (dev_conf->intr_conf.rxq) { > - if (eth_vhost_install_intr(eth_dev) < 0) { > - VHOST_LOG(INFO, > - "Failed to install interrupt handler.\n"); > - return -1; > - } > - } > + eth_vhost_uninstall_intr(eth_dev); > + if (dev_conf->intr_conf.rxq && eth_vhost_install_intr(eth_dev) < 0) > { > + VHOST_LOG(ERR, "Failed to install interrupt handler.\n"); > + return -1; > } >=20 > + queue_setup(eth_dev, internal); > + if (rte_atomic32_read(&internal->dev_attached) =3D=3D 1 && > + dev_conf->intr_conf.rxq) > + eth_vhost_configure_intr(eth_dev); > + > rte_atomic32_set(&internal->started, 1); > update_queuing_status(eth_dev, false); >=20 > @@ -1266,6 +1198,8 @@ eth_dev_close(struct rte_eth_dev *dev) > rte_free(internal->iface_name); > rte_free(internal); >=20 > + eth_vhost_uninstall_intr(dev); > + > dev->data->dev_private =3D NULL; >=20 > rte_free(vring_states[dev->data->port_id]); > @@ -1293,6 +1227,7 @@ eth_rx_queue_setup(struct rte_eth_dev *dev, uint16_= t > rx_queue_id, > vq->mb_pool =3D mb_pool; > vq->virtqueue_id =3D rx_queue_id * VIRTIO_QNUM + VIRTIO_TXQ; > rte_spinlock_init(&vq->intr_lock); > + vq->kickfd =3D -1; > dev->data->rx_queues[rx_queue_id] =3D vq; >=20 > return 0; > @@ -1315,6 +1250,7 @@ eth_tx_queue_setup(struct rte_eth_dev *dev, uint16_= t > tx_queue_id, >=20 > vq->virtqueue_id =3D tx_queue_id * VIRTIO_QNUM + VIRTIO_RXQ; > rte_spinlock_init(&vq->intr_lock); > + vq->kickfd =3D -1; > dev->data->tx_queues[tx_queue_id] =3D vq; >=20 > return 0; > -- > 2.39.2 Reviewed-by: Chenbo Xia =20