xref: /dpdk/drivers/vdpa/mlx5/mlx5_vdpa_lm.c (revision e12a0166c80f65e35408f4715b2f3a60763c3741)
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