aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaeed Mahameed <saeedm@mellanox.com>2018-02-01 06:32:00 -0500
committerSaeed Mahameed <saeedm@mellanox.com>2018-02-15 03:30:01 -0500
commitf105b45bf77ced96e516e1cd771c41bb7e8c830b (patch)
treebc86d8533f9f0ffc3187d7bf13565610f2e3f15e
parentd5c07157dd4f5ab9123eaab7db572ca360c19a55 (diff)
net/mlx5: CQ hold/put API
Now as the CQ table is per EQ, add an API to hold/put CQ to be used from eq.c in downstream patch. Signed-off-by: Saeed Mahameed <saeedm@mellanox.com> Reviewed-by: Gal Pressman <galp@mellanox.com>
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/cq.c42
-rw-r--r--include/linux/mlx5/cq.h11
2 files changed, 30 insertions, 23 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cq.c b/drivers/net/ethernet/mellanox/mlx5/core/cq.c
index f6e478d05ecc..06dc7bd302ed 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/cq.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/cq.c
@@ -58,8 +58,7 @@ void mlx5_cq_tasklet_cb(unsigned long data)
58 tasklet_ctx.list) { 58 tasklet_ctx.list) {
59 list_del_init(&mcq->tasklet_ctx.list); 59 list_del_init(&mcq->tasklet_ctx.list);
60 mcq->tasklet_ctx.comp(mcq); 60 mcq->tasklet_ctx.comp(mcq);
61 if (refcount_dec_and_test(&mcq->refcount)) 61 mlx5_cq_put(mcq);
62 complete(&mcq->free);
63 if (time_after(jiffies, end)) 62 if (time_after(jiffies, end))
64 break; 63 break;
65 } 64 }
@@ -80,23 +79,31 @@ static void mlx5_add_cq_to_tasklet(struct mlx5_core_cq *cq)
80 * still arrive. 79 * still arrive.
81 */ 80 */
82 if (list_empty_careful(&cq->tasklet_ctx.list)) { 81 if (list_empty_careful(&cq->tasklet_ctx.list)) {
83 refcount_inc(&cq->refcount); 82 mlx5_cq_hold(cq);
84 list_add_tail(&cq->tasklet_ctx.list, &tasklet_ctx->list); 83 list_add_tail(&cq->tasklet_ctx.list, &tasklet_ctx->list);
85 } 84 }
86 spin_unlock_irqrestore(&tasklet_ctx->lock, flags); 85 spin_unlock_irqrestore(&tasklet_ctx->lock, flags);
87} 86}
88 87
89void mlx5_cq_completion(struct mlx5_eq *eq, u32 cqn) 88/* caller must eventually call mlx5_cq_put on the returned cq */
89static struct mlx5_core_cq *mlx5_eq_cq_get(struct mlx5_eq *eq, u32 cqn)
90{ 90{
91 struct mlx5_cq_table *table = &eq->cq_table; 91 struct mlx5_cq_table *table = &eq->cq_table;
92 struct mlx5_core_cq *cq; 92 struct mlx5_core_cq *cq = NULL;
93 93
94 spin_lock(&table->lock); 94 spin_lock(&table->lock);
95 cq = radix_tree_lookup(&table->tree, cqn); 95 cq = radix_tree_lookup(&table->tree, cqn);
96 if (likely(cq)) 96 if (likely(cq))
97 refcount_inc(&cq->refcount); 97 mlx5_cq_hold(cq);
98 spin_unlock(&table->lock); 98 spin_unlock(&table->lock);
99 99
100 return cq;
101}
102
103void mlx5_cq_completion(struct mlx5_eq *eq, u32 cqn)
104{
105 struct mlx5_core_cq *cq = mlx5_eq_cq_get(eq, cqn);
106
100 if (unlikely(!cq)) { 107 if (unlikely(!cq)) {
101 mlx5_core_warn(eq->dev, "Completion event for bogus CQ 0x%x\n", cqn); 108 mlx5_core_warn(eq->dev, "Completion event for bogus CQ 0x%x\n", cqn);
102 return; 109 return;
@@ -106,22 +113,12 @@ void mlx5_cq_completion(struct mlx5_eq *eq, u32 cqn)
106 113
107 cq->comp(cq); 114 cq->comp(cq);
108 115
109 if (refcount_dec_and_test(&cq->refcount)) 116 mlx5_cq_put(cq);
110 complete(&cq->free);
111} 117}
112 118
113void mlx5_cq_event(struct mlx5_eq *eq, u32 cqn, int event_type) 119void mlx5_cq_event(struct mlx5_eq *eq, u32 cqn, int event_type)
114{ 120{
115 struct mlx5_cq_table *table = &eq->cq_table; 121 struct mlx5_core_cq *cq = mlx5_eq_cq_get(eq, cqn);
116 struct mlx5_core_cq *cq;
117
118 spin_lock(&table->lock);
119
120 cq = radix_tree_lookup(&table->tree, cqn);
121 if (likely(cq))
122 refcount_inc(&cq->refcount);
123
124 spin_unlock(&table->lock);
125 122
126 if (unlikely(!cq)) { 123 if (unlikely(!cq)) {
127 mlx5_core_warn(eq->dev, "Async event for bogus CQ 0x%x\n", cqn); 124 mlx5_core_warn(eq->dev, "Async event for bogus CQ 0x%x\n", cqn);
@@ -130,8 +127,7 @@ void mlx5_cq_event(struct mlx5_eq *eq, u32 cqn, int event_type)
130 127
131 cq->event(cq, event_type); 128 cq->event(cq, event_type);
132 129
133 if (refcount_dec_and_test(&cq->refcount)) 130 mlx5_cq_put(cq);
134 complete(&cq->free);
135} 131}
136 132
137int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, 133int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
@@ -158,7 +154,8 @@ int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
158 cq->cons_index = 0; 154 cq->cons_index = 0;
159 cq->arm_sn = 0; 155 cq->arm_sn = 0;
160 cq->eq = eq; 156 cq->eq = eq;
161 refcount_set(&cq->refcount, 1); 157 refcount_set(&cq->refcount, 0);
158 mlx5_cq_hold(cq);
162 init_completion(&cq->free); 159 init_completion(&cq->free);
163 if (!cq->comp) 160 if (!cq->comp)
164 cq->comp = mlx5_add_cq_to_tasklet; 161 cq->comp = mlx5_add_cq_to_tasklet;
@@ -221,8 +218,7 @@ int mlx5_core_destroy_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq)
221 synchronize_irq(cq->irqn); 218 synchronize_irq(cq->irqn);
222 219
223 mlx5_debug_cq_remove(dev, cq); 220 mlx5_debug_cq_remove(dev, cq);
224 if (refcount_dec_and_test(&cq->refcount)) 221 mlx5_cq_put(cq);
225 complete(&cq->free);
226 wait_for_completion(&cq->free); 222 wait_for_completion(&cq->free);
227 223
228 return 0; 224 return 0;
diff --git a/include/linux/mlx5/cq.h b/include/linux/mlx5/cq.h
index 06ba425a6ad7..445ad194e0fe 100644
--- a/include/linux/mlx5/cq.h
+++ b/include/linux/mlx5/cq.h
@@ -172,6 +172,17 @@ static inline void mlx5_cq_arm(struct mlx5_core_cq *cq, u32 cmd,
172 mlx5_write64(doorbell, uar_page + MLX5_CQ_DOORBELL, NULL); 172 mlx5_write64(doorbell, uar_page + MLX5_CQ_DOORBELL, NULL);
173} 173}
174 174
175static inline void mlx5_cq_hold(struct mlx5_core_cq *cq)
176{
177 refcount_inc(&cq->refcount);
178}
179
180static inline void mlx5_cq_put(struct mlx5_core_cq *cq)
181{
182 if (refcount_dec_and_test(&cq->refcount))
183 complete(&cq->free);
184}
185
175int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, 186int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
176 u32 *in, int inlen); 187 u32 *in, int inlen);
177int mlx5_core_destroy_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq); 188int mlx5_core_destroy_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq);