Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright 2019 Mellanox Technologies, Ltd
3 : : */
4 : : #include <rte_malloc.h>
5 : : #include <rte_errno.h>
6 : :
7 : : #include "mlx5_vdpa_utils.h"
8 : : #include "mlx5_vdpa.h"
9 : :
10 : :
11 : : int
12 : 0 : mlx5_vdpa_logging_enable(struct mlx5_vdpa_priv *priv, int enable)
13 : : {
14 : 0 : struct mlx5_devx_virtq_attr attr = {
15 : : .mod_fields_bitmap =
16 : : MLX5_VIRTQ_MODIFY_TYPE_DIRTY_BITMAP_DUMP_ENABLE,
17 : : .dirty_bitmap_dump_enable = enable,
18 : : };
19 : : struct mlx5_vdpa_virtq *virtq;
20 : : int i;
21 : :
22 [ # # ]: 0 : for (i = 0; i < priv->nr_virtqs; ++i) {
23 : 0 : attr.queue_index = i;
24 : : virtq = &priv->virtqs[i];
25 [ # # ]: 0 : if (!virtq->configured) {
26 : 0 : DRV_LOG(DEBUG, "virtq %d is invalid for dirty bitmap enabling.", i);
27 : : } else {
28 : : struct mlx5_vdpa_virtq *virtq = &priv->virtqs[i];
29 : :
30 : 0 : pthread_mutex_lock(&virtq->virtq_lock);
31 [ # # ]: 0 : if (mlx5_devx_cmd_modify_virtq(priv->virtqs[i].virtq,
32 : : &attr)) {
33 : 0 : pthread_mutex_unlock(&virtq->virtq_lock);
34 : 0 : DRV_LOG(ERR,
35 : : "Failed to modify virtq %d for dirty bitmap enabling.",
36 : : i);
37 : 0 : return -1;
38 : : }
39 : 0 : pthread_mutex_unlock(&virtq->virtq_lock);
40 : : }
41 : : }
42 : : return 0;
43 : : }
44 : :
45 : : int
46 : 0 : mlx5_vdpa_dirty_bitmap_set(struct mlx5_vdpa_priv *priv, uint64_t log_base,
47 : : uint64_t log_size)
48 : : {
49 : 0 : struct mlx5_devx_virtq_attr attr = {
50 : : .mod_fields_bitmap = MLX5_VIRTQ_MODIFY_TYPE_DIRTY_BITMAP_PARAMS,
51 : : .dirty_bitmap_addr = log_base,
52 : : .dirty_bitmap_size = log_size,
53 : : };
54 : : struct mlx5_vdpa_virtq *virtq;
55 : : int i;
56 : 0 : int ret = mlx5_os_wrapped_mkey_create(priv->cdev->ctx, priv->cdev->pd,
57 : 0 : priv->cdev->pdn,
58 : : (void *)(uintptr_t)log_base,
59 : : log_size, &priv->lm_mr);
60 : :
61 [ # # ]: 0 : if (ret) {
62 : 0 : DRV_LOG(ERR, "Failed to allocate wrapped MR for lm.");
63 : 0 : return -1;
64 : : }
65 : 0 : attr.dirty_bitmap_mkey = priv->lm_mr.lkey;
66 [ # # ]: 0 : for (i = 0; i < priv->nr_virtqs; ++i) {
67 : 0 : attr.queue_index = i;
68 : : virtq = &priv->virtqs[i];
69 [ # # ]: 0 : if (!virtq->configured) {
70 : 0 : DRV_LOG(DEBUG, "virtq %d is invalid for LM.", i);
71 : : } else {
72 : : struct mlx5_vdpa_virtq *virtq = &priv->virtqs[i];
73 : :
74 : 0 : pthread_mutex_lock(&virtq->virtq_lock);
75 [ # # ]: 0 : if (mlx5_devx_cmd_modify_virtq(
76 : : priv->virtqs[i].virtq,
77 : : &attr)) {
78 : 0 : pthread_mutex_unlock(&virtq->virtq_lock);
79 : 0 : DRV_LOG(ERR,
80 : : "Failed to modify virtq %d for LM.", i);
81 : 0 : goto err;
82 : : }
83 : 0 : pthread_mutex_unlock(&virtq->virtq_lock);
84 : : }
85 : : }
86 : : return 0;
87 : : err:
88 : 0 : mlx5_os_wrapped_mkey_destroy(&priv->lm_mr);
89 : 0 : return -1;
90 : : }
91 : :
92 : : int
93 : 0 : mlx5_vdpa_lm_log(struct mlx5_vdpa_priv *priv)
94 : : {
95 : 0 : RTE_ATOMIC(uint32_t) remaining_cnt = 0;
96 : 0 : RTE_ATOMIC(uint32_t) err_cnt = 0;
97 : : uint32_t task_num = 0;
98 : : uint32_t i, thrd_idx, data[1];
99 : : struct mlx5_vdpa_virtq *virtq;
100 : : uint64_t features;
101 : : int ret;
102 : :
103 : 0 : ret = rte_vhost_get_negotiated_features(priv->vid, &features);
104 [ # # ]: 0 : if (ret) {
105 : 0 : DRV_LOG(ERR, "Failed to get negotiated features.");
106 : 0 : return -1;
107 : : }
108 [ # # # # ]: 0 : if (priv->use_c_thread && priv->nr_virtqs) {
109 : 0 : uint32_t main_task_idx[priv->nr_virtqs];
110 : :
111 [ # # ]: 0 : for (i = 0; i < priv->nr_virtqs; i++) {
112 : : virtq = &priv->virtqs[i];
113 [ # # ]: 0 : if (!virtq->configured)
114 : 0 : continue;
115 : 0 : thrd_idx = i % (conf_thread_mng.max_thrds + 1);
116 [ # # ]: 0 : if (!thrd_idx) {
117 : 0 : main_task_idx[task_num] = i;
118 : 0 : task_num++;
119 : 0 : continue;
120 : : }
121 : 0 : thrd_idx = priv->last_c_thrd_idx + 1;
122 [ # # ]: 0 : if (thrd_idx >= conf_thread_mng.max_thrds)
123 : : thrd_idx = 0;
124 : 0 : priv->last_c_thrd_idx = thrd_idx;
125 : 0 : data[0] = i;
126 [ # # ]: 0 : if (mlx5_vdpa_task_add(priv, thrd_idx,
127 : : MLX5_VDPA_TASK_STOP_VIRTQ,
128 : : &remaining_cnt, &err_cnt,
129 : : (void **)&data, 1)) {
130 : 0 : DRV_LOG(ERR, "Fail to add "
131 : : "task stop virtq (%d).", i);
132 : 0 : main_task_idx[task_num] = i;
133 : 0 : task_num++;
134 : : }
135 : : }
136 [ # # ]: 0 : for (i = 0; i < task_num; i++) {
137 : 0 : virtq = &priv->virtqs[main_task_idx[i]];
138 : 0 : pthread_mutex_lock(&virtq->virtq_lock);
139 : 0 : ret = mlx5_vdpa_virtq_stop(priv,
140 : : main_task_idx[i]);
141 [ # # ]: 0 : if (ret) {
142 : 0 : pthread_mutex_unlock(&virtq->virtq_lock);
143 : 0 : DRV_LOG(ERR,
144 : : "Failed to stop virtq %d.", i);
145 : 0 : return -1;
146 : : }
147 [ # # ]: 0 : if (RTE_VHOST_NEED_LOG(features))
148 : 0 : rte_vhost_log_used_vring(priv->vid, i, 0,
149 : 0 : MLX5_VDPA_USED_RING_LEN(virtq->vq_size));
150 : 0 : pthread_mutex_unlock(&virtq->virtq_lock);
151 : : }
152 [ # # ]: 0 : if (mlx5_vdpa_c_thread_wait_bulk_tasks_done(&remaining_cnt,
153 : : &err_cnt, 2000)) {
154 : 0 : DRV_LOG(ERR,
155 : : "Failed to wait virt-queue setup tasks ready.");
156 : 0 : return -1;
157 : : }
158 : : } else {
159 [ # # ]: 0 : for (i = 0; i < priv->nr_virtqs; i++) {
160 : : virtq = &priv->virtqs[i];
161 : 0 : pthread_mutex_lock(&virtq->virtq_lock);
162 [ # # ]: 0 : if (!virtq->configured) {
163 : 0 : pthread_mutex_unlock(&virtq->virtq_lock);
164 : 0 : continue;
165 : : }
166 : 0 : ret = mlx5_vdpa_virtq_stop(priv, i);
167 [ # # ]: 0 : if (ret) {
168 : 0 : pthread_mutex_unlock(&virtq->virtq_lock);
169 : 0 : DRV_LOG(ERR,
170 : : "Failed to stop virtq %d for LM log.", i);
171 : 0 : return -1;
172 : : }
173 [ # # ]: 0 : if (RTE_VHOST_NEED_LOG(features))
174 : 0 : rte_vhost_log_used_vring(priv->vid, i, 0,
175 : 0 : MLX5_VDPA_USED_RING_LEN(virtq->vq_size));
176 : 0 : pthread_mutex_unlock(&virtq->virtq_lock);
177 : : }
178 : : }
179 : : return 0;
180 : : }
|