]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/net/ethernet/mellanox/mlx5/core/qp.c
Merge tag 'mlx5-fixes-2017-12-19' of git://git.kernel.org/pub/scm/linux/kernel/git...
[mirror_ubuntu-bionic-kernel.git] / drivers / net / ethernet / mellanox / mlx5 / core / qp.c
CommitLineData
e126ba97 1/*
302bdf68 2 * Copyright (c) 2013-2015, Mellanox Technologies. All rights reserved.
e126ba97
EC
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */
32
e126ba97
EC
33#include <linux/gfp.h>
34#include <linux/export.h>
35#include <linux/mlx5/cmd.h>
36#include <linux/mlx5/qp.h>
37#include <linux/mlx5/driver.h>
e2013b21 38#include <linux/mlx5/transobj.h>
e126ba97
EC
39
40#include "mlx5_core.h"
41
5903325a
EC
42static struct mlx5_core_rsc_common *mlx5_get_rsc(struct mlx5_core_dev *dev,
43 u32 rsn)
e126ba97
EC
44{
45 struct mlx5_qp_table *table = &dev->priv.qp_table;
5903325a 46 struct mlx5_core_rsc_common *common;
e126ba97
EC
47
48 spin_lock(&table->lock);
49
5903325a
EC
50 common = radix_tree_lookup(&table->tree, rsn);
51 if (common)
52 atomic_inc(&common->refcount);
e126ba97
EC
53
54 spin_unlock(&table->lock);
55
5903325a
EC
56 if (!common) {
57 mlx5_core_warn(dev, "Async event for bogus resource 0x%x\n",
58 rsn);
59 return NULL;
e126ba97 60 }
5903325a
EC
61 return common;
62}
e126ba97 63
5903325a
EC
64void mlx5_core_put_rsc(struct mlx5_core_rsc_common *common)
65{
66 if (atomic_dec_and_test(&common->refcount))
67 complete(&common->free);
68}
69
a14c2d4b 70static u64 qp_allowed_event_types(void)
71{
72 u64 mask;
73
74 mask = BIT(MLX5_EVENT_TYPE_PATH_MIG) |
75 BIT(MLX5_EVENT_TYPE_COMM_EST) |
76 BIT(MLX5_EVENT_TYPE_SQ_DRAINED) |
77 BIT(MLX5_EVENT_TYPE_SRQ_LAST_WQE) |
78 BIT(MLX5_EVENT_TYPE_WQ_CATAS_ERROR) |
79 BIT(MLX5_EVENT_TYPE_PATH_MIG_FAILED) |
80 BIT(MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR) |
81 BIT(MLX5_EVENT_TYPE_WQ_ACCESS_ERROR);
82
83 return mask;
84}
85
86static u64 rq_allowed_event_types(void)
87{
88 u64 mask;
89
90 mask = BIT(MLX5_EVENT_TYPE_SRQ_LAST_WQE) |
91 BIT(MLX5_EVENT_TYPE_WQ_CATAS_ERROR);
92
93 return mask;
94}
95
96static u64 sq_allowed_event_types(void)
97{
98 return BIT(MLX5_EVENT_TYPE_WQ_CATAS_ERROR);
99}
100
101static bool is_event_type_allowed(int rsc_type, int event_type)
102{
103 switch (rsc_type) {
104 case MLX5_EVENT_QUEUE_TYPE_QP:
105 return BIT(event_type) & qp_allowed_event_types();
106 case MLX5_EVENT_QUEUE_TYPE_RQ:
107 return BIT(event_type) & rq_allowed_event_types();
108 case MLX5_EVENT_QUEUE_TYPE_SQ:
109 return BIT(event_type) & sq_allowed_event_types();
110 default:
111 WARN(1, "Event arrived for unknown resource type");
112 return false;
113 }
114}
115
5903325a
EC
116void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type)
117{
118 struct mlx5_core_rsc_common *common = mlx5_get_rsc(dev, rsn);
119 struct mlx5_core_qp *qp;
120
121 if (!common)
122 return;
123
a14c2d4b 124 if (!is_event_type_allowed((rsn >> MLX5_USER_INDEX_LEN), event_type)) {
125 mlx5_core_warn(dev, "event 0x%.2x is not allowed on resource 0x%.8x\n",
126 event_type, rsn);
127 return;
128 }
129
5903325a
EC
130 switch (common->res) {
131 case MLX5_RES_QP:
e2013b21 132 case MLX5_RES_RQ:
133 case MLX5_RES_SQ:
5903325a
EC
134 qp = (struct mlx5_core_qp *)common;
135 qp->event(qp, event_type);
136 break;
137
138 default:
139 mlx5_core_warn(dev, "invalid resource type for 0x%x\n", rsn);
140 }
e126ba97 141
5903325a 142 mlx5_core_put_rsc(common);
e126ba97
EC
143}
144
e2013b21 145static int create_qprqsq_common(struct mlx5_core_dev *dev,
146 struct mlx5_core_qp *qp,
147 int rsc_type)
148{
149 struct mlx5_qp_table *table = &dev->priv.qp_table;
150 int err;
151
152 qp->common.res = rsc_type;
153 spin_lock_irq(&table->lock);
154 err = radix_tree_insert(&table->tree,
155 qp->qpn | (rsc_type << MLX5_USER_INDEX_LEN),
156 qp);
157 spin_unlock_irq(&table->lock);
158 if (err)
159 return err;
160
161 atomic_set(&qp->common.refcount, 1);
162 init_completion(&qp->common.free);
163 qp->pid = current->pid;
164
165 return 0;
166}
167
168static void destroy_qprqsq_common(struct mlx5_core_dev *dev,
169 struct mlx5_core_qp *qp)
170{
171 struct mlx5_qp_table *table = &dev->priv.qp_table;
172 unsigned long flags;
173
174 spin_lock_irqsave(&table->lock, flags);
175 radix_tree_delete(&table->tree,
176 qp->qpn | (qp->common.res << MLX5_USER_INDEX_LEN));
177 spin_unlock_irqrestore(&table->lock, flags);
178 mlx5_core_put_rsc((struct mlx5_core_rsc_common *)qp);
179 wait_for_completion(&qp->common.free);
180}
181
e126ba97
EC
182int mlx5_core_create_qp(struct mlx5_core_dev *dev,
183 struct mlx5_core_qp *qp,
09a7d9ec 184 u32 *in, int inlen)
e126ba97 185{
09a7d9ec
SM
186 u32 out[MLX5_ST_SZ_DW(create_qp_out)] = {0};
187 u32 dout[MLX5_ST_SZ_DW(destroy_qp_out)];
188 u32 din[MLX5_ST_SZ_DW(destroy_qp_in)];
e126ba97
EC
189 int err;
190
09a7d9ec 191 MLX5_SET(create_qp_in, in, opcode, MLX5_CMD_OP_CREATE_QP);
e126ba97 192
09a7d9ec 193 err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
09a7d9ec 194 if (err)
e126ba97 195 return err;
e126ba97 196
09a7d9ec 197 qp->qpn = MLX5_GET(create_qp_out, out, qpn);
e126ba97
EC
198 mlx5_core_dbg(dev, "qpn = 0x%x\n", qp->qpn);
199
e2013b21 200 err = create_qprqsq_common(dev, qp, MLX5_RES_QP);
201 if (err)
e126ba97 202 goto err_cmd;
e126ba97
EC
203
204 err = mlx5_debug_qp_add(dev, qp);
205 if (err)
206 mlx5_core_dbg(dev, "failed adding QP 0x%x to debug file system\n",
207 qp->qpn);
208
e126ba97 209 atomic_inc(&dev->num_qps);
e126ba97
EC
210
211 return 0;
212
213err_cmd:
09a7d9ec
SM
214 memset(din, 0, sizeof(din));
215 memset(dout, 0, sizeof(dout));
dbff26e4
MS
216 MLX5_SET(destroy_qp_in, din, opcode, MLX5_CMD_OP_DESTROY_QP);
217 MLX5_SET(destroy_qp_in, din, qpn, qp->qpn);
09a7d9ec 218 mlx5_cmd_exec(dev, din, sizeof(din), dout, sizeof(dout));
e126ba97
EC
219 return err;
220}
221EXPORT_SYMBOL_GPL(mlx5_core_create_qp);
222
223int mlx5_core_destroy_qp(struct mlx5_core_dev *dev,
224 struct mlx5_core_qp *qp)
225{
09a7d9ec
SM
226 u32 out[MLX5_ST_SZ_DW(destroy_qp_out)] = {0};
227 u32 in[MLX5_ST_SZ_DW(destroy_qp_in)] = {0};
e126ba97
EC
228 int err;
229
230 mlx5_debug_qp_remove(dev, qp);
231
e2013b21 232 destroy_qprqsq_common(dev, qp);
e126ba97 233
09a7d9ec
SM
234 MLX5_SET(destroy_qp_in, in, opcode, MLX5_CMD_OP_DESTROY_QP);
235 MLX5_SET(destroy_qp_in, in, qpn, qp->qpn);
236 err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
e126ba97
EC
237 if (err)
238 return err;
239
e126ba97
EC
240 atomic_dec(&dev->num_qps);
241 return 0;
242}
243EXPORT_SYMBOL_GPL(mlx5_core_destroy_qp);
244
c1e0bfc1
MG
245int mlx5_core_set_delay_drop(struct mlx5_core_dev *dev,
246 u32 timeout_usec)
247{
248 u32 out[MLX5_ST_SZ_DW(set_delay_drop_params_out)] = {0};
249 u32 in[MLX5_ST_SZ_DW(set_delay_drop_params_in)] = {0};
250
251 MLX5_SET(set_delay_drop_params_in, in, opcode,
252 MLX5_CMD_OP_SET_DELAY_DROP_PARAMS);
253 MLX5_SET(set_delay_drop_params_in, in, delay_drop_timeout,
254 timeout_usec / 100);
255 return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
256}
257EXPORT_SYMBOL_GPL(mlx5_core_set_delay_drop);
258
1a412fb1
SM
259struct mbox_info {
260 u32 *in;
261 u32 *out;
262 int inlen;
263 int outlen;
264};
265
266static int mbox_alloc(struct mbox_info *mbox, int inlen, int outlen)
267{
268 mbox->inlen = inlen;
269 mbox->outlen = outlen;
270 mbox->in = kzalloc(mbox->inlen, GFP_KERNEL);
271 mbox->out = kzalloc(mbox->outlen, GFP_KERNEL);
272 if (!mbox->in || !mbox->out) {
273 kfree(mbox->in);
274 kfree(mbox->out);
275 return -ENOMEM;
276 }
277
278 return 0;
279}
280
281static void mbox_free(struct mbox_info *mbox)
282{
283 kfree(mbox->in);
284 kfree(mbox->out);
285}
286
287static int modify_qp_mbox_alloc(struct mlx5_core_dev *dev, u16 opcode, int qpn,
288 u32 opt_param_mask, void *qpc,
289 struct mbox_info *mbox)
290{
291 mbox->out = NULL;
292 mbox->in = NULL;
293
294#define MBOX_ALLOC(mbox, typ) \
295 mbox_alloc(mbox, MLX5_ST_SZ_BYTES(typ##_in), MLX5_ST_SZ_BYTES(typ##_out))
296
297#define MOD_QP_IN_SET(typ, in, _opcode, _qpn) \
298 MLX5_SET(typ##_in, in, opcode, _opcode); \
299 MLX5_SET(typ##_in, in, qpn, _qpn)
300
301#define MOD_QP_IN_SET_QPC(typ, in, _opcode, _qpn, _opt_p, _qpc) \
302 MOD_QP_IN_SET(typ, in, _opcode, _qpn); \
303 MLX5_SET(typ##_in, in, opt_param_mask, _opt_p); \
304 memcpy(MLX5_ADDR_OF(typ##_in, in, qpc), _qpc, MLX5_ST_SZ_BYTES(qpc))
305
306 switch (opcode) {
307 /* 2RST & 2ERR */
308 case MLX5_CMD_OP_2RST_QP:
309 if (MBOX_ALLOC(mbox, qp_2rst))
310 return -ENOMEM;
311 MOD_QP_IN_SET(qp_2rst, mbox->in, opcode, qpn);
312 break;
313 case MLX5_CMD_OP_2ERR_QP:
314 if (MBOX_ALLOC(mbox, qp_2err))
315 return -ENOMEM;
316 MOD_QP_IN_SET(qp_2err, mbox->in, opcode, qpn);
317 break;
318
319 /* MODIFY with QPC */
320 case MLX5_CMD_OP_RST2INIT_QP:
321 if (MBOX_ALLOC(mbox, rst2init_qp))
322 return -ENOMEM;
323 MOD_QP_IN_SET_QPC(rst2init_qp, mbox->in, opcode, qpn,
324 opt_param_mask, qpc);
325 break;
326 case MLX5_CMD_OP_INIT2RTR_QP:
327 if (MBOX_ALLOC(mbox, init2rtr_qp))
328 return -ENOMEM;
329 MOD_QP_IN_SET_QPC(init2rtr_qp, mbox->in, opcode, qpn,
330 opt_param_mask, qpc);
331 break;
332 case MLX5_CMD_OP_RTR2RTS_QP:
333 if (MBOX_ALLOC(mbox, rtr2rts_qp))
334 return -ENOMEM;
335 MOD_QP_IN_SET_QPC(rtr2rts_qp, mbox->in, opcode, qpn,
336 opt_param_mask, qpc);
337 break;
338 case MLX5_CMD_OP_RTS2RTS_QP:
339 if (MBOX_ALLOC(mbox, rts2rts_qp))
340 return -ENOMEM;
341 MOD_QP_IN_SET_QPC(rts2rts_qp, mbox->in, opcode, qpn,
342 opt_param_mask, qpc);
343 break;
344 case MLX5_CMD_OP_SQERR2RTS_QP:
345 if (MBOX_ALLOC(mbox, sqerr2rts_qp))
346 return -ENOMEM;
347 MOD_QP_IN_SET_QPC(sqerr2rts_qp, mbox->in, opcode, qpn,
348 opt_param_mask, qpc);
349 break;
350 case MLX5_CMD_OP_INIT2INIT_QP:
351 if (MBOX_ALLOC(mbox, init2init_qp))
352 return -ENOMEM;
353 MOD_QP_IN_SET_QPC(init2init_qp, mbox->in, opcode, qpn,
354 opt_param_mask, qpc);
355 break;
356 default:
357 mlx5_core_err(dev, "Unknown transition for modify QP: OP(0x%x) QPN(0x%x)\n",
358 opcode, qpn);
359 return -EINVAL;
360 }
361 return 0;
362}
363
364int mlx5_core_qp_modify(struct mlx5_core_dev *dev, u16 opcode,
365 u32 opt_param_mask, void *qpc,
e126ba97
EC
366 struct mlx5_core_qp *qp)
367{
1a412fb1
SM
368 struct mbox_info mbox;
369 int err;
e126ba97 370
1a412fb1
SM
371 err = modify_qp_mbox_alloc(dev, opcode, qp->qpn,
372 opt_param_mask, qpc, &mbox);
e126ba97
EC
373 if (err)
374 return err;
375
1a412fb1 376 err = mlx5_cmd_exec(dev, mbox.in, mbox.inlen, mbox.out, mbox.outlen);
1a412fb1
SM
377 mbox_free(&mbox);
378 return err;
e126ba97
EC
379}
380EXPORT_SYMBOL_GPL(mlx5_core_qp_modify);
381
382void mlx5_init_qp_table(struct mlx5_core_dev *dev)
383{
384 struct mlx5_qp_table *table = &dev->priv.qp_table;
385
a31208b1 386 memset(table, 0, sizeof(*table));
e126ba97
EC
387 spin_lock_init(&table->lock);
388 INIT_RADIX_TREE(&table->tree, GFP_ATOMIC);
389 mlx5_qp_debugfs_init(dev);
390}
391
392void mlx5_cleanup_qp_table(struct mlx5_core_dev *dev)
393{
394 mlx5_qp_debugfs_cleanup(dev);
395}
396
397int mlx5_core_qp_query(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp,
09a7d9ec 398 u32 *out, int outlen)
e126ba97 399{
09a7d9ec 400 u32 in[MLX5_ST_SZ_DW(query_qp_in)] = {0};
e126ba97 401
09a7d9ec
SM
402 MLX5_SET(query_qp_in, in, opcode, MLX5_CMD_OP_QUERY_QP);
403 MLX5_SET(query_qp_in, in, qpn, qp->qpn);
c4f287c4 404 return mlx5_cmd_exec(dev, in, sizeof(in), out, outlen);
e126ba97
EC
405}
406EXPORT_SYMBOL_GPL(mlx5_core_qp_query);
407
408int mlx5_core_xrcd_alloc(struct mlx5_core_dev *dev, u32 *xrcdn)
409{
09a7d9ec
SM
410 u32 out[MLX5_ST_SZ_DW(alloc_xrcd_out)] = {0};
411 u32 in[MLX5_ST_SZ_DW(alloc_xrcd_in)] = {0};
e126ba97
EC
412 int err;
413
09a7d9ec
SM
414 MLX5_SET(alloc_xrcd_in, in, opcode, MLX5_CMD_OP_ALLOC_XRCD);
415 err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
09a7d9ec
SM
416 if (!err)
417 *xrcdn = MLX5_GET(alloc_xrcd_out, out, xrcd);
e126ba97
EC
418 return err;
419}
420EXPORT_SYMBOL_GPL(mlx5_core_xrcd_alloc);
421
422int mlx5_core_xrcd_dealloc(struct mlx5_core_dev *dev, u32 xrcdn)
423{
09a7d9ec
SM
424 u32 out[MLX5_ST_SZ_DW(dealloc_xrcd_out)] = {0};
425 u32 in[MLX5_ST_SZ_DW(dealloc_xrcd_in)] = {0};
e126ba97 426
09a7d9ec
SM
427 MLX5_SET(dealloc_xrcd_in, in, opcode, MLX5_CMD_OP_DEALLOC_XRCD);
428 MLX5_SET(dealloc_xrcd_in, in, xrcd, xrcdn);
c4f287c4 429 return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
e126ba97
EC
430}
431EXPORT_SYMBOL_GPL(mlx5_core_xrcd_dealloc);
e420f0c0 432
e2013b21 433int mlx5_core_create_rq_tracked(struct mlx5_core_dev *dev, u32 *in, int inlen,
434 struct mlx5_core_qp *rq)
435{
436 int err;
437 u32 rqn;
438
439 err = mlx5_core_create_rq(dev, in, inlen, &rqn);
440 if (err)
441 return err;
442
443 rq->qpn = rqn;
444 err = create_qprqsq_common(dev, rq, MLX5_RES_RQ);
445 if (err)
446 goto err_destroy_rq;
447
448 return 0;
449
450err_destroy_rq:
451 mlx5_core_destroy_rq(dev, rq->qpn);
452
453 return err;
454}
455EXPORT_SYMBOL(mlx5_core_create_rq_tracked);
456
457void mlx5_core_destroy_rq_tracked(struct mlx5_core_dev *dev,
458 struct mlx5_core_qp *rq)
459{
460 destroy_qprqsq_common(dev, rq);
461 mlx5_core_destroy_rq(dev, rq->qpn);
462}
463EXPORT_SYMBOL(mlx5_core_destroy_rq_tracked);
464
465int mlx5_core_create_sq_tracked(struct mlx5_core_dev *dev, u32 *in, int inlen,
466 struct mlx5_core_qp *sq)
467{
468 int err;
469 u32 sqn;
470
471 err = mlx5_core_create_sq(dev, in, inlen, &sqn);
472 if (err)
473 return err;
474
475 sq->qpn = sqn;
476 err = create_qprqsq_common(dev, sq, MLX5_RES_SQ);
477 if (err)
478 goto err_destroy_sq;
479
480 return 0;
481
482err_destroy_sq:
483 mlx5_core_destroy_sq(dev, sq->qpn);
484
485 return err;
486}
487EXPORT_SYMBOL(mlx5_core_create_sq_tracked);
488
489void mlx5_core_destroy_sq_tracked(struct mlx5_core_dev *dev,
490 struct mlx5_core_qp *sq)
491{
492 destroy_qprqsq_common(dev, sq);
493 mlx5_core_destroy_sq(dev, sq->qpn);
494}
495EXPORT_SYMBOL(mlx5_core_destroy_sq_tracked);
237cd218
TT
496
497int mlx5_core_alloc_q_counter(struct mlx5_core_dev *dev, u16 *counter_id)
498{
09a7d9ec
SM
499 u32 in[MLX5_ST_SZ_DW(alloc_q_counter_in)] = {0};
500 u32 out[MLX5_ST_SZ_DW(alloc_q_counter_out)] = {0};
237cd218
TT
501 int err;
502
237cd218 503 MLX5_SET(alloc_q_counter_in, in, opcode, MLX5_CMD_OP_ALLOC_Q_COUNTER);
c4f287c4 504 err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
237cd218
TT
505 if (!err)
506 *counter_id = MLX5_GET(alloc_q_counter_out, out,
507 counter_set_id);
508 return err;
509}
510EXPORT_SYMBOL_GPL(mlx5_core_alloc_q_counter);
511
512int mlx5_core_dealloc_q_counter(struct mlx5_core_dev *dev, u16 counter_id)
513{
09a7d9ec
SM
514 u32 in[MLX5_ST_SZ_DW(dealloc_q_counter_in)] = {0};
515 u32 out[MLX5_ST_SZ_DW(dealloc_q_counter_out)] = {0};
237cd218
TT
516
517 MLX5_SET(dealloc_q_counter_in, in, opcode,
518 MLX5_CMD_OP_DEALLOC_Q_COUNTER);
519 MLX5_SET(dealloc_q_counter_in, in, counter_set_id, counter_id);
c4f287c4 520 return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
237cd218
TT
521}
522EXPORT_SYMBOL_GPL(mlx5_core_dealloc_q_counter);
523
524int mlx5_core_query_q_counter(struct mlx5_core_dev *dev, u16 counter_id,
525 int reset, void *out, int out_size)
526{
09a7d9ec 527 u32 in[MLX5_ST_SZ_DW(query_q_counter_in)] = {0};
237cd218
TT
528
529 MLX5_SET(query_q_counter_in, in, opcode, MLX5_CMD_OP_QUERY_Q_COUNTER);
530 MLX5_SET(query_q_counter_in, in, clear, reset);
531 MLX5_SET(query_q_counter_in, in, counter_set_id, counter_id);
c4f287c4 532 return mlx5_cmd_exec(dev, in, sizeof(in), out, out_size);
237cd218
TT
533}
534EXPORT_SYMBOL_GPL(mlx5_core_query_q_counter);