static int nft_rcv_nl_event(struct notifier_block *this, unsigned long event,
			    void *ptr)
{
	struct nft_table *table, *to_delete[8];
	struct nftables_pernet *nft_net;
	struct netlink_notify *n = ptr;
	struct net *net = n->net;
	unsigned int deleted;
	bool restart = false;

	if (event != NETLINK_URELEASE || n->protocol != NETLINK_NETFILTER)
		return NOTIFY_DONE;

	nft_net = nft_pernet(net);
	deleted = 0;
	mutex_lock(&nft_net->commit_mutex);
again:
	list_for_each_entry(table, &nft_net->tables, list) {
		if (nft_table_has_owner(table) &&
		    n->portid == table->nlpid) {
			__nft_release_hook(net, table);
			list_del_rcu(&table->list);
			to_delete[deleted++] = table;
			if (deleted >= ARRAY_SIZE(to_delete))
				break;
		}
	}
	if (deleted) {
		restart = deleted >= ARRAY_SIZE(to_delete);
		synchronize_rcu();
		while (deleted)
			__nft_release_table(net, to_delete[--deleted]);

		if (restart)
			goto again;
	}
	mutex_unlock(&nft_net->commit_mutex);

	return NOTIFY_DONE;
}
static int nft_rcv_nl_event(struct notifier_block *this, unsigned long event,
			    void *ptr)
{
	struct nft_table *table, *to_delete[8];
	struct nftables_pernet *nft_net;
	struct netlink_notify *n = ptr;
	struct net *net = n->net;
	unsigned int deleted;
	bool restart = false;

	if (event != NETLINK_URELEASE || n->protocol != NETLINK_NETFILTER)
		return NOTIFY_DONE;

	nft_net = nft_pernet(net);
	deleted = 0;
	mutex_lock(&nft_net->commit_mutex);
again:
	list_for_each_entry(table, &nft_net->tables, list) {
		if (nft_table_has_owner(table) &&
		    n->portid == table->nlpid) {
			__nft_release_hook(net, table);
			list_del_rcu(&table->list);
			to_delete[deleted++] = table;
			if (deleted >= ARRAY_SIZE(to_delete))
				break;
		}
	}
	if (deleted) {
		restart = deleted >= ARRAY_SIZE(to_delete);
		synchronize_rcu();
		while (deleted)
			__nft_release_table(net, to_delete[--deleted]);

		if (restart)
			goto again;
	}
	mutex_unlock(&nft_net->commit_mutex);

	return NOTIFY_DONE;
}