@@ -58,8 +58,7 @@ void mlx5_cq_tasklet_cb(unsigned long data)
58
58
tasklet_ctx .list ) {
59
59
list_del_init (& mcq -> tasklet_ctx .list );
60
60
mcq -> tasklet_ctx .comp (mcq );
61
- if (refcount_dec_and_test (& mcq -> refcount ))
62
- complete (& mcq -> free );
61
+ mlx5_cq_put (mcq );
63
62
if (time_after (jiffies , end ))
64
63
break ;
65
64
}
@@ -80,23 +79,31 @@ static void mlx5_add_cq_to_tasklet(struct mlx5_core_cq *cq)
80
79
* still arrive.
81
80
*/
82
81
if (list_empty_careful (& cq -> tasklet_ctx .list )) {
83
- refcount_inc ( & cq -> refcount );
82
+ mlx5_cq_hold ( cq );
84
83
list_add_tail (& cq -> tasklet_ctx .list , & tasklet_ctx -> list );
85
84
}
86
85
spin_unlock_irqrestore (& tasklet_ctx -> lock , flags );
87
86
}
88
87
89
- void mlx5_cq_completion (struct mlx5_eq * eq , u32 cqn )
88
+ /* caller must eventually call mlx5_cq_put on the returned cq */
89
+ static struct mlx5_core_cq * mlx5_eq_cq_get (struct mlx5_eq * eq , u32 cqn )
90
90
{
91
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
94
spin_lock (& table -> lock );
95
95
cq = radix_tree_lookup (& table -> tree , cqn );
96
96
if (likely (cq ))
97
- refcount_inc ( & cq -> refcount );
97
+ mlx5_cq_hold ( cq );
98
98
spin_unlock (& table -> lock );
99
99
100
+ return cq ;
101
+ }
102
+
103
+ void mlx5_cq_completion (struct mlx5_eq * eq , u32 cqn )
104
+ {
105
+ struct mlx5_core_cq * cq = mlx5_eq_cq_get (eq , cqn );
106
+
100
107
if (unlikely (!cq )) {
101
108
mlx5_core_warn (eq -> dev , "Completion event for bogus CQ 0x%x\n" , cqn );
102
109
return ;
@@ -106,22 +113,12 @@ void mlx5_cq_completion(struct mlx5_eq *eq, u32 cqn)
106
113
107
114
cq -> comp (cq );
108
115
109
- if (refcount_dec_and_test (& cq -> refcount ))
110
- complete (& cq -> free );
116
+ mlx5_cq_put (cq );
111
117
}
112
118
113
119
void mlx5_cq_event (struct mlx5_eq * eq , u32 cqn , int event_type )
114
120
{
115
- struct mlx5_cq_table * table = & eq -> cq_table ;
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 );
121
+ struct mlx5_core_cq * cq = mlx5_eq_cq_get (eq , cqn );
125
122
126
123
if (unlikely (!cq )) {
127
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
128
cq -> event (cq , event_type );
132
129
133
- if (refcount_dec_and_test (& cq -> refcount ))
134
- complete (& cq -> free );
130
+ mlx5_cq_put (cq );
135
131
}
136
132
137
133
int 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
154
cq -> cons_index = 0 ;
159
155
cq -> arm_sn = 0 ;
160
156
cq -> eq = eq ;
161
- refcount_set (& cq -> refcount , 1 );
157
+ refcount_set (& cq -> refcount , 0 );
158
+ mlx5_cq_hold (cq );
162
159
init_completion (& cq -> free );
163
160
if (!cq -> comp )
164
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
218
synchronize_irq (cq -> irqn );
222
219
223
220
mlx5_debug_cq_remove (dev , cq );
224
- if (refcount_dec_and_test (& cq -> refcount ))
225
- complete (& cq -> free );
221
+ mlx5_cq_put (cq );
226
222
wait_for_completion (& cq -> free );
227
223
228
224
return 0 ;
0 commit comments