@@ -2742,43 +2742,82 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
2742
2742
struct ib_uflow_resources {
2743
2743
size_t max ;
2744
2744
size_t num ;
2745
- struct ib_flow_action * collection [0 ];
2745
+ size_t collection_num ;
2746
+ size_t counters_num ;
2747
+ struct ib_counters * * counters ;
2748
+ struct ib_flow_action * * collection ;
2746
2749
};
2747
2750
2748
2751
static struct ib_uflow_resources * flow_resources_alloc (size_t num_specs )
2749
2752
{
2750
2753
struct ib_uflow_resources * resources ;
2751
2754
2752
- resources =
2753
- kmalloc (sizeof (* resources ) +
2754
- num_specs * sizeof (* resources -> collection ), GFP_KERNEL );
2755
+ resources = kzalloc (sizeof (* resources ), GFP_KERNEL );
2755
2756
2756
2757
if (!resources )
2757
- return NULL ;
2758
+ goto err_res ;
2759
+
2760
+ resources -> counters =
2761
+ kcalloc (num_specs , sizeof (* resources -> counters ), GFP_KERNEL );
2762
+
2763
+ if (!resources -> counters )
2764
+ goto err_cnt ;
2765
+
2766
+ resources -> collection =
2767
+ kcalloc (num_specs , sizeof (* resources -> collection ), GFP_KERNEL );
2768
+
2769
+ if (!resources -> collection )
2770
+ goto err_collection ;
2758
2771
2759
- resources -> num = 0 ;
2760
2772
resources -> max = num_specs ;
2761
2773
2762
2774
return resources ;
2775
+
2776
+ err_collection :
2777
+ kfree (resources -> counters );
2778
+ err_cnt :
2779
+ kfree (resources );
2780
+ err_res :
2781
+ return NULL ;
2763
2782
}
2764
2783
2765
2784
void ib_uverbs_flow_resources_free (struct ib_uflow_resources * uflow_res )
2766
2785
{
2767
2786
unsigned int i ;
2768
2787
2769
- for (i = 0 ; i < uflow_res -> num ; i ++ )
2788
+ for (i = 0 ; i < uflow_res -> collection_num ; i ++ )
2770
2789
atomic_dec (& uflow_res -> collection [i ]-> usecnt );
2771
2790
2791
+ for (i = 0 ; i < uflow_res -> counters_num ; i ++ )
2792
+ atomic_dec (& uflow_res -> counters [i ]-> usecnt );
2793
+
2794
+ kfree (uflow_res -> collection );
2795
+ kfree (uflow_res -> counters );
2772
2796
kfree (uflow_res );
2773
2797
}
2774
2798
2775
2799
static void flow_resources_add (struct ib_uflow_resources * uflow_res ,
2776
- struct ib_flow_action * action )
2800
+ enum ib_flow_spec_type type ,
2801
+ void * ibobj )
2777
2802
{
2778
2803
WARN_ON (uflow_res -> num >= uflow_res -> max );
2779
2804
2780
- atomic_inc (& action -> usecnt );
2781
- uflow_res -> collection [uflow_res -> num ++ ] = action ;
2805
+ switch (type ) {
2806
+ case IB_FLOW_SPEC_ACTION_HANDLE :
2807
+ atomic_inc (& ((struct ib_flow_action * )ibobj )-> usecnt );
2808
+ uflow_res -> collection [uflow_res -> collection_num ++ ] =
2809
+ (struct ib_flow_action * )ibobj ;
2810
+ break ;
2811
+ case IB_FLOW_SPEC_ACTION_COUNT :
2812
+ atomic_inc (& ((struct ib_counters * )ibobj )-> usecnt );
2813
+ uflow_res -> counters [uflow_res -> counters_num ++ ] =
2814
+ (struct ib_counters * )ibobj ;
2815
+ break ;
2816
+ default :
2817
+ WARN_ON (1 );
2818
+ }
2819
+
2820
+ uflow_res -> num ++ ;
2782
2821
}
2783
2822
2784
2823
static int kern_spec_to_ib_spec_action (struct ib_ucontext * ucontext ,
@@ -2815,9 +2854,29 @@ static int kern_spec_to_ib_spec_action(struct ib_ucontext *ucontext,
2815
2854
return - EINVAL ;
2816
2855
ib_spec -> action .size =
2817
2856
sizeof (struct ib_flow_spec_action_handle );
2818
- flow_resources_add (uflow_res , ib_spec -> action .act );
2857
+ flow_resources_add (uflow_res ,
2858
+ IB_FLOW_SPEC_ACTION_HANDLE ,
2859
+ ib_spec -> action .act );
2819
2860
uobj_put_obj_read (ib_spec -> action .act );
2820
2861
break ;
2862
+ case IB_FLOW_SPEC_ACTION_COUNT :
2863
+ if (kern_spec -> flow_count .size !=
2864
+ sizeof (struct ib_uverbs_flow_spec_action_count ))
2865
+ return - EINVAL ;
2866
+ ib_spec -> flow_count .counters =
2867
+ uobj_get_obj_read (counters ,
2868
+ UVERBS_OBJECT_COUNTERS ,
2869
+ kern_spec -> flow_count .handle ,
2870
+ ucontext );
2871
+ if (!ib_spec -> flow_count .counters )
2872
+ return - EINVAL ;
2873
+ ib_spec -> flow_count .size =
2874
+ sizeof (struct ib_flow_spec_action_count );
2875
+ flow_resources_add (uflow_res ,
2876
+ IB_FLOW_SPEC_ACTION_COUNT ,
2877
+ ib_spec -> flow_count .counters );
2878
+ uobj_put_obj_read (ib_spec -> flow_count .counters );
2879
+ break ;
2821
2880
default :
2822
2881
return - EINVAL ;
2823
2882
}
0 commit comments