forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/net/ethernet/mellanox/mlx5/core/rl.c
....@@ -33,15 +33,14 @@
3333 #include <linux/kernel.h>
3434 #include <linux/module.h>
3535 #include <linux/mlx5/driver.h>
36
-#include <linux/mlx5/cmd.h>
3736 #include "mlx5_core.h"
3837
3938 /* Scheduling element fw management */
4039 int mlx5_create_scheduling_element_cmd(struct mlx5_core_dev *dev, u8 hierarchy,
4140 void *ctx, u32 *element_id)
4241 {
43
- u32 in[MLX5_ST_SZ_DW(create_scheduling_element_in)] = {0};
44
- u32 out[MLX5_ST_SZ_DW(create_scheduling_element_in)] = {0};
42
+ u32 out[MLX5_ST_SZ_DW(create_scheduling_element_in)] = {};
43
+ u32 in[MLX5_ST_SZ_DW(create_scheduling_element_in)] = {};
4544 void *schedc;
4645 int err;
4746
....@@ -53,7 +52,7 @@
5352 hierarchy);
5453 memcpy(schedc, ctx, MLX5_ST_SZ_BYTES(scheduling_context));
5554
56
- err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
55
+ err = mlx5_cmd_exec_inout(dev, create_scheduling_element, in, out);
5756 if (err)
5857 return err;
5958
....@@ -66,8 +65,7 @@
6665 void *ctx, u32 element_id,
6766 u32 modify_bitmask)
6867 {
69
- u32 in[MLX5_ST_SZ_DW(modify_scheduling_element_in)] = {0};
70
- u32 out[MLX5_ST_SZ_DW(modify_scheduling_element_in)] = {0};
68
+ u32 in[MLX5_ST_SZ_DW(modify_scheduling_element_in)] = {};
7169 void *schedc;
7270
7371 schedc = MLX5_ADDR_OF(modify_scheduling_element_in, in,
....@@ -82,14 +80,13 @@
8280 hierarchy);
8381 memcpy(schedc, ctx, MLX5_ST_SZ_BYTES(scheduling_context));
8482
85
- return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
83
+ return mlx5_cmd_exec_in(dev, modify_scheduling_element, in);
8684 }
8785
8886 int mlx5_destroy_scheduling_element_cmd(struct mlx5_core_dev *dev, u8 hierarchy,
8987 u32 element_id)
9088 {
91
- u32 in[MLX5_ST_SZ_DW(destroy_scheduling_element_in)] = {0};
92
- u32 out[MLX5_ST_SZ_DW(destroy_scheduling_element_in)] = {0};
89
+ u32 in[MLX5_ST_SZ_DW(destroy_scheduling_element_in)] = {};
9390
9491 MLX5_SET(destroy_scheduling_element_in, in, opcode,
9592 MLX5_CMD_OP_DESTROY_SCHEDULING_ELEMENT);
....@@ -98,7 +95,14 @@
9895 MLX5_SET(destroy_scheduling_element_in, in, scheduling_hierarchy,
9996 hierarchy);
10097
101
- return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
98
+ return mlx5_cmd_exec_in(dev, destroy_scheduling_element, in);
99
+}
100
+
101
+static bool mlx5_rl_are_equal_raw(struct mlx5_rl_entry *entry, void *rl_in,
102
+ u16 uid)
103
+{
104
+ return (!memcmp(entry->rl_raw, rl_in, sizeof(entry->rl_raw)) &&
105
+ entry->uid == uid);
102106 }
103107
104108 /* Finds an entry where we can register the given rate
....@@ -107,16 +111,26 @@
107111 * If the table is full, return NULL
108112 */
109113 static struct mlx5_rl_entry *find_rl_entry(struct mlx5_rl_table *table,
110
- struct mlx5_rate_limit *rl)
114
+ void *rl_in, u16 uid, bool dedicated)
111115 {
112116 struct mlx5_rl_entry *ret_entry = NULL;
113117 bool empty_found = false;
114118 int i;
115119
116120 for (i = 0; i < table->max_size; i++) {
117
- if (mlx5_rl_are_equal(&table->rl_entry[i].rl, rl))
118
- return &table->rl_entry[i];
119
- if (!empty_found && !table->rl_entry[i].rl.rate) {
121
+ if (dedicated) {
122
+ if (!table->rl_entry[i].refcount)
123
+ return &table->rl_entry[i];
124
+ continue;
125
+ }
126
+
127
+ if (table->rl_entry[i].refcount) {
128
+ if (table->rl_entry[i].dedicated)
129
+ continue;
130
+ if (mlx5_rl_are_equal_raw(&table->rl_entry[i], rl_in,
131
+ uid))
132
+ return &table->rl_entry[i];
133
+ } else if (!empty_found) {
120134 empty_found = true;
121135 ret_entry = &table->rl_entry[i];
122136 }
....@@ -126,19 +140,19 @@
126140 }
127141
128142 static int mlx5_set_pp_rate_limit_cmd(struct mlx5_core_dev *dev,
129
- u16 index,
130
- struct mlx5_rate_limit *rl)
143
+ struct mlx5_rl_entry *entry, bool set)
131144 {
132
- u32 in[MLX5_ST_SZ_DW(set_pp_rate_limit_in)] = {0};
133
- u32 out[MLX5_ST_SZ_DW(set_pp_rate_limit_out)] = {0};
145
+ u32 in[MLX5_ST_SZ_DW(set_pp_rate_limit_in)] = {};
146
+ void *pp_context;
134147
148
+ pp_context = MLX5_ADDR_OF(set_pp_rate_limit_in, in, ctx);
135149 MLX5_SET(set_pp_rate_limit_in, in, opcode,
136150 MLX5_CMD_OP_SET_PP_RATE_LIMIT);
137
- MLX5_SET(set_pp_rate_limit_in, in, rate_limit_index, index);
138
- MLX5_SET(set_pp_rate_limit_in, in, rate_limit, rl->rate);
139
- MLX5_SET(set_pp_rate_limit_in, in, burst_upper_bound, rl->max_burst_sz);
140
- MLX5_SET(set_pp_rate_limit_in, in, typical_packet_size, rl->typical_pkt_sz);
141
- return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
151
+ MLX5_SET(set_pp_rate_limit_in, in, uid, entry->uid);
152
+ MLX5_SET(set_pp_rate_limit_in, in, rate_limit_index, entry->index);
153
+ if (set)
154
+ memcpy(pp_context, entry->rl_raw, sizeof(entry->rl_raw));
155
+ return mlx5_cmd_exec_in(dev, set_pp_rate_limit, in);
142156 }
143157
144158 bool mlx5_rl_is_in_range(struct mlx5_core_dev *dev, u32 rate)
....@@ -158,23 +172,25 @@
158172 }
159173 EXPORT_SYMBOL(mlx5_rl_are_equal);
160174
161
-int mlx5_rl_add_rate(struct mlx5_core_dev *dev, u16 *index,
162
- struct mlx5_rate_limit *rl)
175
+int mlx5_rl_add_rate_raw(struct mlx5_core_dev *dev, void *rl_in, u16 uid,
176
+ bool dedicated_entry, u16 *index)
163177 {
164178 struct mlx5_rl_table *table = &dev->priv.rl_table;
165179 struct mlx5_rl_entry *entry;
166180 int err = 0;
181
+ u32 rate;
167182
183
+ rate = MLX5_GET(set_pp_rate_limit_context, rl_in, rate_limit);
168184 mutex_lock(&table->rl_lock);
169185
170
- if (!rl->rate || !mlx5_rl_is_in_range(dev, rl->rate)) {
186
+ if (!rate || !mlx5_rl_is_in_range(dev, rate)) {
171187 mlx5_core_err(dev, "Invalid rate: %u, should be %u to %u\n",
172
- rl->rate, table->min_rate, table->max_rate);
188
+ rate, table->min_rate, table->max_rate);
173189 err = -EINVAL;
174190 goto out;
175191 }
176192
177
- entry = find_rl_entry(table, rl);
193
+ entry = find_rl_entry(table, rl_in, uid, dedicated_entry);
178194 if (!entry) {
179195 mlx5_core_err(dev, "Max number of %u rates reached\n",
180196 table->max_size);
....@@ -185,17 +201,24 @@
185201 /* rate already configured */
186202 entry->refcount++;
187203 } else {
204
+ memcpy(entry->rl_raw, rl_in, sizeof(entry->rl_raw));
205
+ entry->uid = uid;
188206 /* new rate limit */
189
- err = mlx5_set_pp_rate_limit_cmd(dev, entry->index, rl);
207
+ err = mlx5_set_pp_rate_limit_cmd(dev, entry, true);
190208 if (err) {
191
- mlx5_core_err(dev, "Failed configuring rate limit(err %d): \
192
- rate %u, max_burst_sz %u, typical_pkt_sz %u\n",
193
- err, rl->rate, rl->max_burst_sz,
194
- rl->typical_pkt_sz);
209
+ mlx5_core_err(
210
+ dev,
211
+ "Failed configuring rate limit(err %d): rate %u, max_burst_sz %u, typical_pkt_sz %u\n",
212
+ err, rate,
213
+ MLX5_GET(set_pp_rate_limit_context, rl_in,
214
+ burst_upper_bound),
215
+ MLX5_GET(set_pp_rate_limit_context, rl_in,
216
+ typical_packet_size));
195217 goto out;
196218 }
197
- entry->rl = *rl;
219
+
198220 entry->refcount = 1;
221
+ entry->dedicated = dedicated_entry;
199222 }
200223 *index = entry->index;
201224
....@@ -203,33 +226,71 @@
203226 mutex_unlock(&table->rl_lock);
204227 return err;
205228 }
229
+EXPORT_SYMBOL(mlx5_rl_add_rate_raw);
230
+
231
+void mlx5_rl_remove_rate_raw(struct mlx5_core_dev *dev, u16 index)
232
+{
233
+ struct mlx5_rl_table *table = &dev->priv.rl_table;
234
+ struct mlx5_rl_entry *entry;
235
+
236
+ mutex_lock(&table->rl_lock);
237
+ entry = &table->rl_entry[index - 1];
238
+ entry->refcount--;
239
+ if (!entry->refcount)
240
+ /* need to remove rate */
241
+ mlx5_set_pp_rate_limit_cmd(dev, entry, false);
242
+ mutex_unlock(&table->rl_lock);
243
+}
244
+EXPORT_SYMBOL(mlx5_rl_remove_rate_raw);
245
+
246
+int mlx5_rl_add_rate(struct mlx5_core_dev *dev, u16 *index,
247
+ struct mlx5_rate_limit *rl)
248
+{
249
+ u8 rl_raw[MLX5_ST_SZ_BYTES(set_pp_rate_limit_context)] = {};
250
+
251
+ MLX5_SET(set_pp_rate_limit_context, rl_raw, rate_limit, rl->rate);
252
+ MLX5_SET(set_pp_rate_limit_context, rl_raw, burst_upper_bound,
253
+ rl->max_burst_sz);
254
+ MLX5_SET(set_pp_rate_limit_context, rl_raw, typical_packet_size,
255
+ rl->typical_pkt_sz);
256
+
257
+ return mlx5_rl_add_rate_raw(dev, rl_raw,
258
+ MLX5_CAP_QOS(dev, packet_pacing_uid) ?
259
+ MLX5_SHARED_RESOURCE_UID : 0,
260
+ false, index);
261
+}
206262 EXPORT_SYMBOL(mlx5_rl_add_rate);
207263
208264 void mlx5_rl_remove_rate(struct mlx5_core_dev *dev, struct mlx5_rate_limit *rl)
209265 {
266
+ u8 rl_raw[MLX5_ST_SZ_BYTES(set_pp_rate_limit_context)] = {};
210267 struct mlx5_rl_table *table = &dev->priv.rl_table;
211268 struct mlx5_rl_entry *entry = NULL;
212
- struct mlx5_rate_limit reset_rl = {0};
213269
214270 /* 0 is a reserved value for unlimited rate */
215271 if (rl->rate == 0)
216272 return;
217273
274
+ MLX5_SET(set_pp_rate_limit_context, rl_raw, rate_limit, rl->rate);
275
+ MLX5_SET(set_pp_rate_limit_context, rl_raw, burst_upper_bound,
276
+ rl->max_burst_sz);
277
+ MLX5_SET(set_pp_rate_limit_context, rl_raw, typical_packet_size,
278
+ rl->typical_pkt_sz);
279
+
218280 mutex_lock(&table->rl_lock);
219
- entry = find_rl_entry(table, rl);
281
+ entry = find_rl_entry(table, rl_raw,
282
+ MLX5_CAP_QOS(dev, packet_pacing_uid) ?
283
+ MLX5_SHARED_RESOURCE_UID : 0, false);
220284 if (!entry || !entry->refcount) {
221
- mlx5_core_warn(dev, "Rate %u, max_burst_sz %u typical_pkt_sz %u \
222
- are not configured\n",
285
+ mlx5_core_warn(dev, "Rate %u, max_burst_sz %u typical_pkt_sz %u are not configured\n",
223286 rl->rate, rl->max_burst_sz, rl->typical_pkt_sz);
224287 goto out;
225288 }
226289
227290 entry->refcount--;
228
- if (!entry->refcount) {
291
+ if (!entry->refcount)
229292 /* need to remove rate */
230
- mlx5_set_pp_rate_limit_cmd(dev, entry->index, &reset_rl);
231
- entry->rl = reset_rl;
232
- }
293
+ mlx5_set_pp_rate_limit_cmd(dev, entry, false);
233294
234295 out:
235296 mutex_unlock(&table->rl_lock);
....@@ -275,14 +336,13 @@
275336 void mlx5_cleanup_rl_table(struct mlx5_core_dev *dev)
276337 {
277338 struct mlx5_rl_table *table = &dev->priv.rl_table;
278
- struct mlx5_rate_limit rl = {0};
279339 int i;
280340
281341 /* Clear all configured rates */
282342 for (i = 0; i < table->max_size; i++)
283
- if (table->rl_entry[i].rl.rate)
284
- mlx5_set_pp_rate_limit_cmd(dev, table->rl_entry[i].index,
285
- &rl);
343
+ if (table->rl_entry[i].refcount)
344
+ mlx5_set_pp_rate_limit_cmd(dev, &table->rl_entry[i],
345
+ false);
286346
287347 kfree(dev->priv.rl_table.rl_entry);
288348 }