@@ -58,8 +58,7 @@ void mlx5_cq_tasklet_cb(unsigned long data)
5858 tasklet_ctx .list ) {
5959 list_del_init (& mcq -> tasklet_ctx .list );
6060 mcq -> tasklet_ctx .comp (mcq );
61- if (refcount_dec_and_test (& mcq -> refcount ))
62- complete (& mcq -> free );
61+ mlx5_cq_put (mcq );
6362 if (time_after (jiffies , end ))
6463 break ;
6564 }
@@ -80,23 +79,31 @@ static void mlx5_add_cq_to_tasklet(struct mlx5_core_cq *cq)
8079 * still arrive.
8180 */
8281 if (list_empty_careful (& cq -> tasklet_ctx .list )) {
83- refcount_inc ( & cq -> refcount );
82+ mlx5_cq_hold ( cq );
8483 list_add_tail (& cq -> tasklet_ctx .list , & tasklet_ctx -> list );
8584 }
8685 spin_unlock_irqrestore (& tasklet_ctx -> lock , flags );
8786}
8887
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 )
9090{
9191 struct mlx5_cq_table * table = & eq -> cq_table ;
92- struct mlx5_core_cq * cq ;
92+ struct mlx5_core_cq * cq = NULL ;
9393
9494 spin_lock (& table -> lock );
9595 cq = radix_tree_lookup (& table -> tree , cqn );
9696 if (likely (cq ))
97- refcount_inc ( & cq -> refcount );
97+ mlx5_cq_hold ( cq );
9898 spin_unlock (& table -> lock );
9999
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+
100107 if (unlikely (!cq )) {
101108 mlx5_core_warn (eq -> dev , "Completion event for bogus CQ 0x%x\n" , cqn );
102109 return ;
@@ -106,22 +113,12 @@ void mlx5_cq_completion(struct mlx5_eq *eq, u32 cqn)
106113
107114 cq -> comp (cq );
108115
109- if (refcount_dec_and_test (& cq -> refcount ))
110- complete (& cq -> free );
116+ mlx5_cq_put (cq );
111117}
112118
113119void mlx5_cq_event (struct mlx5_eq * eq , u32 cqn , int event_type )
114120{
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 );
125122
126123 if (unlikely (!cq )) {
127124 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)
130127
131128 cq -> event (cq , event_type );
132129
133- if (refcount_dec_and_test (& cq -> refcount ))
134- complete (& cq -> free );
130+ mlx5_cq_put (cq );
135131}
136132
137133int 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,
158154 cq -> cons_index = 0 ;
159155 cq -> arm_sn = 0 ;
160156 cq -> eq = eq ;
161- refcount_set (& cq -> refcount , 1 );
157+ refcount_set (& cq -> refcount , 0 );
158+ mlx5_cq_hold (cq );
162159 init_completion (& cq -> free );
163160 if (!cq -> comp )
164161 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)
221218 synchronize_irq (cq -> irqn );
222219
223220 mlx5_debug_cq_remove (dev , cq );
224- if (refcount_dec_and_test (& cq -> refcount ))
225- complete (& cq -> free );
221+ mlx5_cq_put (cq );
226222 wait_for_completion (& cq -> free );
227223
228224 return 0 ;
0 commit comments