On 12/21/2016 9:03 AM, Cong Wang wrote:
On Tue, Dec 20, 2016 at 10:44 PM, Shahar Klein <shah...@mellanox.com> wrote:
Tried it with same results
This piece is pretty interesting:
[ 408.554689] DEBUGG:SK thread-2853[cpu-1] setting tp_created to 1
tp=ffff94b5b02805a0 back=ffff94b9ea932060
[ 408.574258] DEBUGG:SK thread-2853[cpu-1] add/change filter by:
fl_get [cls_flower] tp=ffff94b5b02805a0 tp->next=ffff94b9ea932060
[ 408.587849] DEBUGG:SK destroy ffff94b5b0280780 tcf_destroy:1905
[ 408.595862] DEBUGG:SK thread-2845[cpu-1] add/change filter by:
fl_get [cls_flower] tp=ffff94b5b02805a0 tp->next=ffff94b5b02805a0
Looks like you added a debug printk inside tcf_destroy() too,
which seems racy with filter creation, it should not happen since
in both cases we take RTNL lock.
Don't know if changing all RCU_INIT_POINTER in that file to
rcu_assign_pointer could help anything or not. Mind to try?
Tried it with same results
Thanks for debugging!
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 3fbba79..b8a66d8 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -305,7 +305,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct
nlmsghdr *n)
kfree(tp);
goto errout;
}
-
+ printk(KERN_ERR "DEBUGG:SK thread-%d[cpu-%d] setting tp_created
to 1 tp=%p back=%p\n", current->pid, current->on_cpu, tp,
rtnl_dereference(*back));
tp_created = 1;
} else if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], tp->ops->kind))
@@ -317,11 +317,13 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct
nlmsghdr *n)
if (n->nlmsg_type == RTM_DELTFILTER && t->tcm_handle == 0) {
struct tcf_proto *next = rtnl_dereference(tp->next);
- RCU_INIT_POINTER(*back, next);
+ printk(KERN_ERR "DEBUGG:SK delete filter by: %pf\n",
tp->ops->get);
+
+ rcu_assign_pointer(*back, next);
tfilter_notify(net, skb, n, tp, fh,
RTM_DELTFILTER, false);
- tcf_destroy(tp, true);
+ tcf_destroy(tp);
err = 0;
goto errout;
}
@@ -331,25 +333,30 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct
nlmsghdr *n)
!(n->nlmsg_flags & NLM_F_CREATE))
goto errout;
} else {
+ bool last;
+
switch (n->nlmsg_type) {
case RTM_NEWTFILTER:
err = -EEXIST;
if (n->nlmsg_flags & NLM_F_EXCL) {
if (tp_created)
- tcf_destroy(tp, true);
+ tcf_destroy(tp);
goto errout;
}
break;
case RTM_DELTFILTER:
- err = tp->ops->delete(tp, fh);
+ printk(KERN_ERR "DEBUGG:SK %s:%d\n", __func__,
__LINE__);
+ err = tp->ops->delete(tp, fh, &last);
if (err == 0) {
- struct tcf_proto *next =
rtnl_dereference(tp->next);
-
tfilter_notify(net, skb, n, tp,
t->tcm_handle,
RTM_DELTFILTER, false);
- if (tcf_destroy(tp, false))
- RCU_INIT_POINTER(*back, next);
+ if (last) {
+ struct tcf_proto *next =
rtnl_dereference(tp->next);
+
+ rcu_assign_pointer(*back, next);
+ tcf_destroy(tp);
+ }
}
goto errout;
case RTM_GETTFILTER:
@@ -366,13 +373,14 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct
nlmsghdr *n)
n->nlmsg_flags & NLM_F_CREATE ? TCA_ACT_NOREPLACE
: TCA_ACT_REPLACE);
if (err == 0) {
if (tp_created) {
- RCU_INIT_POINTER(tp->next, rtnl_dereference(*back));
+ rcu_assign_pointer(tp->next, rtnl_dereference(*back));
rcu_assign_pointer(*back, tp);
+ printk(KERN_ERR "DEBUGG:SK thread-%d[cpu-%d] add/change
filter by: %pf tp=%p tp->next=%p\n", current->pid, current->on_cpu,
tp->ops->get, tp, tp->next);
}
tfilter_notify(net, skb, n, tp, fh, RTM_NEWTFILTER, false);
} else {
if (tp_created)
- tcf_destroy(tp, true);
+ tcf_destroy(tp);
}
errout: