net_sched: remove tc class reference counting
For TC classes, their ->get() and ->put() are always paired, and the reference counting is completely useless, because: 1) For class modification and dumping paths, we already hold RTNL lock, so all of these ->get(),->change(),->put() are atomic. 2) For filter bindiing/unbinding, we use other reference counter than this one, and they should have RTNL lock too. 3) For ->qlen_notify(), it is special because it is called on ->enqueue() path, but we already hold qdisc tree lock there, and we hold this tree lock when graft or delete the class too, so it should not be gone or changed until we release the tree lock. Therefore, this patch removes ->get() and ->put(), but: 1) Adds a new ->find() to find the pointer to a class by classid, no refcnt. 2) Move the original class destroy upon the last refcnt into ->delete(), right after releasing tree lock. This is fine because the class is already removed from hash when holding the lock. For those who also use ->put() as ->unbind(), just rename them to reflect this change. Cc: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> Acked-by: Jiri Pirko <jiri@mellanox.com> Acked-by: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
14546ba1e5
commit
143976ce99
@@ -586,7 +586,7 @@ replay:
|
||||
|
||||
/* Do we search for filter, attached to class? */
|
||||
if (TC_H_MIN(parent)) {
|
||||
cl = cops->get(q, parent);
|
||||
cl = cops->find(q, parent);
|
||||
if (cl == 0)
|
||||
return -ENOENT;
|
||||
}
|
||||
@@ -716,8 +716,6 @@ replay:
|
||||
errout:
|
||||
if (chain)
|
||||
tcf_chain_put(chain);
|
||||
if (cl)
|
||||
cops->put(q, cl);
|
||||
if (err == -EAGAIN)
|
||||
/* Replay the request. */
|
||||
goto replay;
|
||||
@@ -822,17 +820,17 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
goto out;
|
||||
cops = q->ops->cl_ops;
|
||||
if (!cops)
|
||||
goto errout;
|
||||
goto out;
|
||||
if (!cops->tcf_block)
|
||||
goto errout;
|
||||
goto out;
|
||||
if (TC_H_MIN(tcm->tcm_parent)) {
|
||||
cl = cops->get(q, tcm->tcm_parent);
|
||||
cl = cops->find(q, tcm->tcm_parent);
|
||||
if (cl == 0)
|
||||
goto errout;
|
||||
goto out;
|
||||
}
|
||||
block = cops->tcf_block(q, cl);
|
||||
if (!block)
|
||||
goto errout;
|
||||
goto out;
|
||||
|
||||
index_start = cb->args[0];
|
||||
index = 0;
|
||||
@@ -847,9 +845,6 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
|
||||
cb->args[0] = index;
|
||||
|
||||
errout:
|
||||
if (cl)
|
||||
cops->put(q, cl);
|
||||
out:
|
||||
return skb->len;
|
||||
}
|
||||
|
Reference in New Issue
Block a user