mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-23 07:12:09 +00:00
net: rcu-ify tcf_proto
rcu'ify tcf_proto this allows calling tc_classify() without holding any locks. Updaters are protected by RTNL. This patch prepares the core net_sched infrastracture for running the classifier/action chains without holding the qdisc lock however it does nothing to ensure cls_xxx and act_xxx types also work without locking. Additional patches are required to address the fall out. Signed-off-by: John Fastabend <john.r.fastabend@intel.com> Acked-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
46e5da40ae
commit
25d8c0d55f
17 changed files with 121 additions and 88 deletions
|
@ -117,7 +117,6 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n)
|
|||
{
|
||||
struct net *net = sock_net(skb->sk);
|
||||
struct nlattr *tca[TCA_MAX + 1];
|
||||
spinlock_t *root_lock;
|
||||
struct tcmsg *t;
|
||||
u32 protocol;
|
||||
u32 prio;
|
||||
|
@ -125,7 +124,8 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n)
|
|||
u32 parent;
|
||||
struct net_device *dev;
|
||||
struct Qdisc *q;
|
||||
struct tcf_proto **back, **chain;
|
||||
struct tcf_proto __rcu **back;
|
||||
struct tcf_proto __rcu **chain;
|
||||
struct tcf_proto *tp;
|
||||
const struct tcf_proto_ops *tp_ops;
|
||||
const struct Qdisc_class_ops *cops;
|
||||
|
@ -197,7 +197,9 @@ replay:
|
|||
goto errout;
|
||||
|
||||
/* Check the chain for existence of proto-tcf with this priority */
|
||||
for (back = chain; (tp = *back) != NULL; back = &tp->next) {
|
||||
for (back = chain;
|
||||
(tp = rtnl_dereference(*back)) != NULL;
|
||||
back = &tp->next) {
|
||||
if (tp->prio >= prio) {
|
||||
if (tp->prio == prio) {
|
||||
if (!nprio ||
|
||||
|
@ -209,8 +211,6 @@ replay:
|
|||
}
|
||||
}
|
||||
|
||||
root_lock = qdisc_root_sleeping_lock(q);
|
||||
|
||||
if (tp == NULL) {
|
||||
/* Proto-tcf does not exist, create new one */
|
||||
|
||||
|
@ -259,7 +259,8 @@ replay:
|
|||
}
|
||||
tp->ops = tp_ops;
|
||||
tp->protocol = protocol;
|
||||
tp->prio = nprio ? : TC_H_MAJ(tcf_auto_prio(*back));
|
||||
tp->prio = nprio ? :
|
||||
TC_H_MAJ(tcf_auto_prio(rtnl_dereference(*back)));
|
||||
tp->q = q;
|
||||
tp->classify = tp_ops->classify;
|
||||
tp->classid = parent;
|
||||
|
@ -280,9 +281,9 @@ replay:
|
|||
|
||||
if (fh == 0) {
|
||||
if (n->nlmsg_type == RTM_DELTFILTER && t->tcm_handle == 0) {
|
||||
spin_lock_bh(root_lock);
|
||||
*back = tp->next;
|
||||
spin_unlock_bh(root_lock);
|
||||
struct tcf_proto *next = rtnl_dereference(tp->next);
|
||||
|
||||
RCU_INIT_POINTER(*back, next);
|
||||
|
||||
tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER);
|
||||
tcf_destroy(tp);
|
||||
|
@ -322,10 +323,8 @@ replay:
|
|||
n->nlmsg_flags & NLM_F_CREATE ? TCA_ACT_NOREPLACE : TCA_ACT_REPLACE);
|
||||
if (err == 0) {
|
||||
if (tp_created) {
|
||||
spin_lock_bh(root_lock);
|
||||
tp->next = *back;
|
||||
*back = tp;
|
||||
spin_unlock_bh(root_lock);
|
||||
RCU_INIT_POINTER(tp->next, rtnl_dereference(*back));
|
||||
rcu_assign_pointer(*back, tp);
|
||||
}
|
||||
tfilter_notify(net, skb, n, tp, fh, RTM_NEWTFILTER);
|
||||
} else {
|
||||
|
@ -420,7 +419,7 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
|
|||
int s_t;
|
||||
struct net_device *dev;
|
||||
struct Qdisc *q;
|
||||
struct tcf_proto *tp, **chain;
|
||||
struct tcf_proto *tp, __rcu **chain;
|
||||
struct tcmsg *tcm = nlmsg_data(cb->nlh);
|
||||
unsigned long cl = 0;
|
||||
const struct Qdisc_class_ops *cops;
|
||||
|
@ -454,7 +453,8 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
|
|||
|
||||
s_t = cb->args[0];
|
||||
|
||||
for (tp = *chain, t = 0; tp; tp = tp->next, t++) {
|
||||
for (tp = rtnl_dereference(*chain), t = 0;
|
||||
tp; tp = rtnl_dereference(tp->next), t++) {
|
||||
if (t < s_t)
|
||||
continue;
|
||||
if (TC_H_MAJ(tcm->tcm_info) &&
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue