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

Reply via email to