X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fvdpa%2Fmlx5%2Fmlx5_vdpa_virtq.c;h=f530646058fa16e86df0a10ae2f099e2d49febd0;hb=4ad8bc2fc7857a92aa0bb147529859358c5acc4f;hp=17e71cf4f45ca74435a464c09ab0fa887011a860;hpb=118494d3ad0882a3be77a99457f8659df15756d6;p=dpdk.git diff --git a/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c b/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c index 17e71cf4f4..f530646058 100644 --- a/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c +++ b/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c @@ -88,11 +88,6 @@ mlx5_vdpa_virtq_unset(struct mlx5_vdpa_virtq *virtq) rte_free(virtq->umems[i].buf); } memset(&virtq->umems, 0, sizeof(virtq->umems)); - if (virtq->counters) { - claim_zero(mlx5_devx_cmd_destroy(virtq->counters)); - virtq->counters = NULL; - } - 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; @@ -103,12 +98,19 @@ void mlx5_vdpa_virtqs_release(struct mlx5_vdpa_priv *priv) { int i; + struct mlx5_vdpa_virtq *virtq; - for (i = 0; i < priv->nr_virtqs; i++) - mlx5_vdpa_virtq_unset(&priv->virtqs[i]); - if (priv->tis) { - claim_zero(mlx5_devx_cmd_destroy(priv->tis)); - priv->tis = NULL; + for (i = 0; i < priv->nr_virtqs; i++) { + virtq = &priv->virtqs[i]; + mlx5_vdpa_virtq_unset(virtq); + if (virtq->counters) + claim_zero(mlx5_devx_cmd_destroy(virtq->counters)); + } + for (i = 0; i < priv->num_lag_ports; i++) { + if (priv->tiss[i]) { + claim_zero(mlx5_devx_cmd_destroy(priv->tiss[i])); + priv->tiss[i] = NULL; + } } if (priv->td) { claim_zero(mlx5_devx_cmd_destroy(priv->td)); @@ -119,6 +121,7 @@ mlx5_vdpa_virtqs_release(struct mlx5_vdpa_priv *priv) priv->virtq_db_addr = NULL; } priv->features = 0; + memset(priv->virtqs, 0, sizeof(*virtq) * priv->nr_virtqs); priv->nr_virtqs = 0; } @@ -138,7 +141,6 @@ mlx5_vdpa_virtq_modify(struct mlx5_vdpa_virtq *virtq, int state) int 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; @@ -148,6 +150,17 @@ mlx5_vdpa_virtq_stop(struct mlx5_vdpa_priv *priv, int index) if (ret) return -1; virtq->stopped = true; + DRV_LOG(DEBUG, "vid %u virtq %u was stopped.", priv->vid, index); + return mlx5_vdpa_virtq_query(priv, index); +} + +int +mlx5_vdpa_virtq_query(struct mlx5_vdpa_priv *priv, int index) +{ + struct mlx5_devx_virtq_attr attr = {0}; + struct mlx5_vdpa_virtq *virtq = &priv->virtqs[index]; + int ret; + if (mlx5_devx_cmd_query_virtq(virtq->virtq, &attr)) { DRV_LOG(ERR, "Failed to query virtq %d.", index); return -1; @@ -162,7 +175,9 @@ 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); + if (attr.state == MLX5_VIRTQ_STATE_ERROR) + DRV_LOG(WARNING, "vid %d vring %d hw error=%hhu", + priv->vid, index, attr.error_type); return 0; } @@ -195,6 +210,8 @@ mlx5_vdpa_virtq_setup(struct mlx5_vdpa_priv *priv, int index) unsigned int i; uint16_t last_avail_idx; uint16_t last_used_idx; + uint16_t event_num = MLX5_EVENT_TYPE_OBJECT_CHANGE; + uint64_t cookie; ret = rte_vhost_get_vhost_vring(priv->vid, index, &vq); if (ret) @@ -231,8 +248,9 @@ mlx5_vdpa_virtq_setup(struct mlx5_vdpa_priv *priv, int index) " need event QPs and event mechanism.", index); } if (priv->caps.queue_counters_valid) { - virtq->counters = mlx5_devx_cmd_create_virtio_q_counters - (priv->ctx); + if (!virtq->counters) + virtq->counters = mlx5_devx_cmd_create_virtio_q_counters + (priv->ctx); if (!virtq->counters) { DRV_LOG(ERR, "Failed to create virtq couners for virtq" " %d.", index); @@ -302,9 +320,12 @@ mlx5_vdpa_virtq_setup(struct mlx5_vdpa_priv *priv, int index) attr.hw_used_index = last_used_idx; attr.q_size = vq.size; attr.mkey = priv->gpa_mkey_index; - attr.tis_id = priv->tis->id; + attr.tis_id = priv->tiss[(index / 2) % priv->num_lag_ports]->id; attr.queue_index = index; attr.pd = priv->pdn; + attr.hw_latency_mode = priv->hw_latency_mode; + attr.hw_max_latency_us = priv->hw_max_latency_us; + attr.hw_max_pending_comp = priv->hw_max_pending_comp; virtq->virtq = mlx5_devx_cmd_create_virtq(priv->ctx, &attr); virtq->priv = priv; if (!virtq->virtq) @@ -332,6 +353,19 @@ mlx5_vdpa_virtq_setup(struct mlx5_vdpa_priv *priv, int index) virtq->intr_handle.fd, index); } } + /* Subscribe virtq error event. */ + virtq->version++; + cookie = ((uint64_t)virtq->version << 32) + index; + ret = mlx5_glue->devx_subscribe_devx_event(priv->err_chnl, + virtq->virtq->obj, + sizeof(event_num), + &event_num, cookie); + if (ret) { + DRV_LOG(ERR, "Failed to subscribe device %d virtq %d error event.", + priv->vid, index); + rte_errno = errno; + goto error; + } virtq->stopped = false; DRV_LOG(DEBUG, "vid %u virtq %u was created successfully.", priv->vid, index); @@ -408,6 +442,13 @@ mlx5_vdpa_virtqs_prepare(struct mlx5_vdpa_priv *priv) DRV_LOG(ERR, "Failed to configure negotiated features."); return -1; } + if ((priv->features & (1ULL << VIRTIO_NET_F_CSUM)) == 0 && + ((priv->features & (1ULL << VIRTIO_NET_F_HOST_TSO4)) > 0 || + (priv->features & (1ULL << VIRTIO_NET_F_HOST_TSO6)) > 0)) { + /* Packet may be corrupted if TSO is enabled without CSUM. */ + DRV_LOG(INFO, "TSO is enabled without CSUM, force CSUM."); + priv->features |= (1ULL << VIRTIO_NET_F_CSUM); + } if (nr_vring > priv->caps.max_num_virtio_queues * 2) { DRV_LOG(ERR, "Do not support more than %d virtqs(%d).", (int)priv->caps.max_num_virtio_queues * 2, @@ -432,10 +473,14 @@ mlx5_vdpa_virtqs_prepare(struct mlx5_vdpa_priv *priv) return -rte_errno; } tis_attr.transport_domain = priv->td->id; - priv->tis = mlx5_devx_cmd_create_tis(priv->ctx, &tis_attr); - if (!priv->tis) { - DRV_LOG(ERR, "Failed to create TIS."); - goto error; + for (i = 0; i < priv->num_lag_ports; i++) { + /* 0 is auto affinity, non-zero value to propose port. */ + tis_attr.lag_tx_port_affinity = i + 1; + priv->tiss[i] = mlx5_devx_cmd_create_tis(priv->ctx, &tis_attr); + if (!priv->tiss[i]) { + DRV_LOG(ERR, "Failed to create TIS %u.", i); + goto error; + } } priv->nr_virtqs = nr_vring; for (i = 0; i < nr_vring; i++) @@ -458,7 +503,7 @@ mlx5_vdpa_virtq_is_modified(struct mlx5_vdpa_priv *priv, return -1; if (vq.size != virtq->vq_size || vq.kickfd != virtq->intr_handle.fd) return 1; - if (virtq->eqp.cq.cq) { + if (virtq->eqp.cq.cq_obj.cq) { if (vq.callfd != virtq->eqp.cq.callfd) return 1; } else if (vq.callfd != -1) { @@ -526,12 +571,11 @@ mlx5_vdpa_virtq_stats_get(struct mlx5_vdpa_priv *priv, int qid, struct mlx5_devx_virtio_q_couners_attr attr = {0}; int ret; - if (!virtq->virtq || !virtq->enable) { + if (!virtq->counters) { DRV_LOG(ERR, "Failed to read virtq %d statistics - virtq " "is invalid.", qid); return -EINVAL; } - MLX5_ASSERT(virtq->counters); ret = mlx5_devx_cmd_query_virtio_q_counters(virtq->counters, &attr); if (ret) { DRV_LOG(ERR, "Failed to read virtq %d stats from HW.", qid); @@ -583,12 +627,11 @@ mlx5_vdpa_virtq_stats_reset(struct mlx5_vdpa_priv *priv, int qid) struct mlx5_vdpa_virtq *virtq = &priv->virtqs[qid]; int ret; - if (!virtq->virtq || !virtq->enable) { + if (!virtq->counters) { DRV_LOG(ERR, "Failed to read virtq %d statistics - virtq " "is invalid.", qid); return -EINVAL; } - MLX5_ASSERT(virtq->counters); ret = mlx5_devx_cmd_query_virtio_q_counters(virtq->counters, &virtq->reset); if (ret)