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