@@ -99,6 +99,7 @@ struct res_qp {
99
99
struct list_head mcg_list ;
100
100
spinlock_t mcg_spl ;
101
101
int local_qpn ;
102
+ atomic_t ref_count ;
102
103
};
103
104
104
105
enum res_mtt_states {
@@ -197,6 +198,7 @@ enum res_fs_rule_states {
197
198
198
199
struct res_fs_rule {
199
200
struct res_common com ;
201
+ int qpn ;
200
202
};
201
203
202
204
static void * res_tracker_lookup (struct rb_root * root , u64 res_id )
@@ -447,6 +449,7 @@ static struct res_common *alloc_qp_tr(int id)
447
449
ret -> local_qpn = id ;
448
450
INIT_LIST_HEAD (& ret -> mcg_list );
449
451
spin_lock_init (& ret -> mcg_spl );
452
+ atomic_set (& ret -> ref_count , 0 );
450
453
451
454
return & ret -> com ;
452
455
}
@@ -554,7 +557,7 @@ static struct res_common *alloc_xrcdn_tr(int id)
554
557
return & ret -> com ;
555
558
}
556
559
557
- static struct res_common * alloc_fs_rule_tr (u64 id )
560
+ static struct res_common * alloc_fs_rule_tr (u64 id , int qpn )
558
561
{
559
562
struct res_fs_rule * ret ;
560
563
@@ -564,7 +567,7 @@ static struct res_common *alloc_fs_rule_tr(u64 id)
564
567
565
568
ret -> com .res_id = id ;
566
569
ret -> com .state = RES_FS_RULE_ALLOCATED ;
567
-
570
+ ret -> qpn = qpn ;
568
571
return & ret -> com ;
569
572
}
570
573
@@ -602,7 +605,7 @@ static struct res_common *alloc_tr(u64 id, enum mlx4_resource type, int slave,
602
605
ret = alloc_xrcdn_tr (id );
603
606
break ;
604
607
case RES_FS_RULE :
605
- ret = alloc_fs_rule_tr (id );
608
+ ret = alloc_fs_rule_tr (id , extra );
606
609
break ;
607
610
default :
608
611
return NULL ;
@@ -671,10 +674,14 @@ static int add_res_range(struct mlx4_dev *dev, int slave, u64 base, int count,
671
674
672
675
static int remove_qp_ok (struct res_qp * res )
673
676
{
674
- if (res -> com .state == RES_QP_BUSY )
677
+ if (res -> com .state == RES_QP_BUSY || atomic_read (& res -> ref_count ) ||
678
+ !list_empty (& res -> mcg_list )) {
679
+ pr_err ("resource tracker: fail to remove qp, state %d, ref_count %d\n" ,
680
+ res -> com .state , atomic_read (& res -> ref_count ));
675
681
return - EBUSY ;
676
- else if (res -> com .state != RES_QP_RESERVED )
682
+ } else if (res -> com .state != RES_QP_RESERVED ) {
677
683
return - EPERM ;
684
+ }
678
685
679
686
return 0 ;
680
687
}
@@ -3124,6 +3131,7 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
3124
3131
struct list_head * rlist = & tracker -> slave_list [slave ].res_list [RES_MAC ];
3125
3132
int err ;
3126
3133
int qpn ;
3134
+ struct res_qp * rqp ;
3127
3135
struct mlx4_net_trans_rule_hw_ctrl * ctrl ;
3128
3136
struct _rule_hw * rule_header ;
3129
3137
int header_id ;
@@ -3134,7 +3142,7 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
3134
3142
3135
3143
ctrl = (struct mlx4_net_trans_rule_hw_ctrl * )inbox -> buf ;
3136
3144
qpn = be32_to_cpu (ctrl -> qpn ) & 0xffffff ;
3137
- err = get_res (dev , slave , qpn , RES_QP , NULL );
3145
+ err = get_res (dev , slave , qpn , RES_QP , & rqp );
3138
3146
if (err ) {
3139
3147
pr_err ("Steering rule with qpn 0x%x rejected.\n" , qpn );
3140
3148
return err ;
@@ -3175,14 +3183,16 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
3175
3183
if (err )
3176
3184
goto err_put ;
3177
3185
3178
- err = add_res_range (dev , slave , vhcr -> out_param , 1 , RES_FS_RULE , 0 );
3186
+ err = add_res_range (dev , slave , vhcr -> out_param , 1 , RES_FS_RULE , qpn );
3179
3187
if (err ) {
3180
3188
mlx4_err (dev , "Fail to add flow steering resources.\n " );
3181
3189
/* detach rule*/
3182
3190
mlx4_cmd (dev , vhcr -> out_param , 0 , 0 ,
3183
3191
MLX4_QP_FLOW_STEERING_DETACH , MLX4_CMD_TIME_CLASS_A ,
3184
3192
MLX4_CMD_NATIVE );
3193
+ goto err_put ;
3185
3194
}
3195
+ atomic_inc (& rqp -> ref_count );
3186
3196
err_put :
3187
3197
put_res (dev , slave , qpn , RES_QP );
3188
3198
return err ;
@@ -3195,20 +3205,35 @@ int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev *dev, int slave,
3195
3205
struct mlx4_cmd_info * cmd )
3196
3206
{
3197
3207
int err ;
3208
+ struct res_qp * rqp ;
3209
+ struct res_fs_rule * rrule ;
3198
3210
3199
3211
if (dev -> caps .steering_mode !=
3200
3212
MLX4_STEERING_MODE_DEVICE_MANAGED )
3201
3213
return - EOPNOTSUPP ;
3202
3214
3215
+ err = get_res (dev , slave , vhcr -> in_param , RES_FS_RULE , & rrule );
3216
+ if (err )
3217
+ return err ;
3218
+ /* Release the rule form busy state before removal */
3219
+ put_res (dev , slave , vhcr -> in_param , RES_FS_RULE );
3220
+ err = get_res (dev , slave , rrule -> qpn , RES_QP , & rqp );
3221
+ if (err )
3222
+ return err ;
3223
+
3203
3224
err = rem_res_range (dev , slave , vhcr -> in_param , 1 , RES_FS_RULE , 0 );
3204
3225
if (err ) {
3205
3226
mlx4_err (dev , "Fail to remove flow steering resources.\n " );
3206
- return err ;
3227
+ goto out ;
3207
3228
}
3208
3229
3209
3230
err = mlx4_cmd (dev , vhcr -> in_param , 0 , 0 ,
3210
3231
MLX4_QP_FLOW_STEERING_DETACH , MLX4_CMD_TIME_CLASS_A ,
3211
3232
MLX4_CMD_NATIVE );
3233
+ if (!err )
3234
+ atomic_dec (& rqp -> ref_count );
3235
+ out :
3236
+ put_res (dev , slave , rrule -> qpn , RES_QP );
3212
3237
return err ;
3213
3238
}
3214
3239
0 commit comments