• Yunsheng Lin's avatar
    net: sched: fix tx action reschedule issue with stopped queue · dcad9ee9
    Yunsheng Lin authored
    The netdev qeueue might be stopped when byte queue limit has
    reached or tx hw ring is full, net_tx_action() may still be
    rescheduled if STATE_MISSED is set, which consumes unnecessary
    cpu without dequeuing and transmiting any skb because the
    netdev queue is stopped, see qdisc_run_end().
    
    This patch fixes it by checking the netdev queue state before
    calling qdisc_run() and clearing STATE_MISSED if netdev queue is
    stopped during qdisc_run(), the net_tx_action() is rescheduled
    again when netdev qeueue is restarted, see netif_tx_wake_queue().
    
    As there is time window between netif_xmit_frozen_or_stopped()
    checking and STATE_MISSED clearing, between which STATE_MISSED
    may set by net_tx_action() scheduled by netif_tx_wake_queue(),
    so set the STATE_MISSED again if netdev queue is restarted.
    
    Fixes: 6b3ba914 ("net: sched: allow qdiscs to handle locking")
    Reported-by: default avatarMichal Kubecek <mkubecek@suse.cz>
    Acked-by: default avatarJakub Kicinski <kuba@kernel.org>
    Signed-off-by: default avatarYunsheng Lin <linyunsheng@huawei.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    dcad9ee9
sch_generic.c 34.8 KB