Such helper does not cope correctly with NOLOCK qdiscs.
In the following patches we will move back qlen to per CPU
values for such qdiscs, so qdisc_qlen_sum() is not an option,
too.
Instead, use qlen only for lock qdiscs, and always set
flow off for NOLOCK qdiscs with a not empty tx queue.

Signed-off-by: Paolo Abeni <pab...@redhat.com>
---
 net/caif/caif_dev.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c
index 711d7156efd8..6c6e01963aac 100644
--- a/net/caif/caif_dev.c
+++ b/net/caif/caif_dev.c
@@ -186,15 +186,19 @@ static int transmit(struct cflayer *layer, struct cfpkt 
*pkt)
                goto noxoff;
 
        if (likely(!netif_queue_stopped(caifd->netdev))) {
+               struct Qdisc *sch;
+
                /* If we run with a TX queue, check if the queue is too long*/
                txq = netdev_get_tx_queue(skb->dev, 0);
-               qlen = qdisc_qlen(rcu_dereference_bh(txq->qdisc));
-
-               if (likely(qlen == 0))
+               sch = rcu_dereference_bh(txq->qdisc);
+               if (likely(qdisc_is_empty(sch)))
                        goto noxoff;
 
+               /* can check for explicit qdisc len value only !NOLOCK,
+                * always set flow off otherwise
+                */
                high = (caifd->netdev->tx_queue_len * q_high) / 100;
-               if (likely(qlen < high))
+               if (!(sch->flags & TCQ_F_NOLOCK) && likely(sch->q.qlen < high))
                        goto noxoff;
        }
 
-- 
2.20.1

Reply via email to