diff options
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/eq.c | 12 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/qp.c | 57 | ||||
-rw-r--r-- | include/linux/mlx5/driver.h | 13 | ||||
-rw-r--r-- | include/linux/mlx5/qp.h | 3 |
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 | ||
42 | void mlx5_qp_event(struct mlx5_core_dev *dev, u32 qpn, int event_type) | 42 | static 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); | 64 | void 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 | |||
70 | void 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 | ||
66 | int mlx5_core_create_qp(struct mlx5_core_dev *dev, | 91 | int 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 | ||
378 | enum mlx5_res_type { | ||
379 | MLX5_RES_QP, | ||
380 | }; | ||
381 | |||
382 | struct mlx5_core_rsc_common { | ||
383 | enum mlx5_res_type res; | ||
384 | atomic_t refcount; | ||
385 | struct completion free; | ||
386 | }; | ||
387 | |||
378 | struct mlx5_core_srq { | 388 | struct 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); | |||
700 | void mlx5_eq_cleanup(struct mlx5_core_dev *dev); | 710 | void mlx5_eq_cleanup(struct mlx5_core_dev *dev); |
701 | void mlx5_fill_page_array(struct mlx5_buf *buf, __be64 *pas); | 711 | void mlx5_fill_page_array(struct mlx5_buf *buf, __be64 *pas); |
702 | void mlx5_cq_completion(struct mlx5_core_dev *dev, u32 cqn); | 712 | void mlx5_cq_completion(struct mlx5_core_dev *dev, u32 cqn); |
703 | void mlx5_qp_event(struct mlx5_core_dev *dev, u32 qpn, int event_type); | 713 | void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type); |
704 | void mlx5_srq_event(struct mlx5_core_dev *dev, u32 srqn, int event_type); | 714 | void mlx5_srq_event(struct mlx5_core_dev *dev, u32 srqn, int event_type); |
705 | struct mlx5_core_srq *mlx5_core_get_srq(struct mlx5_core_dev *dev, u32 srqn); | 715 | struct mlx5_core_srq *mlx5_core_get_srq(struct mlx5_core_dev *dev, u32 srqn); |
706 | void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, unsigned long vector); | 716 | void 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); | |||
737 | int mlx5_core_create_psv(struct mlx5_core_dev *dev, u32 pdn, | 747 | int mlx5_core_create_psv(struct mlx5_core_dev *dev, u32 pdn, |
738 | int npsvs, u32 *sig_index); | 748 | int npsvs, u32 *sig_index); |
739 | int mlx5_core_destroy_psv(struct mlx5_core_dev *dev, int psv_num); | 749 | int mlx5_core_destroy_psv(struct mlx5_core_dev *dev, int psv_num); |
750 | void mlx5_core_put_rsc(struct mlx5_core_rsc_common *common); | ||
740 | 751 | ||
741 | static inline u32 mlx5_mkey_to_idx(u32 mkey) | 752 | static 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 | ||
344 | struct mlx5_core_qp { | 344 | struct 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 | }; |