Commit b245d32c authored by Al Viro's avatar Al Viro Committed by David S. Miller

net: sched: cls_u32: keep track of knodes count in tc_u_common

allows to simplify u32_delete() considerably
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 8a8065f6
...@@ -97,6 +97,7 @@ struct tc_u_common { ...@@ -97,6 +97,7 @@ struct tc_u_common {
int refcnt; int refcnt;
struct idr handle_idr; struct idr handle_idr;
struct hlist_node hnode; struct hlist_node hnode;
long knodes;
}; };
static inline unsigned int u32_hash_fold(__be32 key, static inline unsigned int u32_hash_fold(__be32 key,
...@@ -452,6 +453,7 @@ static void u32_delete_key_freepf_work(struct work_struct *work) ...@@ -452,6 +453,7 @@ static void u32_delete_key_freepf_work(struct work_struct *work)
static int u32_delete_key(struct tcf_proto *tp, struct tc_u_knode *key) static int u32_delete_key(struct tcf_proto *tp, struct tc_u_knode *key)
{ {
struct tc_u_common *tp_c = tp->data;
struct tc_u_knode __rcu **kp; struct tc_u_knode __rcu **kp;
struct tc_u_knode *pkp; struct tc_u_knode *pkp;
struct tc_u_hnode *ht = rtnl_dereference(key->ht_up); struct tc_u_hnode *ht = rtnl_dereference(key->ht_up);
...@@ -462,6 +464,7 @@ static int u32_delete_key(struct tcf_proto *tp, struct tc_u_knode *key) ...@@ -462,6 +464,7 @@ static int u32_delete_key(struct tcf_proto *tp, struct tc_u_knode *key)
kp = &pkp->next, pkp = rtnl_dereference(*kp)) { kp = &pkp->next, pkp = rtnl_dereference(*kp)) {
if (pkp == key) { if (pkp == key) {
RCU_INIT_POINTER(*kp, key->next); RCU_INIT_POINTER(*kp, key->next);
tp_c->knodes--;
tcf_unbind_filter(tp, &key->res); tcf_unbind_filter(tp, &key->res);
idr_remove(&ht->handle_idr, key->handle); idr_remove(&ht->handle_idr, key->handle);
...@@ -576,6 +579,7 @@ static int u32_replace_hw_knode(struct tcf_proto *tp, struct tc_u_knode *n, ...@@ -576,6 +579,7 @@ static int u32_replace_hw_knode(struct tcf_proto *tp, struct tc_u_knode *n,
static void u32_clear_hnode(struct tcf_proto *tp, struct tc_u_hnode *ht, static void u32_clear_hnode(struct tcf_proto *tp, struct tc_u_hnode *ht,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
struct tc_u_common *tp_c = tp->data;
struct tc_u_knode *n; struct tc_u_knode *n;
unsigned int h; unsigned int h;
...@@ -583,6 +587,7 @@ static void u32_clear_hnode(struct tcf_proto *tp, struct tc_u_hnode *ht, ...@@ -583,6 +587,7 @@ static void u32_clear_hnode(struct tcf_proto *tp, struct tc_u_hnode *ht,
while ((n = rtnl_dereference(ht->ht[h])) != NULL) { while ((n = rtnl_dereference(ht->ht[h])) != NULL) {
RCU_INIT_POINTER(ht->ht[h], RCU_INIT_POINTER(ht->ht[h],
rtnl_dereference(n->next)); rtnl_dereference(n->next));
tp_c->knodes--;
tcf_unbind_filter(tp, &n->res); tcf_unbind_filter(tp, &n->res);
u32_remove_hw_knode(tp, n, extack); u32_remove_hw_knode(tp, n, extack);
idr_remove(&ht->handle_idr, n->handle); idr_remove(&ht->handle_idr, n->handle);
...@@ -1141,6 +1146,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, ...@@ -1141,6 +1146,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
RCU_INIT_POINTER(n->next, pins); RCU_INIT_POINTER(n->next, pins);
rcu_assign_pointer(*ins, n); rcu_assign_pointer(*ins, n);
tp_c->knodes++;
*arg = n; *arg = n;
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment