mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-23 23:46:09 +07:00
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 <yishaih@mellanox.com> Signed-off-by: Raed Salem <raeds@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:
parent
7eea23a5cd
commit
b6ba4a9aa5
@ -263,6 +263,7 @@ struct ib_uverbs_flow_spec {
|
|||||||
struct ib_uverbs_flow_spec_action_tag flow_tag;
|
struct ib_uverbs_flow_spec_action_tag flow_tag;
|
||||||
struct ib_uverbs_flow_spec_action_drop drop;
|
struct ib_uverbs_flow_spec_action_drop drop;
|
||||||
struct ib_uverbs_flow_spec_action_handle action;
|
struct ib_uverbs_flow_spec_action_handle action;
|
||||||
|
struct ib_uverbs_flow_spec_action_count flow_count;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2742,43 +2742,82 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
|
|||||||
struct ib_uflow_resources {
|
struct ib_uflow_resources {
|
||||||
size_t max;
|
size_t max;
|
||||||
size_t num;
|
size_t num;
|
||||||
struct ib_flow_action *collection[0];
|
size_t collection_num;
|
||||||
|
size_t counters_num;
|
||||||
|
struct ib_counters **counters;
|
||||||
|
struct ib_flow_action **collection;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ib_uflow_resources *flow_resources_alloc(size_t num_specs)
|
static struct ib_uflow_resources *flow_resources_alloc(size_t num_specs)
|
||||||
{
|
{
|
||||||
struct ib_uflow_resources *resources;
|
struct ib_uflow_resources *resources;
|
||||||
|
|
||||||
resources =
|
resources = kzalloc(sizeof(*resources), GFP_KERNEL);
|
||||||
kmalloc(sizeof(*resources) +
|
|
||||||
num_specs * sizeof(*resources->collection), GFP_KERNEL);
|
|
||||||
|
|
||||||
if (!resources)
|
if (!resources)
|
||||||
return NULL;
|
goto err_res;
|
||||||
|
|
||||||
|
resources->counters =
|
||||||
|
kcalloc(num_specs, sizeof(*resources->counters), GFP_KERNEL);
|
||||||
|
|
||||||
|
if (!resources->counters)
|
||||||
|
goto err_cnt;
|
||||||
|
|
||||||
|
resources->collection =
|
||||||
|
kcalloc(num_specs, sizeof(*resources->collection), GFP_KERNEL);
|
||||||
|
|
||||||
|
if (!resources->collection)
|
||||||
|
goto err_collection;
|
||||||
|
|
||||||
resources->num = 0;
|
|
||||||
resources->max = num_specs;
|
resources->max = num_specs;
|
||||||
|
|
||||||
return resources;
|
return resources;
|
||||||
|
|
||||||
|
err_collection:
|
||||||
|
kfree(resources->counters);
|
||||||
|
err_cnt:
|
||||||
|
kfree(resources);
|
||||||
|
err_res:
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ib_uverbs_flow_resources_free(struct ib_uflow_resources *uflow_res)
|
void ib_uverbs_flow_resources_free(struct ib_uflow_resources *uflow_res)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < uflow_res->num; i++)
|
for (i = 0; i < uflow_res->collection_num; i++)
|
||||||
atomic_dec(&uflow_res->collection[i]->usecnt);
|
atomic_dec(&uflow_res->collection[i]->usecnt);
|
||||||
|
|
||||||
|
for (i = 0; i < uflow_res->counters_num; i++)
|
||||||
|
atomic_dec(&uflow_res->counters[i]->usecnt);
|
||||||
|
|
||||||
|
kfree(uflow_res->collection);
|
||||||
|
kfree(uflow_res->counters);
|
||||||
kfree(uflow_res);
|
kfree(uflow_res);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flow_resources_add(struct ib_uflow_resources *uflow_res,
|
static void flow_resources_add(struct ib_uflow_resources *uflow_res,
|
||||||
struct ib_flow_action *action)
|
enum ib_flow_spec_type type,
|
||||||
|
void *ibobj)
|
||||||
{
|
{
|
||||||
WARN_ON(uflow_res->num >= uflow_res->max);
|
WARN_ON(uflow_res->num >= uflow_res->max);
|
||||||
|
|
||||||
atomic_inc(&action->usecnt);
|
switch (type) {
|
||||||
uflow_res->collection[uflow_res->num++] = action;
|
case IB_FLOW_SPEC_ACTION_HANDLE:
|
||||||
|
atomic_inc(&((struct ib_flow_action *)ibobj)->usecnt);
|
||||||
|
uflow_res->collection[uflow_res->collection_num++] =
|
||||||
|
(struct ib_flow_action *)ibobj;
|
||||||
|
break;
|
||||||
|
case IB_FLOW_SPEC_ACTION_COUNT:
|
||||||
|
atomic_inc(&((struct ib_counters *)ibobj)->usecnt);
|
||||||
|
uflow_res->counters[uflow_res->counters_num++] =
|
||||||
|
(struct ib_counters *)ibobj;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
WARN_ON(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
uflow_res->num++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kern_spec_to_ib_spec_action(struct ib_ucontext *ucontext,
|
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,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
ib_spec->action.size =
|
ib_spec->action.size =
|
||||||
sizeof(struct ib_flow_spec_action_handle);
|
sizeof(struct ib_flow_spec_action_handle);
|
||||||
flow_resources_add(uflow_res, ib_spec->action.act);
|
flow_resources_add(uflow_res,
|
||||||
|
IB_FLOW_SPEC_ACTION_HANDLE,
|
||||||
|
ib_spec->action.act);
|
||||||
uobj_put_obj_read(ib_spec->action.act);
|
uobj_put_obj_read(ib_spec->action.act);
|
||||||
break;
|
break;
|
||||||
|
case IB_FLOW_SPEC_ACTION_COUNT:
|
||||||
|
if (kern_spec->flow_count.size !=
|
||||||
|
sizeof(struct ib_uverbs_flow_spec_action_count))
|
||||||
|
return -EINVAL;
|
||||||
|
ib_spec->flow_count.counters =
|
||||||
|
uobj_get_obj_read(counters,
|
||||||
|
UVERBS_OBJECT_COUNTERS,
|
||||||
|
kern_spec->flow_count.handle,
|
||||||
|
ucontext);
|
||||||
|
if (!ib_spec->flow_count.counters)
|
||||||
|
return -EINVAL;
|
||||||
|
ib_spec->flow_count.size =
|
||||||
|
sizeof(struct ib_flow_spec_action_count);
|
||||||
|
flow_resources_add(uflow_res,
|
||||||
|
IB_FLOW_SPEC_ACTION_COUNT,
|
||||||
|
ib_spec->flow_count.counters);
|
||||||
|
uobj_put_obj_read(ib_spec->flow_count.counters);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -998,6 +998,19 @@ struct ib_uverbs_flow_spec_action_handle {
|
|||||||
__u32 reserved1;
|
__u32 reserved1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ib_uverbs_flow_spec_action_count {
|
||||||
|
union {
|
||||||
|
struct ib_uverbs_flow_spec_hdr hdr;
|
||||||
|
struct {
|
||||||
|
__u32 type;
|
||||||
|
__u16 size;
|
||||||
|
__u16 reserved;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
__u32 handle;
|
||||||
|
__u32 reserved1;
|
||||||
|
};
|
||||||
|
|
||||||
struct ib_uverbs_flow_tunnel_filter {
|
struct ib_uverbs_flow_tunnel_filter {
|
||||||
__be32 tunnel_id;
|
__be32 tunnel_id;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user