Skip to content

Commit

Permalink
net: sched: cls_u32: simplify the hell out u32_delete() emptiness check
Browse files Browse the repository at this point in the history
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: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Al Viro authored and David S. Miller committed Oct 8, 2018
1 parent b245d32 commit a030598
Showing 1 changed file with 1 addition and 47 deletions.
48 changes: 1 addition & 47 deletions net/sched/cls_u32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}

Expand Down

0 comments on commit a030598

Please sign in to comment.