On 01/15/2018 06:24 PM, Daniel Borkmann via iovisor-dev wrote: > On 01/11/2018 07:05 AM, Sandipan Das via iovisor-dev wrote: > [...] >> Any ideas about why this is happening? Also, it would be really helpful >> if someone can translate the Pyroute2 calls in the test script to the >> corresponding tc commands. > > I can trigger it as well, so I should have something very soon; currently > looking into it.
Here's the fix for your panic ... cooking up proper patch with commit description for netdev now: >From 126dd0c1ecb7c207f79976c6c3ef13be08afe6b5 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann <[email protected]> Date: Mon, 15 Jan 2018 19:48:28 +0000 Subject: [PATCH net] net, sched: fix miniq {b,q}stats handling Signed-off-by: Daniel Borkmann <[email protected]> --- net/sched/sch_api.c | 38 +++++++++++++++++++------------------- net/sched/sch_ingress.c | 17 ++--------------- 2 files changed, 21 insertions(+), 34 deletions(-) diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 0f1eab9..1593f81 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -1034,7 +1034,7 @@ static struct Qdisc *qdisc_create(struct net_device *dev, sch->parent = parent; if (handle == TC_H_INGRESS) { - sch->flags |= TCQ_F_INGRESS; + sch->flags |= TCQ_F_INGRESS | TCQ_F_CPUSTATS; handle = TC_H_MAKE(TC_H_INGRESS, 0); lockdep_set_class(qdisc_lock(sch), &qdisc_rx_lock); } else { @@ -1062,23 +1062,22 @@ static struct Qdisc *qdisc_create(struct net_device *dev, netdev_info(dev, "Caught tx_queue_len zero misconfig\n"); } - if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS])) == 0) { - if (qdisc_is_percpu_stats(sch)) { - sch->cpu_bstats = - netdev_alloc_pcpu_stats(struct gnet_stats_basic_cpu); - if (!sch->cpu_bstats) - goto err_out4; - - sch->cpu_qstats = alloc_percpu(struct gnet_stats_queue); - if (!sch->cpu_qstats) - goto err_out4; - } + if (qdisc_is_percpu_stats(sch)) { + sch->cpu_bstats = netdev_alloc_pcpu_stats(struct gnet_stats_basic_cpu); + if (!sch->cpu_bstats) + goto err_out4; + + sch->cpu_qstats = alloc_percpu(struct gnet_stats_queue); + if (!sch->cpu_qstats) + goto err_out4; + } + if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS])) == 0) { if (tca[TCA_STAB]) { stab = qdisc_get_stab(tca[TCA_STAB]); if (IS_ERR(stab)) { err = PTR_ERR(stab); - goto err_out4; + goto err_out5; } rcu_assign_pointer(sch->stab, stab); } @@ -1087,7 +1086,7 @@ static struct Qdisc *qdisc_create(struct net_device *dev, err = -EOPNOTSUPP; if (sch->flags & TCQ_F_MQROOT) - goto err_out4; + goto err_out5; if ((sch->parent != TC_H_ROOT) && !(sch->flags & TCQ_F_INGRESS) && @@ -1103,7 +1102,7 @@ static struct Qdisc *qdisc_create(struct net_device *dev, running, tca[TCA_RATE]); if (err) - goto err_out4; + goto err_out5; } qdisc_hash_add(sch, false); @@ -1113,6 +1112,9 @@ static struct Qdisc *qdisc_create(struct net_device *dev, /* ops->init() failed, we call ->destroy() like qdisc_create_dflt() */ if (ops->destroy) ops->destroy(sch); +err_out4: + free_percpu(sch->cpu_bstats); + free_percpu(sch->cpu_qstats); err_out3: dev_put(dev); kfree((char *) sch - sch->padded); @@ -1122,9 +1124,7 @@ static struct Qdisc *qdisc_create(struct net_device *dev, *errp = err; return NULL; -err_out4: - free_percpu(sch->cpu_bstats); - free_percpu(sch->cpu_qstats); +err_out5: /* * Any broken qdiscs that would require a ops->reset() here? * The qdisc was never in action so it shouldn't be necessary. @@ -1132,7 +1132,7 @@ static struct Qdisc *qdisc_create(struct net_device *dev, qdisc_put_stab(rtnl_dereference(sch->stab)); if (ops->destroy) ops->destroy(sch); - goto err_out3; + goto err_out4; } static int qdisc_change(struct Qdisc *sch, struct nlattr **tca) diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c index fc1286f..3cb2b25 100644 --- a/net/sched/sch_ingress.c +++ b/net/sched/sch_ingress.c @@ -66,7 +66,6 @@ static int ingress_init(struct Qdisc *sch, struct nlattr *opt) { struct ingress_sched_data *q = qdisc_priv(sch); struct net_device *dev = qdisc_dev(sch); - int err; net_inc_ingress_queue(); @@ -76,13 +75,7 @@ static int ingress_init(struct Qdisc *sch, struct nlattr *opt) q->block_info.chain_head_change = clsact_chain_head_change; q->block_info.chain_head_change_priv = &q->miniqp; - err = tcf_block_get_ext(&q->block, sch, &q->block_info); - if (err) - return err; - - sch->flags |= TCQ_F_CPUSTATS; - - return 0; + return tcf_block_get_ext(&q->block, sch, &q->block_info); } static void ingress_destroy(struct Qdisc *sch) @@ -192,13 +185,7 @@ static int clsact_init(struct Qdisc *sch, struct nlattr *opt) q->egress_block_info.chain_head_change = clsact_chain_head_change; q->egress_block_info.chain_head_change_priv = &q->miniqp_egress; - err = tcf_block_get_ext(&q->egress_block, sch, &q->egress_block_info); - if (err) - return err; - - sch->flags |= TCQ_F_CPUSTATS; - - return 0; + return tcf_block_get_ext(&q->egress_block, sch, &q->egress_block_info); } static void clsact_destroy(struct Qdisc *sch) -- 2.9.5 _______________________________________________ iovisor-dev mailing list [email protected] https://lists.iovisor.org/mailman/listinfo/iovisor-dev
