Skip to content

Commit b6ba4a9

Browse files
Raed SalemLeon Romanovsky
authored andcommitted
IB/uverbs: Add support for flow counters
The struct ib_uverbs_flow_spec_action_count associates a counters object with the flow. Post this association the flow counters can be read via the counters object. Reviewed-by: Yishai Hadas <[email protected]> Signed-off-by: Raed Salem <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 7eea23a commit b6ba4a9

File tree

3 files changed

+84
-11
lines changed

3 files changed

+84
-11
lines changed

drivers/infiniband/core/uverbs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ struct ib_uverbs_flow_spec {
263263
struct ib_uverbs_flow_spec_action_tag flow_tag;
264264
struct ib_uverbs_flow_spec_action_drop drop;
265265
struct ib_uverbs_flow_spec_action_handle action;
266+
struct ib_uverbs_flow_spec_action_count flow_count;
266267
};
267268
};
268269

drivers/infiniband/core/uverbs_cmd.c

Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2742,43 +2742,82 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
27422742
struct ib_uflow_resources {
27432743
size_t max;
27442744
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;
27462749
};
27472750

27482751
static struct ib_uflow_resources *flow_resources_alloc(size_t num_specs)
27492752
{
27502753
struct ib_uflow_resources *resources;
27512754

2752-
resources =
2753-
kmalloc(sizeof(*resources) +
2754-
num_specs * sizeof(*resources->collection), GFP_KERNEL);
2755+
resources = kzalloc(sizeof(*resources), GFP_KERNEL);
27552756

27562757
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;
27582771

2759-
resources->num = 0;
27602772
resources->max = num_specs;
27612773

27622774
return resources;
2775+
2776+
err_collection:
2777+
kfree(resources->counters);
2778+
err_cnt:
2779+
kfree(resources);
2780+
err_res:
2781+
return NULL;
27632782
}
27642783

27652784
void ib_uverbs_flow_resources_free(struct ib_uflow_resources *uflow_res)
27662785
{
27672786
unsigned int i;
27682787

2769-
for (i = 0; i < uflow_res->num; i++)
2788+
for (i = 0; i < uflow_res->collection_num; i++)
27702789
atomic_dec(&uflow_res->collection[i]->usecnt);
27712790

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);
27722796
kfree(uflow_res);
27732797
}
27742798

27752799
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)
27772802
{
27782803
WARN_ON(uflow_res->num >= uflow_res->max);
27792804

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++;
27822821
}
27832822

27842823
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,
28152854
return -EINVAL;
28162855
ib_spec->action.size =
28172856
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);
28192860
uobj_put_obj_read(ib_spec->action.act);
28202861
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;
28212880
default:
28222881
return -EINVAL;
28232882
}

include/uapi/rdma/ib_user_verbs.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -998,6 +998,19 @@ struct ib_uverbs_flow_spec_action_handle {
998998
__u32 reserved1;
999999
};
10001000

1001+
struct ib_uverbs_flow_spec_action_count {
1002+
union {
1003+
struct ib_uverbs_flow_spec_hdr hdr;
1004+
struct {
1005+
__u32 type;
1006+
__u16 size;
1007+
__u16 reserved;
1008+
};
1009+
};
1010+
__u32 handle;
1011+
__u32 reserved1;
1012+
};
1013+
10011014
struct ib_uverbs_flow_tunnel_filter {
10021015
__be32 tunnel_id;
10031016
};

0 commit comments

Comments
 (0)