summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorEli Cohen <eli@mellanox.com>2014-10-02 13:19:45 +0400
committerDavid S. Miller <davem@davemloft.net>2014-10-04 02:42:32 +0400
commit5903325a64834211daf63a62db3b35ee580cb8bf (patch)
tree74a608cedc17732bbc607d157ddfd3c01e9757f5 /drivers
parentb775516b042f9e35f856bd2914afefd9d23021d7 (diff)
downloadlinux-5903325a64834211daf63a62db3b35ee580cb8bf.tar.xz
net/mlx5_core: Identify resources by their type
This patch puts a common part as the first field of mlx5_core_qp. This field is used to identify which resource generated an event. This is required since upcoming new resource types such as DC targets are allocated for the same numerical space as regular QPs and may generate the same events. By searching the resource in the same table we can then look at the common field to identify the resource. Signed-off-by: Eli Cohen <eli@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eq.c12
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/qp.c57
2 files changed, 47 insertions, 22 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
index 11b9b840ad4d..ed53291468f3 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
@@ -198,7 +198,7 @@ static int mlx5_eq_int(struct mlx5_core_dev *dev, struct mlx5_eq *eq)
int eqes_found = 0;
int set_ci = 0;
u32 cqn;
- u32 srqn;
+ u32 rsn;
u8 port;
while ((eqe = next_eqe_sw(eq))) {
@@ -224,18 +224,18 @@ static int mlx5_eq_int(struct mlx5_core_dev *dev, struct mlx5_eq *eq)
case MLX5_EVENT_TYPE_PATH_MIG_FAILED:
case MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR:
case MLX5_EVENT_TYPE_WQ_ACCESS_ERROR:
+ rsn = be32_to_cpu(eqe->data.qp_srq.qp_srq_n) & 0xffffff;
mlx5_core_dbg(dev, "event %s(%d) arrived\n",
eqe_type_str(eqe->type), eqe->type);
- mlx5_qp_event(dev, be32_to_cpu(eqe->data.qp_srq.qp_srq_n) & 0xffffff,
- eqe->type);
+ mlx5_rsc_event(dev, rsn, eqe->type);
break;
case MLX5_EVENT_TYPE_SRQ_RQ_LIMIT:
case MLX5_EVENT_TYPE_SRQ_CATAS_ERROR:
- srqn = be32_to_cpu(eqe->data.qp_srq.qp_srq_n) & 0xffffff;
+ rsn = be32_to_cpu(eqe->data.qp_srq.qp_srq_n) & 0xffffff;
mlx5_core_dbg(dev, "SRQ event %s(%d): srqn 0x%x\n",
- eqe_type_str(eqe->type), eqe->type, srqn);
- mlx5_srq_event(dev, srqn, eqe->type);
+ eqe_type_str(eqe->type), eqe->type, rsn);
+ mlx5_srq_event(dev, rsn, eqe->type);
break;
case MLX5_EVENT_TYPE_CMD:
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/qp.c b/drivers/net/ethernet/mellanox/mlx5/core/qp.c
index 415b67ce379e..5261a2b0da43 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/qp.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/qp.c
@@ -39,28 +39,53 @@
#include "mlx5_core.h"
-void mlx5_qp_event(struct mlx5_core_dev *dev, u32 qpn, int event_type)
+static struct mlx5_core_rsc_common *mlx5_get_rsc(struct mlx5_core_dev *dev,
+ u32 rsn)
{
struct mlx5_qp_table *table = &dev->priv.qp_table;
- struct mlx5_core_qp *qp;
+ struct mlx5_core_rsc_common *common;
spin_lock(&table->lock);
- qp = radix_tree_lookup(&table->tree, qpn);
- if (qp)
- atomic_inc(&qp->refcount);
+ common = radix_tree_lookup(&table->tree, rsn);
+ if (common)
+ atomic_inc(&common->refcount);
spin_unlock(&table->lock);
- if (!qp) {
- mlx5_core_warn(dev, "Async event for bogus QP 0x%x\n", qpn);
- return;
+ if (!common) {
+ mlx5_core_warn(dev, "Async event for bogus resource 0x%x\n",
+ rsn);
+ return NULL;
}
+ return common;
+}
- qp->event(qp, event_type);
+void mlx5_core_put_rsc(struct mlx5_core_rsc_common *common)
+{
+ if (atomic_dec_and_test(&common->refcount))
+ complete(&common->free);
+}
+
+void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type)
+{
+ struct mlx5_core_rsc_common *common = mlx5_get_rsc(dev, rsn);
+ struct mlx5_core_qp *qp;
+
+ if (!common)
+ return;
+
+ switch (common->res) {
+ case MLX5_RES_QP:
+ qp = (struct mlx5_core_qp *)common;
+ qp->event(qp, event_type);
+ break;
+
+ default:
+ mlx5_core_warn(dev, "invalid resource type for 0x%x\n", rsn);
+ }
- if (atomic_dec_and_test(&qp->refcount))
- complete(&qp->free);
+ mlx5_core_put_rsc(common);
}
int mlx5_core_create_qp(struct mlx5_core_dev *dev,
@@ -92,6 +117,7 @@ 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);
@@ -106,9 +132,9 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev,
qp->qpn);
qp->pid = current->pid;
- atomic_set(&qp->refcount, 1);
+ atomic_set(&qp->common.refcount, 1);
atomic_inc(&dev->num_qps);
- init_completion(&qp->free);
+ init_completion(&qp->common.free);
return 0;
@@ -138,9 +164,8 @@ int mlx5_core_destroy_qp(struct mlx5_core_dev *dev,
radix_tree_delete(&table->tree, qp->qpn);
spin_unlock_irqrestore(&table->lock, flags);
- if (atomic_dec_and_test(&qp->refcount))
- complete(&qp->free);
- wait_for_completion(&qp->free);
+ mlx5_core_put_rsc((struct mlx5_core_rsc_common *)qp);
+ wait_for_completion(&qp->common.free);
memset(&in, 0, sizeof(in));
memset(&out, 0, sizeof(out));