]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - net/sched/sch_red.c
net: sched: Move to new offload indication in RED
[mirror_ubuntu-bionic-kernel.git] / net / sched / sch_red.c
index 9d874e60e0323dee6bb7410b0ec34186eaac19d7..f0747eb87dc4784e67e0b5872dcf37effaaa4060 100644 (file)
@@ -157,6 +157,7 @@ static int red_offload(struct Qdisc *sch, bool enable)
                .handle = sch->handle,
                .parent = sch->parent,
        };
+       int err;
 
        if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc)
                return -EOPNOTSUPP;
@@ -171,7 +172,14 @@ static int red_offload(struct Qdisc *sch, bool enable)
                opt.command = TC_RED_DESTROY;
        }
 
-       return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED, &opt);
+       err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED, &opt);
+
+       if (!err && enable)
+               sch->flags |= TCQ_F_OFFLOADED;
+       else
+               sch->flags &= ~TCQ_F_OFFLOADED;
+
+       return err;
 }
 
 static void red_destroy(struct Qdisc *sch)
@@ -274,7 +282,7 @@ static int red_init(struct Qdisc *sch, struct nlattr *opt)
        return red_change(sch, opt);
 }
 
-static int red_dump_offload(struct Qdisc *sch, struct tc_red_qopt *opt)
+static int red_dump_offload_stats(struct Qdisc *sch, struct tc_red_qopt *opt)
 {
        struct net_device *dev = qdisc_dev(sch);
        struct tc_red_qopt_offload hw_stats = {
@@ -286,21 +294,12 @@ static int red_dump_offload(struct Qdisc *sch, struct tc_red_qopt *opt)
                        .stats.qstats = &sch->qstats,
                },
        };
-       int err;
 
-       opt->flags &= ~TC_RED_OFFLOADED;
-       if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc)
-               return 0;
-
-       err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED,
-                                           &hw_stats);
-       if (err == -EOPNOTSUPP)
+       if (!(sch->flags & TCQ_F_OFFLOADED))
                return 0;
 
-       if (!err)
-               opt->flags |= TC_RED_OFFLOADED;
-
-       return err;
+       return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED,
+                                            &hw_stats);
 }
 
 static int red_dump(struct Qdisc *sch, struct sk_buff *skb)
@@ -319,7 +318,7 @@ static int red_dump(struct Qdisc *sch, struct sk_buff *skb)
        int err;
 
        sch->qstats.backlog = q->qdisc->qstats.backlog;
-       err = red_dump_offload(sch, &opt);
+       err = red_dump_offload_stats(sch, &opt);
        if (err)
                goto nla_put_failure;
 
@@ -347,7 +346,7 @@ static int red_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
                .marked = q->stats.prob_mark + q->stats.forced_mark,
        };
 
-       if (tc_can_offload(dev) &&  dev->netdev_ops->ndo_setup_tc) {
+       if (sch->flags & TCQ_F_OFFLOADED) {
                struct red_stats hw_stats = {0};
                struct tc_red_qopt_offload hw_stats_request = {
                        .command = TC_RED_XSTATS,