static void u32_destroy(struct tcf_proto *tp, bool rtnl_held,
			struct netlink_ext_ack *extack)
{
	struct tc_u_common *tp_c = tp->data;
	struct tc_u_hnode *root_ht = rtnl_dereference(tp->root);

	WARN_ON(root_ht == NULL);

	if (root_ht && --root_ht->refcnt == 1)
		u32_destroy_hnode(tp, root_ht, extack);

	if (--tp_c->refcnt == 0) {
		struct tc_u_hnode *ht;

		hlist_del(&tp_c->hnode);

		while ((ht = rtnl_dereference(tp_c->hlist)) != NULL) {
			u32_clear_hnode(tp, ht, extack);
			RCU_INIT_POINTER(tp_c->hlist, ht->next);

			/* u32_destroy_key() will later free ht for us, if it's
			 * still referenced by some knode
			 */
			if (--ht->refcnt == 0)
				kfree_rcu(ht, rcu);
		}

		idr_destroy(&tp_c->handle_idr);
		kfree(tp_c);
	}

	tp->data = NULL;
}
static void u32_destroy(struct tcf_proto *tp, bool rtnl_held,
			struct netlink_ext_ack *extack)
{
	struct tc_u_common *tp_c = tp->data;
	struct tc_u_hnode *root_ht = rtnl_dereference(tp->root);

	WARN_ON(root_ht == NULL);

	if (root_ht && --root_ht->refcnt == 1)
		u32_destroy_hnode(tp, root_ht, extack);

	if (--tp_c->refcnt == 0) {
		struct tc_u_hnode *ht;

		hlist_del(&tp_c->hnode);

		while ((ht = rtnl_dereference(tp_c->hlist)) != NULL) {
			u32_clear_hnode(tp, ht, extack);
			RCU_INIT_POINTER(tp_c->hlist, ht->next);

			 
			if (--ht->refcnt == 0)
				kfree_rcu(ht, rcu);
		}

		idr_destroy(&tp_c->handle_idr);
		kfree(tp_c);
	}

	tp->data = NULL;
}