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 79DECA04FD; Mon, 23 May 2022 12:23:45 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C1B0C42B8F; Mon, 23 May 2022 12:23:03 +0200 (CEST) Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by mails.dpdk.org (Postfix) with ESMTP id 7BE7540156 for ; Mon, 23 May 2022 12:23:02 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1653301382; x=1684837382; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=2Kn5/lPhfCLBUjN3qkKYL6oh6Is+p5mBsvE9047AfUA=; b=Y5B8Sgb72KApSHGg/j0oR/u6Rv5DYdiLOwcw396mxTIiovSegWg3VIhv Q++DVTqIn94YYHgZnsQv15OKdtFM0sVhcqRvu5eKZwy2FsizrUs9ELp3M wiQBMqoy3J2sPryYHQUWo3CYOcVO6WqB/FGnChzSLQYAts2kDGRnfwcNl sbkZV+dDlbkbk7oEvbXTLkwZ1U82Q6YENczroFTxpEBf4SWhsIIPfcFwo VEqVBZh7VtDfbvuXP9NQopAc4nyHSJhDj/mvbIW2O1gTUXvIXZB9XEFLm 6Fbj62tpz7U4GljvIWXOF/0Q1n3Ig9Ico4lc8kqUO7fS+BjuQN9Lo4mEv Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10355"; a="255239404" X-IronPort-AV: E=Sophos;i="5.91,246,1647327600"; d="scan'208";a="255239404" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 May 2022 03:23:02 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.91,246,1647327600"; d="scan'208";a="547889546" Received: from dpdk-dipei.sh.intel.com ([10.67.110.238]) by orsmga006.jf.intel.com with ESMTP; 23 May 2022 03:22:59 -0700 From: Andy Pei To: dev@dpdk.org Cc: chenbo.xia@intel.com, maxime.coquelin@redhat.com, gang.cao@intel.com, changpeng.liu@intel.com, rosen.xu@intel.com, qimaix.xiao@intel.com Subject: [PATCH v9 12/13] vdpa/ifc: add interrupt handling for config space Date: Mon, 23 May 2022 17:35:23 +0800 Message-Id: <1653298524-232138-13-git-send-email-andy.pei@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1653298524-232138-1-git-send-email-andy.pei@intel.com> References: <1643093258-47258-2-git-send-email-andy.pei@intel.com> <1653298524-232138-1-git-send-email-andy.pei@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 Create a thread to poll and relay config space change interrupt. Use VHOST_USER_SLAVE_CONFIG_CHANGE_MSG to inform QEMU. Signed-off-by: Andy Pei --- drivers/vdpa/ifc/ifcvf_vdpa.c | 121 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 120 insertions(+), 1 deletion(-) diff --git a/drivers/vdpa/ifc/ifcvf_vdpa.c b/drivers/vdpa/ifc/ifcvf_vdpa.c index 80d6261..af1f192 100644 --- a/drivers/vdpa/ifc/ifcvf_vdpa.c +++ b/drivers/vdpa/ifc/ifcvf_vdpa.c @@ -53,7 +53,9 @@ struct ifcvf_internal { int vfio_group_fd; int vfio_dev_fd; pthread_t tid; /* thread for notify relay */ + pthread_t intr_tid; /* thread for config space change interrupt relay */ int epfd; + int csc_epfd; int vid; struct rte_vdpa_device *vdev; uint16_t max_queues; @@ -566,6 +568,114 @@ struct rte_vdpa_dev_info { return 0; } +static void +virtio_interrupt_handler(struct ifcvf_internal *internal) +{ + int vid = internal->vid; + int ret; + + ret = rte_vhost_slave_config_change(vid, 1); + if (ret) + DRV_LOG(ERR, "failed to notify the guest about configuration space change."); +} + +static void * +intr_relay(void *arg) +{ + struct ifcvf_internal *internal = (struct ifcvf_internal *)arg; + struct epoll_event csc_event; + struct epoll_event ev; + uint64_t buf; + int nbytes; + int csc_epfd, csc_val = 0; + + csc_epfd = epoll_create(1); + if (csc_epfd < 0) { + DRV_LOG(ERR, "failed to create epoll for config space change."); + return NULL; + } + + ev.events = EPOLLIN | EPOLLPRI | EPOLLRDHUP | EPOLLHUP; + ev.data.fd = rte_intr_fd_get(internal->pdev->intr_handle); + if (epoll_ctl(csc_epfd, EPOLL_CTL_ADD, + rte_intr_fd_get(internal->pdev->intr_handle), &ev) < 0) { + DRV_LOG(ERR, "epoll add error: %s", strerror(errno)); + goto out; + } + + internal->csc_epfd = csc_epfd; + + for (;;) { + csc_val = epoll_wait(csc_epfd, &csc_event, 1, -1); + if (csc_val < 0) { + if (errno == EINTR) + continue; + DRV_LOG(ERR, "epoll_wait return fail."); + goto out; + } else if (csc_val == 0) { + continue; + } else { + /* csc_val > 0 */ + nbytes = read(csc_event.data.fd, &buf, 8); + if (nbytes < 0) { + if (errno == EINTR || + errno == EWOULDBLOCK || + errno == EAGAIN) + continue; + DRV_LOG(ERR, "Error reading from file descriptor %d: %s\n", + csc_event.data.fd, + strerror(errno)); + goto out; + } else if (nbytes == 0) { + DRV_LOG(ERR, "Read nothing from file descriptor %d\n", + csc_event.data.fd); + continue; + } else { + virtio_interrupt_handler(internal); + } + } + } + +out: + if (csc_epfd >= 0) + close(csc_epfd); + internal->csc_epfd = -1; + + return NULL; +} + +static int +setup_intr_relay(struct ifcvf_internal *internal) +{ + char name[THREAD_NAME_LEN]; + int ret; + + snprintf(name, sizeof(name), "ifc-intr-%d", internal->vid); + ret = rte_ctrl_thread_create(&internal->intr_tid, name, NULL, + intr_relay, (void *)internal); + if (ret) { + DRV_LOG(ERR, "failed to create notify relay pthread."); + return -1; + } + return 0; +} + +static void +unset_intr_relay(struct ifcvf_internal *internal) +{ + void *status; + + if (internal->intr_tid) { + pthread_cancel(internal->intr_tid); + pthread_join(internal->intr_tid, &status); + } + internal->intr_tid = 0; + + if (internal->csc_epfd >= 0) + close(internal->csc_epfd); + internal->csc_epfd = -1; +} + static int update_datapath(struct ifcvf_internal *internal) { @@ -592,10 +702,16 @@ struct rte_vdpa_dev_info { if (ret) goto err; + ret = setup_intr_relay(internal); + if (ret) + goto err; + rte_atomic32_set(&internal->running, 1); } else if (rte_atomic32_read(&internal->running) && (!rte_atomic32_read(&internal->started) || !rte_atomic32_read(&internal->dev_attached))) { + unset_intr_relay(internal); + ret = unset_notify_relay(internal); if (ret) goto err; @@ -812,7 +928,7 @@ struct rte_vdpa_dev_info { if (nfds < 0) { if (errno == EINTR) continue; - DRV_LOG(ERR, "epoll_wait return fail\n"); + DRV_LOG(ERR, "epoll_wait return fail."); return NULL; } @@ -888,6 +1004,9 @@ struct rte_vdpa_dev_info { /* stop the direct IO data path */ unset_notify_relay(internal); vdpa_ifcvf_stop(internal); + + unset_intr_relay(internal); + vdpa_disable_vfio_intr(internal); ret = rte_vhost_host_notifier_ctrl(vid, RTE_VHOST_QUEUE_ALL, false); -- 1.8.3.1