static void filter_rm_dtor(struct efrm_resource_manager *rm) { EFRM_TRACE("%s:", __func__); EFRM_RESOURCE_MANAGER_ASSERT_VALID(&efrm_filter_manager->rm); EFRM_ASSERT(&efrm_filter_manager->rm == rm); kfifo_vfree(efrm_filter_manager->free_ids); EFRM_TRACE("%s: done", __func__); }
int efrm_filter_resource_alloc(struct vi_resource *vi_parent, struct filter_resource **frs_out) { struct filter_resource *frs; int rc, instance; EFRM_ASSERT(frs_out); EFRM_ASSERT(efrm_filter_manager); EFRM_RESOURCE_MANAGER_ASSERT_VALID(&efrm_filter_manager->rm); EFRM_ASSERT(vi_parent != NULL); EFRM_ASSERT(EFRM_RESOURCE_TYPE(vi_parent->rs.rs_handle) == EFRM_RESOURCE_VI); /* Allocate resource data structure. This is called in atomic * context by the onload driver. */ frs = kmalloc(sizeof(struct filter_resource), GFP_ATOMIC); if (!frs) return -ENOMEM; /* Allocate an instance. */ rc = kfifo_get(efrm_filter_manager->free_ids, (unsigned char *)&instance, sizeof(instance)); if (rc != sizeof(instance)) { EFRM_TRACE("%s: out of instances", __FUNCTION__); EFRM_ASSERT(rc == 0); rc = -EBUSY; goto fail1; } /* Initialise the resource DS. */ efrm_resource_init(&frs->rs, EFRM_RESOURCE_FILTER, instance); frs->pt = vi_parent; efrm_resource_ref(&frs->pt->rs); frs->filter_idx = -1; EFRM_TRACE("%s: " EFRM_RESOURCE_FMT " VI %d", __FUNCTION__, EFRM_RESOURCE_PRI_ARG(frs->rs.rs_handle), EFRM_RESOURCE_INSTANCE(vi_parent->rs.rs_handle)); efrm_client_add_resource(vi_parent->rs.rs_client, &frs->rs); *frs_out = frs; return 0; fail1: memset(frs, 0, sizeof(*frs)); kfree(frs); return rc; }