xref: /linux/drivers/infiniband/core/uverbs_flow.c (revision 9611c0ce215a66770ccbe5c126bf57ba8c31bcad)
1*9733e9f5SJason Gunthorpe // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2*9733e9f5SJason Gunthorpe #include "uverbs.h"
3*9733e9f5SJason Gunthorpe 
4*9733e9f5SJason Gunthorpe struct ib_uflow_resources *flow_resources_alloc(size_t num_specs)
5*9733e9f5SJason Gunthorpe {
6*9733e9f5SJason Gunthorpe 	struct ib_uflow_resources *resources;
7*9733e9f5SJason Gunthorpe 
8*9733e9f5SJason Gunthorpe 	resources = kzalloc_obj(*resources);
9*9733e9f5SJason Gunthorpe 
10*9733e9f5SJason Gunthorpe 	if (!resources)
11*9733e9f5SJason Gunthorpe 		return NULL;
12*9733e9f5SJason Gunthorpe 
13*9733e9f5SJason Gunthorpe 	if (!num_specs)
14*9733e9f5SJason Gunthorpe 		goto out;
15*9733e9f5SJason Gunthorpe 
16*9733e9f5SJason Gunthorpe 	resources->counters =
17*9733e9f5SJason Gunthorpe 		kzalloc_objs(*resources->counters, num_specs);
18*9733e9f5SJason Gunthorpe 	resources->collection =
19*9733e9f5SJason Gunthorpe 		kzalloc_objs(*resources->collection, num_specs);
20*9733e9f5SJason Gunthorpe 
21*9733e9f5SJason Gunthorpe 	if (!resources->counters || !resources->collection)
22*9733e9f5SJason Gunthorpe 		goto err;
23*9733e9f5SJason Gunthorpe 
24*9733e9f5SJason Gunthorpe out:
25*9733e9f5SJason Gunthorpe 	resources->max = num_specs;
26*9733e9f5SJason Gunthorpe 	return resources;
27*9733e9f5SJason Gunthorpe 
28*9733e9f5SJason Gunthorpe err:
29*9733e9f5SJason Gunthorpe 	kfree(resources->counters);
30*9733e9f5SJason Gunthorpe 	kfree(resources);
31*9733e9f5SJason Gunthorpe 
32*9733e9f5SJason Gunthorpe 	return NULL;
33*9733e9f5SJason Gunthorpe }
34*9733e9f5SJason Gunthorpe EXPORT_SYMBOL(flow_resources_alloc);
35*9733e9f5SJason Gunthorpe 
36*9733e9f5SJason Gunthorpe void ib_uverbs_flow_resources_free(struct ib_uflow_resources *uflow_res)
37*9733e9f5SJason Gunthorpe {
38*9733e9f5SJason Gunthorpe 	unsigned int i;
39*9733e9f5SJason Gunthorpe 
40*9733e9f5SJason Gunthorpe 	if (!uflow_res)
41*9733e9f5SJason Gunthorpe 		return;
42*9733e9f5SJason Gunthorpe 
43*9733e9f5SJason Gunthorpe 	for (i = 0; i < uflow_res->collection_num; i++)
44*9733e9f5SJason Gunthorpe 		atomic_dec(&uflow_res->collection[i]->usecnt);
45*9733e9f5SJason Gunthorpe 
46*9733e9f5SJason Gunthorpe 	for (i = 0; i < uflow_res->counters_num; i++)
47*9733e9f5SJason Gunthorpe 		atomic_dec(&uflow_res->counters[i]->usecnt);
48*9733e9f5SJason Gunthorpe 
49*9733e9f5SJason Gunthorpe 	kfree(uflow_res->collection);
50*9733e9f5SJason Gunthorpe 	kfree(uflow_res->counters);
51*9733e9f5SJason Gunthorpe 	kfree(uflow_res);
52*9733e9f5SJason Gunthorpe }
53*9733e9f5SJason Gunthorpe EXPORT_SYMBOL(ib_uverbs_flow_resources_free);
54*9733e9f5SJason Gunthorpe 
55*9733e9f5SJason Gunthorpe void flow_resources_add(struct ib_uflow_resources *uflow_res,
56*9733e9f5SJason Gunthorpe 			enum ib_flow_spec_type type,
57*9733e9f5SJason Gunthorpe 			void *ibobj)
58*9733e9f5SJason Gunthorpe {
59*9733e9f5SJason Gunthorpe 	WARN_ON(uflow_res->num >= uflow_res->max);
60*9733e9f5SJason Gunthorpe 
61*9733e9f5SJason Gunthorpe 	switch (type) {
62*9733e9f5SJason Gunthorpe 	case IB_FLOW_SPEC_ACTION_HANDLE:
63*9733e9f5SJason Gunthorpe 		atomic_inc(&((struct ib_flow_action *)ibobj)->usecnt);
64*9733e9f5SJason Gunthorpe 		uflow_res->collection[uflow_res->collection_num++] =
65*9733e9f5SJason Gunthorpe 			(struct ib_flow_action *)ibobj;
66*9733e9f5SJason Gunthorpe 		break;
67*9733e9f5SJason Gunthorpe 	case IB_FLOW_SPEC_ACTION_COUNT:
68*9733e9f5SJason Gunthorpe 		atomic_inc(&((struct ib_counters *)ibobj)->usecnt);
69*9733e9f5SJason Gunthorpe 		uflow_res->counters[uflow_res->counters_num++] =
70*9733e9f5SJason Gunthorpe 			(struct ib_counters *)ibobj;
71*9733e9f5SJason Gunthorpe 		break;
72*9733e9f5SJason Gunthorpe 	default:
73*9733e9f5SJason Gunthorpe 		WARN_ON(1);
74*9733e9f5SJason Gunthorpe 	}
75*9733e9f5SJason Gunthorpe 
76*9733e9f5SJason Gunthorpe 	uflow_res->num++;
77*9733e9f5SJason Gunthorpe }
78*9733e9f5SJason Gunthorpe EXPORT_SYMBOL(flow_resources_add);
79