Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a0305986 authored by Al Viro's avatar Al Viro Committed by David S. Miller
Browse files

net: sched: cls_u32: simplify the hell out u32_delete() emptiness check



Now that we have the knode count, we can instantly check if
any hnodes are non-empty.  And that kills the check for extra
references to root hnode - those could happen only if there was
a knode to carry such a link.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarJamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b245d32c
Loading
Loading
Loading
Loading
+1 −47
Original line number Diff line number Diff line
@@ -627,17 +627,6 @@ static int u32_destroy_hnode(struct tcf_proto *tp, struct tc_u_hnode *ht,
	return -ENOENT;
}

static bool ht_empty(struct tc_u_hnode *ht)
{
	unsigned int h;

	for (h = 0; h <= ht->divisor; h++)
		if (rcu_access_pointer(ht->ht[h]))
			return false;

	return true;
}

static void u32_destroy(struct tcf_proto *tp, struct netlink_ext_ack *extack)
{
	struct tc_u_common *tp_c = tp->data;
@@ -675,13 +664,9 @@ static int u32_delete(struct tcf_proto *tp, void *arg, bool *last,
		      struct netlink_ext_ack *extack)
{
	struct tc_u_hnode *ht = arg;
	struct tc_u_hnode *root_ht = rtnl_dereference(tp->root);
	struct tc_u_common *tp_c = tp->data;
	int ret = 0;

	if (ht == NULL)
		goto out;

	if (TC_U32_KEY(ht->handle)) {
		u32_remove_hw_knode(tp, (struct tc_u_knode *)ht, extack);
		ret = u32_delete_key(tp, (struct tc_u_knode *)ht);
@@ -702,38 +687,7 @@ static int u32_delete(struct tcf_proto *tp, void *arg, bool *last,
	}

out:
	*last = true;
	if (root_ht) {
		if (root_ht->refcnt > 1) {
			*last = false;
			goto ret;
		}
		if (root_ht->refcnt == 1) {
			if (!ht_empty(root_ht)) {
				*last = false;
				goto ret;
			}
		}
	}

	if (tp_c->refcnt > 1) {
		*last = false;
		goto ret;
	}

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

		for (ht = rtnl_dereference(tp_c->hlist);
		     ht;
		     ht = rtnl_dereference(ht->next))
			if (!ht_empty(ht)) {
				*last = false;
				break;
			}
	}

ret:
	*last = tp_c->refcnt == 1 && tp_c->knodes == 0;
	return ret;
}