@@ -190,6 +190,15 @@ struct res_xrcdn {
190
190
int port ;
191
191
};
192
192
193
+ enum res_fs_rule_states {
194
+ RES_FS_RULE_BUSY = RES_ANY_BUSY ,
195
+ RES_FS_RULE_ALLOCATED ,
196
+ };
197
+
198
+ struct res_fs_rule {
199
+ struct res_common com ;
200
+ };
201
+
193
202
static void * res_tracker_lookup (struct rb_root * root , u64 res_id )
194
203
{
195
204
struct rb_node * node = root -> rb_node ;
@@ -245,6 +254,7 @@ static const char *ResourceType(enum mlx4_resource rt)
245
254
case RES_MAC : return "RES_MAC" ;
246
255
case RES_EQ : return "RES_EQ" ;
247
256
case RES_COUNTER : return "RES_COUNTER" ;
257
+ case RES_FS_RULE : return "RES_FS_RULE" ;
248
258
case RES_XRCD : return "RES_XRCD" ;
249
259
default : return "Unknown resource type !!!" ;
250
260
};
@@ -516,6 +526,20 @@ static struct res_common *alloc_xrcdn_tr(int id)
516
526
return & ret -> com ;
517
527
}
518
528
529
+ static struct res_common * alloc_fs_rule_tr (u64 id )
530
+ {
531
+ struct res_fs_rule * ret ;
532
+
533
+ ret = kzalloc (sizeof * ret , GFP_KERNEL );
534
+ if (!ret )
535
+ return NULL ;
536
+
537
+ ret -> com .res_id = id ;
538
+ ret -> com .state = RES_FS_RULE_ALLOCATED ;
539
+
540
+ return & ret -> com ;
541
+ }
542
+
519
543
static struct res_common * alloc_tr (u64 id , enum mlx4_resource type , int slave ,
520
544
int extra )
521
545
{
@@ -549,6 +573,9 @@ static struct res_common *alloc_tr(u64 id, enum mlx4_resource type, int slave,
549
573
case RES_XRCD :
550
574
ret = alloc_xrcdn_tr (id );
551
575
break ;
576
+ case RES_FS_RULE :
577
+ ret = alloc_fs_rule_tr (id );
578
+ break ;
552
579
default :
553
580
return NULL ;
554
581
}
@@ -681,6 +708,16 @@ static int remove_xrcdn_ok(struct res_xrcdn *res)
681
708
return 0 ;
682
709
}
683
710
711
+ static int remove_fs_rule_ok (struct res_fs_rule * res )
712
+ {
713
+ if (res -> com .state == RES_FS_RULE_BUSY )
714
+ return - EBUSY ;
715
+ else if (res -> com .state != RES_FS_RULE_ALLOCATED )
716
+ return - EPERM ;
717
+
718
+ return 0 ;
719
+ }
720
+
684
721
static int remove_cq_ok (struct res_cq * res )
685
722
{
686
723
if (res -> com .state == RES_CQ_BUSY )
@@ -722,6 +759,8 @@ static int remove_ok(struct res_common *res, enum mlx4_resource type, int extra)
722
759
return remove_counter_ok ((struct res_counter * )res );
723
760
case RES_XRCD :
724
761
return remove_xrcdn_ok ((struct res_xrcdn * )res );
762
+ case RES_FS_RULE :
763
+ return remove_fs_rule_ok ((struct res_fs_rule * )res );
725
764
default :
726
765
return - EINVAL ;
727
766
}
@@ -2744,14 +2783,28 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
2744
2783
struct mlx4_cmd_mailbox * outbox ,
2745
2784
struct mlx4_cmd_info * cmd )
2746
2785
{
2786
+ int err ;
2787
+
2747
2788
if (dev -> caps .steering_mode !=
2748
2789
MLX4_STEERING_MODE_DEVICE_MANAGED )
2749
2790
return - EOPNOTSUPP ;
2750
- return mlx4_cmd_imm (dev , inbox -> dma , & vhcr -> out_param ,
2751
- vhcr -> in_modifier , 0 ,
2752
- MLX4_QP_FLOW_STEERING_ATTACH ,
2753
- MLX4_CMD_TIME_CLASS_A ,
2754
- MLX4_CMD_NATIVE );
2791
+
2792
+ err = mlx4_cmd_imm (dev , inbox -> dma , & vhcr -> out_param ,
2793
+ vhcr -> in_modifier , 0 ,
2794
+ MLX4_QP_FLOW_STEERING_ATTACH , MLX4_CMD_TIME_CLASS_A ,
2795
+ MLX4_CMD_NATIVE );
2796
+ if (err )
2797
+ return err ;
2798
+
2799
+ err = add_res_range (dev , slave , vhcr -> out_param , 1 , RES_FS_RULE , 0 );
2800
+ if (err ) {
2801
+ mlx4_err (dev , "Fail to add flow steering resources.\n " );
2802
+ /* detach rule*/
2803
+ mlx4_cmd (dev , vhcr -> out_param , 0 , 0 ,
2804
+ MLX4_QP_FLOW_STEERING_ATTACH , MLX4_CMD_TIME_CLASS_A ,
2805
+ MLX4_CMD_NATIVE );
2806
+ }
2807
+ return err ;
2755
2808
}
2756
2809
2757
2810
int mlx4_QP_FLOW_STEERING_DETACH_wrapper (struct mlx4_dev * dev , int slave ,
@@ -2760,12 +2813,22 @@ int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev *dev, int slave,
2760
2813
struct mlx4_cmd_mailbox * outbox ,
2761
2814
struct mlx4_cmd_info * cmd )
2762
2815
{
2816
+ int err ;
2817
+
2763
2818
if (dev -> caps .steering_mode !=
2764
2819
MLX4_STEERING_MODE_DEVICE_MANAGED )
2765
2820
return - EOPNOTSUPP ;
2766
- return mlx4_cmd (dev , vhcr -> in_param , 0 , 0 ,
2767
- MLX4_QP_FLOW_STEERING_DETACH , MLX4_CMD_TIME_CLASS_A ,
2768
- MLX4_CMD_NATIVE );
2821
+
2822
+ err = rem_res_range (dev , slave , vhcr -> in_param , 1 , RES_FS_RULE , 0 );
2823
+ if (err ) {
2824
+ mlx4_err (dev , "Fail to remove flow steering resources.\n " );
2825
+ return err ;
2826
+ }
2827
+
2828
+ err = mlx4_cmd (dev , vhcr -> in_param , 0 , 0 ,
2829
+ MLX4_QP_FLOW_STEERING_DETACH , MLX4_CMD_TIME_CLASS_A ,
2830
+ MLX4_CMD_NATIVE );
2831
+ return err ;
2769
2832
}
2770
2833
2771
2834
enum {
@@ -3177,6 +3240,58 @@ static void rem_slave_mtts(struct mlx4_dev *dev, int slave)
3177
3240
spin_unlock_irq (mlx4_tlock (dev ));
3178
3241
}
3179
3242
3243
+ static void rem_slave_fs_rule (struct mlx4_dev * dev , int slave )
3244
+ {
3245
+ struct mlx4_priv * priv = mlx4_priv (dev );
3246
+ struct mlx4_resource_tracker * tracker =
3247
+ & priv -> mfunc .master .res_tracker ;
3248
+ struct list_head * fs_rule_list =
3249
+ & tracker -> slave_list [slave ].res_list [RES_FS_RULE ];
3250
+ struct res_fs_rule * fs_rule ;
3251
+ struct res_fs_rule * tmp ;
3252
+ int state ;
3253
+ u64 base ;
3254
+ int err ;
3255
+
3256
+ err = move_all_busy (dev , slave , RES_FS_RULE );
3257
+ if (err )
3258
+ mlx4_warn (dev , "rem_slave_fs_rule: Could not move all mtts to busy for slave %d\n" ,
3259
+ slave );
3260
+
3261
+ spin_lock_irq (mlx4_tlock (dev ));
3262
+ list_for_each_entry_safe (fs_rule , tmp , fs_rule_list , com .list ) {
3263
+ spin_unlock_irq (mlx4_tlock (dev ));
3264
+ if (fs_rule -> com .owner == slave ) {
3265
+ base = fs_rule -> com .res_id ;
3266
+ state = fs_rule -> com .from_state ;
3267
+ while (state != 0 ) {
3268
+ switch (state ) {
3269
+ case RES_FS_RULE_ALLOCATED :
3270
+ /* detach rule */
3271
+ err = mlx4_cmd (dev , base , 0 , 0 ,
3272
+ MLX4_QP_FLOW_STEERING_DETACH ,
3273
+ MLX4_CMD_TIME_CLASS_A ,
3274
+ MLX4_CMD_NATIVE );
3275
+
3276
+ spin_lock_irq (mlx4_tlock (dev ));
3277
+ rb_erase (& fs_rule -> com .node ,
3278
+ & tracker -> res_tree [RES_FS_RULE ]);
3279
+ list_del (& fs_rule -> com .list );
3280
+ spin_unlock_irq (mlx4_tlock (dev ));
3281
+ kfree (fs_rule );
3282
+ state = 0 ;
3283
+ break ;
3284
+
3285
+ default :
3286
+ state = 0 ;
3287
+ }
3288
+ }
3289
+ }
3290
+ spin_lock_irq (mlx4_tlock (dev ));
3291
+ }
3292
+ spin_unlock_irq (mlx4_tlock (dev ));
3293
+ }
3294
+
3180
3295
static void rem_slave_eqs (struct mlx4_dev * dev , int slave )
3181
3296
{
3182
3297
struct mlx4_priv * priv = mlx4_priv (dev );
@@ -3318,5 +3433,6 @@ void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave)
3318
3433
rem_slave_mtts (dev , slave );
3319
3434
rem_slave_counters (dev , slave );
3320
3435
rem_slave_xrcdns (dev , slave );
3436
+ rem_slave_fs_rule (dev , slave );
3321
3437
mutex_unlock (& priv -> mfunc .master .res_tracker .slave_list [slave ].mutex );
3322
3438
}
0 commit comments