static void __pfq_group_free(int gid) { struct pfq_group * g = pfq_get_group(gid); struct sk_filter *filter; struct pfq_computation_tree *old_comp; void *old_ctx; if (!g) { pr_devel("[PFQ] get_group: invalid group id %d!\n", gid); return; } /* remove this gid from demux matrix */ pfq_devmap_update(map_reset, Q_ANY_DEVICE, Q_ANY_QUEUE, gid); g->pid = 0; g->owner = -1; g->policy = Q_POLICY_GROUP_UNDEFINED; filter = (struct sk_filter *)atomic_long_xchg(&g->bp_filter, 0L); old_comp = (struct pfq_computation_tree *)atomic_long_xchg(&g->comp, 0L); old_ctx = (void *)atomic_long_xchg(&g->comp_ctx, 0L); msleep(Q_GRACE_PERIOD); /* sleeping is possible here: user-context */ /* call fini on old computation */ if (old_comp) pfq_computation_fini(old_comp); kfree(old_comp); kfree(old_ctx); if (filter) pfq_free_sk_filter(filter); g->vlan_filt = false; pr_devel("[PFQ] group id:%d destroyed.\n", gid); }
static void __pfq_group_dtor(int gid) { struct pfq_group * that = &pfq_groups[gid]; void *context[Q_FUN_MAX]; struct sk_filter *filter; int i; /* remove this gid from demux matrix */ pfq_devmap_update(map_reset, Q_ANY_DEVICE, Q_ANY_QUEUE, gid); that->pid = 0; that->policy = Q_GROUP_UNDEFINED; for(i = 0; i < Q_FUN_MAX; i++) { atomic_long_set(&pfq_groups[gid].fun_ctx[i].function, 0L); context[i] = (void *)atomic_long_xchg(&pfq_groups[gid].fun_ctx[i].context, 0L); } filter = (struct sk_filter *)atomic_long_xchg(&pfq_groups[gid].filter, 0L); msleep(Q_GRACE_PERIOD); /* sleeping is possible here: user-context */ for(i = 0; i < Q_FUN_MAX; i++) { kfree(context[i]); } pfq_free_sk_filter(filter); that->vlan_filt = false; pr_devel("[PFQ] group id:%d destroyed.\n", gid); }