• Vladimir Oltean's avatar
    net: dsa: felix: drop oversized frames with tc-taprio instead of hanging the port · 55a515b1
    Vladimir Oltean authored
    Currently, sending a packet into a time gate too small for it (or always
    closed) causes the queue system to hold the frame forever. Even worse,
    this frame isn't subject to aging either, because for that to happen, it
    needs to be scheduled for transmission in the first place. But the frame
    will consume buffer memory and frame references while it is forever held
    in the queue system.
    
    Before commit a4ae997a ("net: mscc: ocelot: initialize watermarks to
    sane defaults"), this behavior was somewhat subtle, as the switch had a
    more intricately tuned default watermark configuration out of reset,
    which did not allow any single port and tc to consume the entire switch
    buffer space. Nonetheless, the held frames are still there, and they
    reduce the total backplane capacity of the switch.
    
    However, after the aforementioned commit, the behavior can be very
    clearly seen, since we deliberately allow each {port, tc} to consume the
    entire shared buffer of the switch minus the reservations (and we
    disable all reservations by default). That is to say, we allow a
    permanently closed tc-taprio gate to hang the entire switch.
    
    A careful inspection of the documentation shows that the QSYS:Q_MAX_SDU
    per-port-tc registers serve 2 purposes: one is for guard band calculation
    (when zero, this falls back to QSYS:PORT_MAX_SDU), and the other is to
    enable oversized frame dropping (when non-zero).
    
    Currently the QSYS:Q_MAX_SDU registers are all zero, so oversized frame
    dropping is disabled. The goal of the change is to enable it seamlessly.
    For that, we need to hook into the MTU change, tc-taprio change, and
    port link speed change procedures, since we depend on these variables.
    
    Frames are not dropped on egress due to a queue system oversize
    condition, instead that egress port is simply excluded from the mask of
    valid destination ports for the packet. If there are no destination
    ports at all, the ingress counter that increments is the generic
    "drop_tail" in ethtool -S.
    
    The issue exists in various forms since the tc-taprio offload was introduced.
    
    Fixes: de143c0e ("net: dsa: felix: Configure Time-Aware Scheduler via taprio offload")
    Reported-by: default avatarRichie Pearn <richard.pearn@nxp.com>
    Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
    Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
    55a515b1
felix.h 3.37 KB