From: Nogah Frankel <nog...@mellanox.com>

Offloaded qdiscs are allowed to expose only parts of their statistics.
It means that if backlog is being exposed and qlen is not, it might trigger
a warning in qdisc_tree_reduce_backlog.
Do not warn in case the qdisc that was removed was an offloaded one.

Signed-off-by: Nogah Frankel <nog...@mellanox.com>
Reviewed-by: Yuval Mintz <yuv...@mellanox.com>
Signed-off-by: Jiri Pirko <j...@mellanox.com>
---
 net/sched/sch_api.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 27e672c12492..68f9d942bed4 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -739,6 +739,7 @@ static u32 qdisc_alloc_handle(struct net_device *dev)
 void qdisc_tree_reduce_backlog(struct Qdisc *sch, unsigned int n,
                               unsigned int len)
 {
+       bool qdisc_is_offloaded = sch->flags & TCQ_F_OFFLOADED;
        const struct Qdisc_class_ops *cops;
        unsigned long cl;
        u32 parentid;
@@ -760,8 +761,12 @@ void qdisc_tree_reduce_backlog(struct Qdisc *sch, unsigned 
int n,
                 * If child was empty even before update then backlog
                 * counter is screwed and we skip notification because
                 * parent class is already passive.
+                *
+                * If the original child was offloaded then it is allowed
+                * to be seem as empty, so the parent is notified anyway.
                 */
-               notify = !sch->q.qlen && !WARN_ON_ONCE(!n);
+               notify = !sch->q.qlen && !WARN_ON_ONCE(!n &&
+                                                      !qdisc_is_offloaded);
                /* TODO: perform the search on a per txq basis */
                sch = qdisc_lookup(qdisc_dev(sch), TC_H_MAJ(parentid));
                if (sch == NULL) {
-- 
2.14.3

Reply via email to