aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eq.c12
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/qp.c57
-rw-r--r--include/linux/mlx5/driver.h13
-rw-r--r--include/linux/mlx5/qp.h3
4 files changed, 60 insertions, 25 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)
198 int eqes_found = 0; 198 int eqes_found = 0;
199 int set_ci = 0; 199 int set_ci = 0;
200 u32 cqn; 200 u32 cqn;
201 u32 srqn; 201 u32 rsn;
202 u8 port; 202 u8 port;
203 203
204 while ((eqe = next_eqe_sw(eq))) { 204 while ((eqe = next_eqe_sw(eq))) {
@@ -224,18 +224,18 @@ static int mlx5_eq_int(struct mlx5_core_dev *dev, struct mlx5_eq *eq)
224 case MLX5_EVENT_TYPE_PATH_MIG_FAILED: 224 case MLX5_EVENT_TYPE_PATH_MIG_FAILED:
225 case MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR: 225 case MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR:
226 case MLX5_EVENT_TYPE_WQ_ACCESS_ERROR: 226 case MLX5_EVENT_TYPE_WQ_ACCESS_ERROR:
227 rsn = be32_to_cpu(eqe->data.qp_srq.qp_srq_n) & 0xffffff;
227 mlx5_core_dbg(dev, "event %s(%d) arrived\n", 228 mlx5_core_dbg(dev, "event %s(%d) arrived\n",
228 eqe_type_str(eqe->type), eqe->type); 229 eqe_type_str(eqe->type), eqe->type);
229 mlx5_qp_event(dev, be32_to_cpu(eqe->data.qp_srq.qp_srq_n) & 0xffffff, 230 mlx5_rsc_event(dev, rsn, eqe->type);
230 eqe->type);
231 break; 231 break;
232 232
233 case MLX5_EVENT_TYPE_SRQ_RQ_LIMIT: 233 case MLX5_EVENT_TYPE_SRQ_RQ_LIMIT:
234 case MLX5_EVENT_TYPE_SRQ_CATAS_ERROR: 234 case MLX5_EVENT_TYPE_SRQ_CATAS_ERROR:
235 srqn = be32_to_cpu(eqe->data.qp_srq.qp_srq_n) & 0xffffff; 235 rsn = be32_to_cpu(eqe->data.qp_srq.qp_srq_n) & 0xffffff;
236 mlx5_core_dbg(dev, "SRQ event %s(%d): srqn 0x%x\n", 236 mlx5_core_dbg(dev, "SRQ event %s(%d): srqn 0x%x\n",
237 eqe_type_str(eqe->type), eqe->type, srqn); 237 eqe_type_str(eqe->type), eqe->type, rsn);
238 mlx5_srq_event(dev, srqn, eqe->type); 238 mlx5_srq_event(dev, rsn, eqe->type);
239 break; 239 break;
240 240
241 case MLX5_EVENT_TYPE_CMD: 241 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 @@
39 39
40#include "mlx5_core.h" 40#include "mlx5_core.h"
41 41
42void mlx5_qp_event(struct mlx5_core_dev *dev, u32 qpn, int event_type) 42static struct mlx5_core_rsc_common *mlx5_get_rsc(struct mlx5_core_dev *dev,
43 u32 rsn)
43{ 44{
44 struct mlx5_qp_table *table = &dev->priv.qp_table; 45 struct mlx5_qp_table *table = &dev->priv.qp_table;
45 struct mlx5_core_qp *qp; 46 struct mlx5_core_rsc_common *common;
46 47
47 spin_lock(&table->lock); 48 spin_lock(&table->lock);
48 49
49 qp = radix_tree_lookup(&table->tree, qpn); 50 common = radix_tree_lookup(&table->tree, rsn);
50 if (qp) 51 if (common)
51 atomic_inc(&qp->refcount); 52 atomic_inc(&common->refcount);
52 53
53 spin_unlock(&table->lock); 54 spin_unlock(&table->lock);
54 55
55 if (!qp) { 56 if (!common) {
56 mlx5_core_warn(dev, "Async event for bogus QP 0x%x\n", qpn); 57 mlx5_core_warn(dev, "Async event for bogus resource 0x%x\n",
57 return; 58 rsn);
59 return NULL;
58 } 60 }
61 return common;
62}
59 63
60 qp->event(qp, event_type); 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
70void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type)
71{
72 struct mlx5_core_rsc_common *common = mlx5_get_rsc(dev, rsn);
73 struct mlx5_core_qp *qp;
74
75 if (!common)
76 return;
77
78 switch (common->res) {
79 case MLX5_RES_QP:
80 qp = (struct mlx5_core_qp *)common;
81 qp->event(qp, event_type);
82 break;
83
84 default:
85 mlx5_core_warn(dev, "invalid resource type for 0x%x\n", rsn);
86 }
61 87
62 if (atomic_dec_and_test(&qp->refcount)) 88 mlx5_core_put_rsc(common);
63 complete(&qp->free);
64} 89}
65 90
66int mlx5_core_create_qp(struct mlx5_core_dev *dev, 91int mlx5_core_create_qp(struct mlx5_core_dev *dev,
@@ -92,6 +117,7 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev,
92 qp->qpn = be32_to_cpu(out.qpn) & 0xffffff; 117 qp->qpn = be32_to_cpu(out.qpn) & 0xffffff;
93 mlx5_core_dbg(dev, "qpn = 0x%x\n", qp->qpn); 118 mlx5_core_dbg(dev, "qpn = 0x%x\n", qp->qpn);
94 119
120 qp->common.res = MLX5_RES_QP;
95 spin_lock_irq(&table->lock); 121 spin_lock_irq(&table->lock);
96 err = radix_tree_insert(&table->tree, qp->qpn, qp); 122 err = radix_tree_insert(&table->tree, qp->qpn, qp);
97 spin_unlock_irq(&table->lock); 123 spin_unlock_irq(&table->lock);
@@ -106,9 +132,9 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev,
106 qp->qpn); 132 qp->qpn);
107 133
108 qp->pid = current->pid; 134 qp->pid = current->pid;
109 atomic_set(&qp->refcount, 1); 135 atomic_set(&qp->common.refcount, 1);
110 atomic_inc(&dev->num_qps); 136 atomic_inc(&dev->num_qps);
111 init_completion(&qp->free); 137 init_completion(&qp->common.free);
112 138
113 return 0; 139 return 0;
114 140
@@ -138,9 +164,8 @@ int mlx5_core_destroy_qp(struct mlx5_core_dev *dev,
138 radix_tree_delete(&table->tree, qp->qpn); 164 radix_tree_delete(&table->tree, qp->qpn);
139 spin_unlock_irqrestore(&table->lock, flags); 165 spin_unlock_irqrestore(&table->lock, flags);
140 166
141 if (atomic_dec_and_test(&qp->refcount)) 167 mlx5_core_put_rsc((struct mlx5_core_rsc_common *)qp);
142 complete(&qp->free); 168 wait_for_completion(&qp->common.free);
143 wait_for_completion(&qp->free);
144 169
145 memset(&in, 0, sizeof(in)); 170 memset(&in, 0, sizeof(in));
146 memset(&out, 0, sizeof(out)); 171 memset(&out, 0, sizeof(out));
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index c439f9c59b93..246310dc8bef 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -375,6 +375,16 @@ struct mlx5_core_mr {
375 u32 pd; 375 u32 pd;
376}; 376};
377 377
378enum mlx5_res_type {
379 MLX5_RES_QP,
380};
381
382struct mlx5_core_rsc_common {
383 enum mlx5_res_type res;
384 atomic_t refcount;
385 struct completion free;
386};
387
378struct mlx5_core_srq { 388struct mlx5_core_srq {
379 u32 srqn; 389 u32 srqn;
380 int max; 390 int max;
@@ -700,7 +710,7 @@ int mlx5_eq_init(struct mlx5_core_dev *dev);
700void mlx5_eq_cleanup(struct mlx5_core_dev *dev); 710void mlx5_eq_cleanup(struct mlx5_core_dev *dev);
701void mlx5_fill_page_array(struct mlx5_buf *buf, __be64 *pas); 711void mlx5_fill_page_array(struct mlx5_buf *buf, __be64 *pas);
702void mlx5_cq_completion(struct mlx5_core_dev *dev, u32 cqn); 712void mlx5_cq_completion(struct mlx5_core_dev *dev, u32 cqn);
703void mlx5_qp_event(struct mlx5_core_dev *dev, u32 qpn, int event_type); 713void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type);
704void mlx5_srq_event(struct mlx5_core_dev *dev, u32 srqn, int event_type); 714void mlx5_srq_event(struct mlx5_core_dev *dev, u32 srqn, int event_type);
705struct mlx5_core_srq *mlx5_core_get_srq(struct mlx5_core_dev *dev, u32 srqn); 715struct mlx5_core_srq *mlx5_core_get_srq(struct mlx5_core_dev *dev, u32 srqn);
706void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, unsigned long vector); 716void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, unsigned long vector);
@@ -737,6 +747,7 @@ void mlx5_cmdif_debugfs_cleanup(struct mlx5_core_dev *dev);
737int mlx5_core_create_psv(struct mlx5_core_dev *dev, u32 pdn, 747int mlx5_core_create_psv(struct mlx5_core_dev *dev, u32 pdn,
738 int npsvs, u32 *sig_index); 748 int npsvs, u32 *sig_index);
739int mlx5_core_destroy_psv(struct mlx5_core_dev *dev, int psv_num); 749int mlx5_core_destroy_psv(struct mlx5_core_dev *dev, int psv_num);
750void mlx5_core_put_rsc(struct mlx5_core_rsc_common *common);
740 751
741static inline u32 mlx5_mkey_to_idx(u32 mkey) 752static inline u32 mlx5_mkey_to_idx(u32 mkey)
742{ 753{
diff --git a/include/linux/mlx5/qp.h b/include/linux/mlx5/qp.h
index 9709b30e2d69..7c4c0f1f5805 100644
--- a/include/linux/mlx5/qp.h
+++ b/include/linux/mlx5/qp.h
@@ -342,10 +342,9 @@ struct mlx5_stride_block_ctrl_seg {
342}; 342};
343 343
344struct mlx5_core_qp { 344struct mlx5_core_qp {
345 struct mlx5_core_rsc_common common; /* must be first */
345 void (*event) (struct mlx5_core_qp *, int); 346 void (*event) (struct mlx5_core_qp *, int);
346 int qpn; 347 int qpn;
347 atomic_t refcount;
348 struct completion free;
349 struct mlx5_rsc_debug *dbg; 348 struct mlx5_rsc_debug *dbg;
350 int pid; 349 int pid;
351}; 350};