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