From patchwork Thu Jun 25 13:38:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 72191 X-Patchwork-Delegate: maxime.coquelin@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 071E0A0350; Thu, 25 Jun 2020 15:38:54 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 808E51BEB7; Thu, 25 Jun 2020 15:38:38 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 1CCA01BEB5 for ; Thu, 25 Jun 2020 15:38:37 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from matan@mellanox.com) with SMTP; 25 Jun 2020 16:38:33 +0300 Received: from pegasus25.mtr.labs.mlnx. (pegasus25.mtr.labs.mlnx [10.210.16.10]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 05PDcK41009858; Thu, 25 Jun 2020 16:38:33 +0300 From: Matan Azrad To: Maxime Coquelin Cc: dev@dpdk.org, Xiao Wang Date: Thu, 25 Jun 2020 13:38:18 +0000 Message-Id: <1593092298-52257-6-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1593092298-52257-1-git-send-email-matan@mellanox.com> References: <1592497686-433697-1-git-send-email-matan@mellanox.com> <1593092298-52257-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v2 5/5] vdpa/mlx5: support queue update X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Last changes in vDPA device management by vhost library may cause queue ready state update after the device configuration. So, there is chance that some queue configuration information will be known only after the device was configured. Add support to reconfigure a queue after the device configuration according to the queue state update and the configuration changes. Adjust the host notifier and the guest notification configuration to be per queue and to be applied in the enablement process. Signed-off-by: Matan Azrad Reviewed-by: Maxime Coquelin --- drivers/vdpa/mlx5/mlx5_vdpa.c | 26 ------------ drivers/vdpa/mlx5/mlx5_vdpa.h | 8 +++- drivers/vdpa/mlx5/mlx5_vdpa_virtq.c | 80 ++++++++++++++++++++++++++----------- 3 files changed, 64 insertions(+), 50 deletions(-) diff --git a/drivers/vdpa/mlx5/mlx5_vdpa.c b/drivers/vdpa/mlx5/mlx5_vdpa.c index 51f3fe8..a2b1816 100644 --- a/drivers/vdpa/mlx5/mlx5_vdpa.c +++ b/drivers/vdpa/mlx5/mlx5_vdpa.c @@ -141,31 +141,6 @@ } static int -mlx5_vdpa_direct_db_prepare(struct mlx5_vdpa_priv *priv) -{ - int ret; - - if (priv->direct_notifier) { - ret = rte_vhost_host_notifier_ctrl(priv->vid, - RTE_VHOST_QUEUE_ALL, false); - if (ret != 0) { - DRV_LOG(INFO, "Direct HW notifier FD cannot be " - "destroyed for device %d: %d.", priv->vid, ret); - return -1; - } - priv->direct_notifier = 0; - } - ret = rte_vhost_host_notifier_ctrl(priv->vid, RTE_VHOST_QUEUE_ALL, - true); - if (ret != 0) - DRV_LOG(INFO, "Direct HW notifier FD cannot be configured for" - " device %d: %d.", priv->vid, ret); - else - priv->direct_notifier = 1; - return 0; -} - -static int mlx5_vdpa_features_set(int vid) { int did = rte_vhost_get_vdpa_device_id(vid); @@ -330,7 +305,6 @@ if (mlx5_vdpa_mtu_set(priv)) DRV_LOG(WARNING, "MTU cannot be set on device %d.", did); if (mlx5_vdpa_pd_create(priv) || mlx5_vdpa_mem_register(priv) || - mlx5_vdpa_direct_db_prepare(priv) || mlx5_vdpa_virtqs_prepare(priv) || mlx5_vdpa_steer_setup(priv) || mlx5_vdpa_cqe_event_setup(priv)) { mlx5_vdpa_dev_close(vid); diff --git a/drivers/vdpa/mlx5/mlx5_vdpa.h b/drivers/vdpa/mlx5/mlx5_vdpa.h index c0228b2..d4e405a 100644 --- a/drivers/vdpa/mlx5/mlx5_vdpa.h +++ b/drivers/vdpa/mlx5/mlx5_vdpa.h @@ -73,11 +73,18 @@ struct mlx5_vdpa_query_mr { int is_indirect; }; +enum { + MLX5_VDPA_NOTIFIER_STATE_DISABLED, + MLX5_VDPA_NOTIFIER_STATE_ENABLED, + MLX5_VDPA_NOTIFIER_STATE_ERR +}; + struct mlx5_vdpa_virtq { SLIST_ENTRY(mlx5_vdpa_virtq) next; uint8_t enable; uint16_t index; uint16_t vq_size; + uint8_t notifier_state; struct mlx5_vdpa_priv *priv; struct mlx5_devx_obj *virtq; struct mlx5_devx_obj *counters; @@ -112,7 +119,6 @@ enum { struct mlx5_vdpa_priv { TAILQ_ENTRY(mlx5_vdpa_priv) next; uint8_t configured; - uint8_t direct_notifier; /* Whether direct notifier is on or off. */ uint64_t last_traffic_tic; uint32_t last_total; pthread_t timer_tid; diff --git a/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c b/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c index 4b4d019..3e61264 100644 --- a/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c +++ b/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c @@ -36,6 +36,17 @@ break; } while (1); rte_write32(virtq->index, priv->virtq_db_addr); + if (virtq->notifier_state == MLX5_VDPA_NOTIFIER_STATE_DISABLED) { + if (rte_vhost_host_notifier_ctrl(priv->vid, virtq->index, true)) + virtq->notifier_state = MLX5_VDPA_NOTIFIER_STATE_ERR; + else + virtq->notifier_state = + MLX5_VDPA_NOTIFIER_STATE_ENABLED; + DRV_LOG(INFO, "Virtq %u notifier state is %s.", virtq->index, + virtq->notifier_state == + MLX5_VDPA_NOTIFIER_STATE_ENABLED ? "enabled" : + "disabled"); + } DRV_LOG(DEBUG, "Ring virtq %u doorbell.", virtq->index); } @@ -79,6 +90,7 @@ memset(&virtq->reset, 0, sizeof(virtq->reset)); if (virtq->eqp.fw_qp) mlx5_vdpa_event_qp_destroy(&virtq->eqp); + virtq->notifier_state = MLX5_VDPA_NOTIFIER_STATE_DISABLED; return 0; } @@ -87,10 +99,8 @@ { int i; - for (i = 0; i < priv->nr_virtqs; i++) { + for (i = 0; i < priv->nr_virtqs; i++) mlx5_vdpa_virtq_unset(&priv->virtqs[i]); - priv->virtqs[i].enable = 0; - } if (priv->tis) { claim_zero(mlx5_devx_cmd_destroy(priv->tis)); priv->tis = NULL; @@ -143,6 +153,7 @@ DRV_LOG(ERR, "Failed to set virtq %d base.", index); return -1; } + DRV_LOG(DEBUG, "vid %u virtq %u was stopped.", priv->vid, index); return 0; } @@ -289,6 +300,7 @@ virtq->priv = priv; if (!virtq->virtq) goto error; + claim_zero(rte_vhost_enable_guest_notification(priv->vid, index, 1)); if (mlx5_vdpa_virtq_modify(virtq, 1)) goto error; virtq->priv = priv; @@ -297,10 +309,6 @@ virtq->intr_handle.fd = vq.kickfd; if (virtq->intr_handle.fd == -1) { DRV_LOG(WARNING, "Virtq %d kickfd is invalid.", index); - if (!priv->direct_notifier) { - DRV_LOG(ERR, "Virtq %d cannot be notified.", index); - goto error; - } } else { virtq->intr_handle.type = RTE_INTR_HANDLE_EXT; if (rte_intr_callback_register(&virtq->intr_handle, @@ -315,6 +323,8 @@ virtq->intr_handle.fd, index); } } + DRV_LOG(DEBUG, "vid %u virtq %u was created successfully.", priv->vid, + index); return 0; error: mlx5_vdpa_virtq_unset(virtq); @@ -418,18 +428,35 @@ goto error; } priv->nr_virtqs = nr_vring; - for (i = 0; i < nr_vring; i++) { - claim_zero(rte_vhost_enable_guest_notification(priv->vid, i, - 1)); - if (mlx5_vdpa_virtq_setup(priv, i)) + for (i = 0; i < nr_vring; i++) + if (priv->virtqs[i].enable && mlx5_vdpa_virtq_setup(priv, i)) goto error; - } return 0; error: mlx5_vdpa_virtqs_release(priv); return -1; } +static int +mlx5_vdpa_virtq_is_modified(struct mlx5_vdpa_priv *priv, + struct mlx5_vdpa_virtq *virtq) +{ + struct rte_vhost_vring vq; + int ret = rte_vhost_get_vhost_vring(priv->vid, virtq->index, &vq); + + if (ret) + return -1; + if (vq.size != virtq->vq_size || vq.kickfd != virtq->intr_handle.fd) + return 1; + if (virtq->eqp.cq.cq) { + if (vq.callfd != virtq->eqp.cq.callfd) + return 1; + } else if (vq.callfd != -1) { + return 1; + } + return 0; +} + int mlx5_vdpa_virtq_enable(struct mlx5_vdpa_priv *priv, int index, int enable) { @@ -438,26 +465,33 @@ DRV_LOG(INFO, "Update virtq %d status %sable -> %sable.", index, virtq->enable ? "en" : "dis", enable ? "en" : "dis"); - if (virtq->enable == !!enable) - return 0; if (!priv->configured) { virtq->enable = !!enable; return 0; } - if (enable) { - /* Configuration might have been updated - reconfigure virtq. */ - if (virtq->virtq) { - ret = mlx5_vdpa_virtq_stop(priv, index); - if (ret) - DRV_LOG(WARNING, "Failed to stop virtq %d.", - index); - mlx5_vdpa_virtq_unset(virtq); + if (virtq->enable == !!enable) { + if (!enable) + return 0; + ret = mlx5_vdpa_virtq_is_modified(priv, virtq); + if (ret < 0) { + DRV_LOG(ERR, "Virtq %d modify check failed.", index); + return -1; } + if (ret == 0) + return 0; + DRV_LOG(INFO, "Virtq %d was modified, recreate it.", index); + } + if (virtq->virtq) { + ret = mlx5_vdpa_virtq_stop(priv, index); + if (ret) + DRV_LOG(WARNING, "Failed to stop virtq %d.", index); + mlx5_vdpa_virtq_unset(virtq); + } + if (enable) { ret = mlx5_vdpa_virtq_setup(priv, index); if (ret) { DRV_LOG(ERR, "Failed to setup virtq %d.", index); return ret; - /* The only case virtq can stay invalid. */ } } virtq->enable = !!enable;