19d39e57fSMatan Azrad /* SPDX-License-Identifier: BSD-3-Clause
29d39e57fSMatan Azrad * Copyright 2019 Mellanox Technologies, Ltd
39d39e57fSMatan Azrad */
49d39e57fSMatan Azrad #include <rte_malloc.h>
59d39e57fSMatan Azrad #include <rte_errno.h>
69d39e57fSMatan Azrad
79d39e57fSMatan Azrad #include "mlx5_vdpa_utils.h"
89d39e57fSMatan Azrad #include "mlx5_vdpa.h"
99d39e57fSMatan Azrad
109d39e57fSMatan Azrad
119d39e57fSMatan Azrad int
mlx5_vdpa_logging_enable(struct mlx5_vdpa_priv * priv,int enable)129d39e57fSMatan Azrad mlx5_vdpa_logging_enable(struct mlx5_vdpa_priv *priv, int enable)
139d39e57fSMatan Azrad {
149d39e57fSMatan Azrad struct mlx5_devx_virtq_attr attr = {
157f2de212SLi Zhang .mod_fields_bitmap =
167f2de212SLi Zhang MLX5_VIRTQ_MODIFY_TYPE_DIRTY_BITMAP_DUMP_ENABLE,
179d39e57fSMatan Azrad .dirty_bitmap_dump_enable = enable,
189d39e57fSMatan Azrad };
197f2de212SLi Zhang struct mlx5_vdpa_virtq *virtq;
20c2eb33aaSMatan Azrad int i;
219d39e57fSMatan Azrad
22c2eb33aaSMatan Azrad for (i = 0; i < priv->nr_virtqs; ++i) {
23c2eb33aaSMatan Azrad attr.queue_index = i;
247f2de212SLi Zhang virtq = &priv->virtqs[i];
257f2de212SLi Zhang if (!virtq->configured) {
267f2de212SLi Zhang DRV_LOG(DEBUG, "virtq %d is invalid for dirty bitmap enabling.", i);
27057f7d20SLi Zhang } else {
28057f7d20SLi Zhang struct mlx5_vdpa_virtq *virtq = &priv->virtqs[i];
29057f7d20SLi Zhang
30057f7d20SLi Zhang pthread_mutex_lock(&virtq->virtq_lock);
31057f7d20SLi Zhang if (mlx5_devx_cmd_modify_virtq(priv->virtqs[i].virtq,
32581e312dSMatan Azrad &attr)) {
33057f7d20SLi Zhang pthread_mutex_unlock(&virtq->virtq_lock);
34057f7d20SLi Zhang DRV_LOG(ERR,
35057f7d20SLi Zhang "Failed to modify virtq %d for dirty bitmap enabling.",
36057f7d20SLi Zhang i);
379d39e57fSMatan Azrad return -1;
389d39e57fSMatan Azrad }
39057f7d20SLi Zhang pthread_mutex_unlock(&virtq->virtq_lock);
40057f7d20SLi Zhang }
419d39e57fSMatan Azrad }
429d39e57fSMatan Azrad return 0;
439d39e57fSMatan Azrad }
449d39e57fSMatan Azrad
459d39e57fSMatan Azrad int
mlx5_vdpa_dirty_bitmap_set(struct mlx5_vdpa_priv * priv,uint64_t log_base,uint64_t log_size)469d39e57fSMatan Azrad mlx5_vdpa_dirty_bitmap_set(struct mlx5_vdpa_priv *priv, uint64_t log_base,
479d39e57fSMatan Azrad uint64_t log_size)
489d39e57fSMatan Azrad {
499d39e57fSMatan Azrad struct mlx5_devx_virtq_attr attr = {
507f2de212SLi Zhang .mod_fields_bitmap = MLX5_VIRTQ_MODIFY_TYPE_DIRTY_BITMAP_PARAMS,
519d39e57fSMatan Azrad .dirty_bitmap_addr = log_base,
529d39e57fSMatan Azrad .dirty_bitmap_size = log_size,
539d39e57fSMatan Azrad };
547f2de212SLi Zhang struct mlx5_vdpa_virtq *virtq;
55c2eb33aaSMatan Azrad int i;
56398ea845SMatan Azrad int ret = mlx5_os_wrapped_mkey_create(priv->cdev->ctx, priv->cdev->pd,
57398ea845SMatan Azrad priv->cdev->pdn,
58398ea845SMatan Azrad (void *)(uintptr_t)log_base,
59398ea845SMatan Azrad log_size, &priv->lm_mr);
609d39e57fSMatan Azrad
61e9511a26SBing Zhao if (ret) {
62398ea845SMatan Azrad DRV_LOG(ERR, "Failed to allocate wrapped MR for lm.");
639d39e57fSMatan Azrad return -1;
649d39e57fSMatan Azrad }
65398ea845SMatan Azrad attr.dirty_bitmap_mkey = priv->lm_mr.lkey;
66c2eb33aaSMatan Azrad for (i = 0; i < priv->nr_virtqs; ++i) {
67c2eb33aaSMatan Azrad attr.queue_index = i;
687f2de212SLi Zhang virtq = &priv->virtqs[i];
697f2de212SLi Zhang if (!virtq->configured) {
70581e312dSMatan Azrad DRV_LOG(DEBUG, "virtq %d is invalid for LM.", i);
71057f7d20SLi Zhang } else {
72057f7d20SLi Zhang struct mlx5_vdpa_virtq *virtq = &priv->virtqs[i];
73057f7d20SLi Zhang
74057f7d20SLi Zhang pthread_mutex_lock(&virtq->virtq_lock);
75057f7d20SLi Zhang if (mlx5_devx_cmd_modify_virtq(
76057f7d20SLi Zhang priv->virtqs[i].virtq,
77581e312dSMatan Azrad &attr)) {
78057f7d20SLi Zhang pthread_mutex_unlock(&virtq->virtq_lock);
79057f7d20SLi Zhang DRV_LOG(ERR,
80057f7d20SLi Zhang "Failed to modify virtq %d for LM.", i);
819d39e57fSMatan Azrad goto err;
829d39e57fSMatan Azrad }
83057f7d20SLi Zhang pthread_mutex_unlock(&virtq->virtq_lock);
84057f7d20SLi Zhang }
859d39e57fSMatan Azrad }
869d39e57fSMatan Azrad return 0;
879d39e57fSMatan Azrad err:
88398ea845SMatan Azrad mlx5_os_wrapped_mkey_destroy(&priv->lm_mr);
899d39e57fSMatan Azrad return -1;
909d39e57fSMatan Azrad }
919d39e57fSMatan Azrad
929d39e57fSMatan Azrad int
mlx5_vdpa_lm_log(struct mlx5_vdpa_priv * priv)939d39e57fSMatan Azrad mlx5_vdpa_lm_log(struct mlx5_vdpa_priv *priv)
949d39e57fSMatan Azrad {
95*e12a0166STyler Retzlaff RTE_ATOMIC(uint32_t) remaining_cnt = 0;
96*e12a0166STyler Retzlaff RTE_ATOMIC(uint32_t) err_cnt = 0;
97*e12a0166STyler Retzlaff uint32_t task_num = 0;
980d9d2897SLi Zhang uint32_t i, thrd_idx, data[1];
99057f7d20SLi Zhang struct mlx5_vdpa_virtq *virtq;
1009d39e57fSMatan Azrad uint64_t features;
1010d9d2897SLi Zhang int ret;
1029d39e57fSMatan Azrad
1030d9d2897SLi Zhang ret = rte_vhost_get_negotiated_features(priv->vid, &features);
1049d39e57fSMatan Azrad if (ret) {
1059d39e57fSMatan Azrad DRV_LOG(ERR, "Failed to get negotiated features.");
1069d39e57fSMatan Azrad return -1;
1079d39e57fSMatan Azrad }
1080d9d2897SLi Zhang if (priv->use_c_thread && priv->nr_virtqs) {
1090d9d2897SLi Zhang uint32_t main_task_idx[priv->nr_virtqs];
1100d9d2897SLi Zhang
1110d9d2897SLi Zhang for (i = 0; i < priv->nr_virtqs; i++) {
112057f7d20SLi Zhang virtq = &priv->virtqs[i];
1130d9d2897SLi Zhang if (!virtq->configured)
1140d9d2897SLi Zhang continue;
1150d9d2897SLi Zhang thrd_idx = i % (conf_thread_mng.max_thrds + 1);
1160d9d2897SLi Zhang if (!thrd_idx) {
1170d9d2897SLi Zhang main_task_idx[task_num] = i;
1180d9d2897SLi Zhang task_num++;
1190d9d2897SLi Zhang continue;
1200d9d2897SLi Zhang }
1210d9d2897SLi Zhang thrd_idx = priv->last_c_thrd_idx + 1;
1220d9d2897SLi Zhang if (thrd_idx >= conf_thread_mng.max_thrds)
1230d9d2897SLi Zhang thrd_idx = 0;
1240d9d2897SLi Zhang priv->last_c_thrd_idx = thrd_idx;
1250d9d2897SLi Zhang data[0] = i;
1260d9d2897SLi Zhang if (mlx5_vdpa_task_add(priv, thrd_idx,
1270d9d2897SLi Zhang MLX5_VDPA_TASK_STOP_VIRTQ,
1280d9d2897SLi Zhang &remaining_cnt, &err_cnt,
1290d9d2897SLi Zhang (void **)&data, 1)) {
1300d9d2897SLi Zhang DRV_LOG(ERR, "Fail to add "
1310d9d2897SLi Zhang "task stop virtq (%d).", i);
1320d9d2897SLi Zhang main_task_idx[task_num] = i;
1330d9d2897SLi Zhang task_num++;
1340d9d2897SLi Zhang }
1350d9d2897SLi Zhang }
1360d9d2897SLi Zhang for (i = 0; i < task_num; i++) {
1370d9d2897SLi Zhang virtq = &priv->virtqs[main_task_idx[i]];
138057f7d20SLi Zhang pthread_mutex_lock(&virtq->virtq_lock);
1390d9d2897SLi Zhang ret = mlx5_vdpa_virtq_stop(priv,
1400d9d2897SLi Zhang main_task_idx[i]);
1419d39e57fSMatan Azrad if (ret) {
1420d9d2897SLi Zhang pthread_mutex_unlock(&virtq->virtq_lock);
1430d9d2897SLi Zhang DRV_LOG(ERR,
1440d9d2897SLi Zhang "Failed to stop virtq %d.", i);
1459d39e57fSMatan Azrad return -1;
1469d39e57fSMatan Azrad }
1470d9d2897SLi Zhang if (RTE_VHOST_NEED_LOG(features))
148c2eb33aaSMatan Azrad rte_vhost_log_used_vring(priv->vid, i, 0,
1490d9d2897SLi Zhang MLX5_VDPA_USED_RING_LEN(virtq->vq_size));
1500d9d2897SLi Zhang pthread_mutex_unlock(&virtq->virtq_lock);
1510d9d2897SLi Zhang }
1520d9d2897SLi Zhang if (mlx5_vdpa_c_thread_wait_bulk_tasks_done(&remaining_cnt,
1530d9d2897SLi Zhang &err_cnt, 2000)) {
1540d9d2897SLi Zhang DRV_LOG(ERR,
1550d9d2897SLi Zhang "Failed to wait virt-queue setup tasks ready.");
1560d9d2897SLi Zhang return -1;
1570d9d2897SLi Zhang }
1580d9d2897SLi Zhang } else {
1590d9d2897SLi Zhang for (i = 0; i < priv->nr_virtqs; i++) {
1600d9d2897SLi Zhang virtq = &priv->virtqs[i];
1610d9d2897SLi Zhang pthread_mutex_lock(&virtq->virtq_lock);
1620d9d2897SLi Zhang if (!virtq->configured) {
1630d9d2897SLi Zhang pthread_mutex_unlock(&virtq->virtq_lock);
1640d9d2897SLi Zhang continue;
1650d9d2897SLi Zhang }
1660d9d2897SLi Zhang ret = mlx5_vdpa_virtq_stop(priv, i);
1670d9d2897SLi Zhang if (ret) {
1680d9d2897SLi Zhang pthread_mutex_unlock(&virtq->virtq_lock);
1690d9d2897SLi Zhang DRV_LOG(ERR,
1700d9d2897SLi Zhang "Failed to stop virtq %d for LM log.", i);
1710d9d2897SLi Zhang return -1;
1720d9d2897SLi Zhang }
1730d9d2897SLi Zhang if (RTE_VHOST_NEED_LOG(features))
1740d9d2897SLi Zhang rte_vhost_log_used_vring(priv->vid, i, 0,
1750d9d2897SLi Zhang MLX5_VDPA_USED_RING_LEN(virtq->vq_size));
1760d9d2897SLi Zhang pthread_mutex_unlock(&virtq->virtq_lock);
1770d9d2897SLi Zhang }
1789d39e57fSMatan Azrad }
1799d39e57fSMatan Azrad return 0;
1809d39e57fSMatan Azrad }
181