X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fvdpa%2Fmlx5%2Fmlx5_vdpa_virtq.c;h=17e71cf4f45ca74435a464c09ab0fa887011a860;hb=f593944fc988dfccebed62205fd0b88c60ed7d77;hp=e99d82c3579b5616d8ced80d921a8352b28b3593;hpb=7de66d823e993fd0394a5604d03564a10f2be8e8;p=dpdk.git diff --git a/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c b/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c index e99d82c357..17e71cf4f4 100644 --- a/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c +++ b/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c @@ -36,6 +36,17 @@ mlx5_vdpa_virtq_handler(void *cb_arg) 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); } @@ -61,8 +72,13 @@ mlx5_vdpa_virtq_unset(struct mlx5_vdpa_virtq *virtq) } virtq->intr_handle.fd = -1; } - if (virtq->virtq) + if (virtq->virtq) { + ret = mlx5_vdpa_virtq_stop(virtq->priv, virtq->index); + if (ret) + DRV_LOG(WARNING, "Failed to stop virtq %d.", + virtq->index); claim_zero(mlx5_devx_cmd_destroy(virtq->virtq)); + } virtq->virtq = NULL; for (i = 0; i < RTE_DIM(virtq->umems); ++i) { if (virtq->umems[i].obj) @@ -79,6 +95,7 @@ mlx5_vdpa_virtq_unset(struct mlx5_vdpa_virtq *virtq) 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 +104,8 @@ mlx5_vdpa_virtqs_release(struct mlx5_vdpa_priv *priv) { 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; @@ -125,10 +140,14 @@ mlx5_vdpa_virtq_stop(struct mlx5_vdpa_priv *priv, int index) { struct mlx5_devx_virtq_attr attr = {0}; struct mlx5_vdpa_virtq *virtq = &priv->virtqs[index]; - int ret = mlx5_vdpa_virtq_modify(virtq, 0); + int ret; + if (virtq->stopped) + return 0; + ret = mlx5_vdpa_virtq_modify(virtq, 0); if (ret) return -1; + virtq->stopped = true; if (mlx5_devx_cmd_query_virtq(virtq->virtq, &attr)) { DRV_LOG(ERR, "Failed to query virtq %d.", index); return -1; @@ -143,6 +162,7 @@ mlx5_vdpa_virtq_stop(struct mlx5_vdpa_priv *priv, int index) 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; } @@ -284,10 +304,12 @@ mlx5_vdpa_virtq_setup(struct mlx5_vdpa_priv *priv, int index) attr.mkey = priv->gpa_mkey_index; attr.tis_id = priv->tis->id; attr.queue_index = index; + attr.pd = priv->pdn; virtq->virtq = mlx5_devx_cmd_create_virtq(priv->ctx, &attr); 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; @@ -296,10 +318,6 @@ mlx5_vdpa_virtq_setup(struct mlx5_vdpa_priv *priv, int index) 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, @@ -314,6 +332,9 @@ mlx5_vdpa_virtq_setup(struct mlx5_vdpa_priv *priv, int index) virtq->intr_handle.fd, index); } } + virtq->stopped = false; + DRV_LOG(DEBUG, "vid %u virtq %u was created successfully.", priv->vid, + index); return 0; error: mlx5_vdpa_virtq_unset(virtq); @@ -417,18 +438,35 @@ mlx5_vdpa_virtqs_prepare(struct mlx5_vdpa_priv *priv) 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) { @@ -437,35 +475,44 @@ mlx5_vdpa_virtq_enable(struct mlx5_vdpa_priv *priv, int index, int enable) 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 (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) { + virtq->enable = 0; + if (is_virtq_recvq(virtq->index, priv->nr_virtqs)) { + ret = mlx5_vdpa_steer_update(priv); if (ret) - DRV_LOG(WARNING, "Failed to stop virtq %d.", - index); - mlx5_vdpa_virtq_unset(virtq); + DRV_LOG(WARNING, "Failed to disable steering " + "for 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; - if (is_virtq_recvq(virtq->index, priv->nr_virtqs)) { - /* Need to add received virtq to the RQT table of the TIRs. */ - ret = mlx5_vdpa_steer_update(priv); - if (ret) { - virtq->enable = !enable; - return ret; + virtq->enable = 1; + if (is_virtq_recvq(virtq->index, priv->nr_virtqs)) { + ret = mlx5_vdpa_steer_update(priv); + if (ret) + DRV_LOG(WARNING, "Failed to enable steering " + "for virtq %d.", index); } } return 0;