|
@@ -36,6 +36,7 @@
|
|
|
#include <linux/mlx5/cmd.h>
|
|
|
#include <linux/mlx5/qp.h>
|
|
|
#include <linux/mlx5/driver.h>
|
|
|
+#include <linux/mlx5/transobj.h>
|
|
|
|
|
|
#include "mlx5_core.h"
|
|
|
|
|
@@ -77,6 +78,8 @@ void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type)
|
|
|
|
|
|
switch (common->res) {
|
|
|
case MLX5_RES_QP:
|
|
|
+ case MLX5_RES_RQ:
|
|
|
+ case MLX5_RES_SQ:
|
|
|
qp = (struct mlx5_core_qp *)common;
|
|
|
qp->event(qp, event_type);
|
|
|
break;
|
|
@@ -177,12 +180,48 @@ void mlx5_eq_pagefault(struct mlx5_core_dev *dev, struct mlx5_eqe *eqe)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+static int create_qprqsq_common(struct mlx5_core_dev *dev,
|
|
|
+ struct mlx5_core_qp *qp,
|
|
|
+ int rsc_type)
|
|
|
+{
|
|
|
+ struct mlx5_qp_table *table = &dev->priv.qp_table;
|
|
|
+ int err;
|
|
|
+
|
|
|
+ qp->common.res = rsc_type;
|
|
|
+ spin_lock_irq(&table->lock);
|
|
|
+ err = radix_tree_insert(&table->tree,
|
|
|
+ qp->qpn | (rsc_type << MLX5_USER_INDEX_LEN),
|
|
|
+ qp);
|
|
|
+ spin_unlock_irq(&table->lock);
|
|
|
+ if (err)
|
|
|
+ return err;
|
|
|
+
|
|
|
+ atomic_set(&qp->common.refcount, 1);
|
|
|
+ init_completion(&qp->common.free);
|
|
|
+ qp->pid = current->pid;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void destroy_qprqsq_common(struct mlx5_core_dev *dev,
|
|
|
+ struct mlx5_core_qp *qp)
|
|
|
+{
|
|
|
+ struct mlx5_qp_table *table = &dev->priv.qp_table;
|
|
|
+ unsigned long flags;
|
|
|
+
|
|
|
+ spin_lock_irqsave(&table->lock, flags);
|
|
|
+ radix_tree_delete(&table->tree,
|
|
|
+ qp->qpn | (qp->common.res << MLX5_USER_INDEX_LEN));
|
|
|
+ spin_unlock_irqrestore(&table->lock, flags);
|
|
|
+ mlx5_core_put_rsc((struct mlx5_core_rsc_common *)qp);
|
|
|
+ wait_for_completion(&qp->common.free);
|
|
|
+}
|
|
|
+
|
|
|
int mlx5_core_create_qp(struct mlx5_core_dev *dev,
|
|
|
struct mlx5_core_qp *qp,
|
|
|
struct mlx5_create_qp_mbox_in *in,
|
|
|
int inlen)
|
|
|
{
|
|
|
- struct mlx5_qp_table *table = &dev->priv.qp_table;
|
|
|
struct mlx5_create_qp_mbox_out out;
|
|
|
struct mlx5_destroy_qp_mbox_in din;
|
|
|
struct mlx5_destroy_qp_mbox_out dout;
|
|
@@ -206,24 +245,16 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev,
|
|
|
qp->qpn = be32_to_cpu(out.qpn) & 0xffffff;
|
|
|
mlx5_core_dbg(dev, "qpn = 0x%x\n", qp->qpn);
|
|
|
|
|
|
- qp->common.res = MLX5_RES_QP;
|
|
|
- spin_lock_irq(&table->lock);
|
|
|
- err = radix_tree_insert(&table->tree, qp->qpn, qp);
|
|
|
- spin_unlock_irq(&table->lock);
|
|
|
- if (err) {
|
|
|
- mlx5_core_warn(dev, "err %d\n", err);
|
|
|
+ err = create_qprqsq_common(dev, qp, MLX5_RES_QP);
|
|
|
+ if (err)
|
|
|
goto err_cmd;
|
|
|
- }
|
|
|
|
|
|
err = mlx5_debug_qp_add(dev, qp);
|
|
|
if (err)
|
|
|
mlx5_core_dbg(dev, "failed adding QP 0x%x to debug file system\n",
|
|
|
qp->qpn);
|
|
|
|
|
|
- qp->pid = current->pid;
|
|
|
- atomic_set(&qp->common.refcount, 1);
|
|
|
atomic_inc(&dev->num_qps);
|
|
|
- init_completion(&qp->common.free);
|
|
|
|
|
|
return 0;
|
|
|
|
|
@@ -243,18 +274,11 @@ int mlx5_core_destroy_qp(struct mlx5_core_dev *dev,
|
|
|
{
|
|
|
struct mlx5_destroy_qp_mbox_in in;
|
|
|
struct mlx5_destroy_qp_mbox_out out;
|
|
|
- struct mlx5_qp_table *table = &dev->priv.qp_table;
|
|
|
- unsigned long flags;
|
|
|
int err;
|
|
|
|
|
|
mlx5_debug_qp_remove(dev, qp);
|
|
|
|
|
|
- spin_lock_irqsave(&table->lock, flags);
|
|
|
- radix_tree_delete(&table->tree, qp->qpn);
|
|
|
- spin_unlock_irqrestore(&table->lock, flags);
|
|
|
-
|
|
|
- mlx5_core_put_rsc((struct mlx5_core_rsc_common *)qp);
|
|
|
- wait_for_completion(&qp->common.free);
|
|
|
+ destroy_qprqsq_common(dev, qp);
|
|
|
|
|
|
memset(&in, 0, sizeof(in));
|
|
|
memset(&out, 0, sizeof(out));
|
|
@@ -442,3 +466,67 @@ int mlx5_core_page_fault_resume(struct mlx5_core_dev *dev, u32 qpn,
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(mlx5_core_page_fault_resume);
|
|
|
#endif
|
|
|
+
|
|
|
+int mlx5_core_create_rq_tracked(struct mlx5_core_dev *dev, u32 *in, int inlen,
|
|
|
+ struct mlx5_core_qp *rq)
|
|
|
+{
|
|
|
+ int err;
|
|
|
+ u32 rqn;
|
|
|
+
|
|
|
+ err = mlx5_core_create_rq(dev, in, inlen, &rqn);
|
|
|
+ if (err)
|
|
|
+ return err;
|
|
|
+
|
|
|
+ rq->qpn = rqn;
|
|
|
+ err = create_qprqsq_common(dev, rq, MLX5_RES_RQ);
|
|
|
+ if (err)
|
|
|
+ goto err_destroy_rq;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+
|
|
|
+err_destroy_rq:
|
|
|
+ mlx5_core_destroy_rq(dev, rq->qpn);
|
|
|
+
|
|
|
+ return err;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(mlx5_core_create_rq_tracked);
|
|
|
+
|
|
|
+void mlx5_core_destroy_rq_tracked(struct mlx5_core_dev *dev,
|
|
|
+ struct mlx5_core_qp *rq)
|
|
|
+{
|
|
|
+ destroy_qprqsq_common(dev, rq);
|
|
|
+ mlx5_core_destroy_rq(dev, rq->qpn);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(mlx5_core_destroy_rq_tracked);
|
|
|
+
|
|
|
+int mlx5_core_create_sq_tracked(struct mlx5_core_dev *dev, u32 *in, int inlen,
|
|
|
+ struct mlx5_core_qp *sq)
|
|
|
+{
|
|
|
+ int err;
|
|
|
+ u32 sqn;
|
|
|
+
|
|
|
+ err = mlx5_core_create_sq(dev, in, inlen, &sqn);
|
|
|
+ if (err)
|
|
|
+ return err;
|
|
|
+
|
|
|
+ sq->qpn = sqn;
|
|
|
+ err = create_qprqsq_common(dev, sq, MLX5_RES_SQ);
|
|
|
+ if (err)
|
|
|
+ goto err_destroy_sq;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+
|
|
|
+err_destroy_sq:
|
|
|
+ mlx5_core_destroy_sq(dev, sq->qpn);
|
|
|
+
|
|
|
+ return err;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(mlx5_core_create_sq_tracked);
|
|
|
+
|
|
|
+void mlx5_core_destroy_sq_tracked(struct mlx5_core_dev *dev,
|
|
|
+ struct mlx5_core_qp *sq)
|
|
|
+{
|
|
|
+ destroy_qprqsq_common(dev, sq);
|
|
|
+ mlx5_core_destroy_sq(dev, sq->qpn);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(mlx5_core_destroy_sq_tracked);
|