• Vladimir Oltean's avatar
    net: dsa: felix: tc-taprio intervals smaller than MTU should send at least one packet · 11afdc65
    Vladimir Oltean authored
    The blamed commit broke tc-taprio schedules such as this one:
    
    tc qdisc replace dev $swp1 root taprio \
            num_tc 8 \
            map 0 1 2 3 4 5 6 7 \
            queues 1@0 1@1 1@2 1@3 1@4 1@5 1@6 1@7 \
            base-time 0 \
            sched-entry S 0x7f 990000 \
            sched-entry S 0x80  10000 \
            flags 0x2
    
    because the gate entry for TC 7 (S 0x80 10000 ns) now has a static guard
    band added earlier than its 'gate close' event, such that packet
    overruns won't occur in the worst case of the largest packet possible.
    
    Since guard bands are statically determined based on the per-tc
    QSYS_QMAXSDU_CFG_* with a fallback on the port-based QSYS_PORT_MAX_SDU,
    we need to discuss what happens with TC 7 depending on kernel version,
    since the driver, prior to commit 55a515b1 ("net: dsa: felix: drop
    oversized frames with tc-taprio instead of hanging the port"), did not
    touch QSYS_QMAXSDU_CFG_*, and therefore relied on QSYS_PORT_MAX_SDU.
    
    1 (before vsc9959_tas_guard_bands_update): QSYS_PORT_MAX_SDU defaults to
      1518, and at gigabit this introduces a static guard band (independent
      of packet sizes) of 12144 ns, plus QSYS::HSCH_MISC_CFG.FRM_ADJ (bit
      time of 20 octets => 160 ns). But this is larger than the time window
      itself, of 10000 ns. So, the queue system never considers a frame with
      TC 7 as eligible for transmission, since the gate practically never
      opens, and these frames are forever stuck in the TX queues and hang
      the port.
    
    2 (after vsc9959_tas_guard_bands_update): Under the sole goal of
      enabling oversized frame dropping, we make an effort to set
      QSYS_QMAXSDU_CFG_7 to 1230 bytes. But QSYS_QMAXSDU_CFG_7 plays
      one more role, which we did not take into account: per-tc static guard
      band, expressed in L2 byte time (auto-adjusted for FCS and L1 overhead).
      There is a discrepancy between what the driver thinks (that there is
      no guard band, and 100% of min_gate_len[tc] is available for egress
      scheduling) and what the hardware actually does (crops the equivalent
      of QSYS_QMAXSDU_CFG_7 ns out of min_gate_len[tc]). In practice, this
      means that the hardware thinks it has exactly 0 ns for scheduling tc 7.
    
    In both cases, even minimum sized Ethernet frames are stuck on egress
    rather than being considered for scheduling on TC 7, even if they would
    fit given a proper configuration. Considering the current situation,
    with vsc9959_tas_guard_bands_update(), frames between 60 octets and 1230
    octets in size are not eligible for oversized dropping (because they are
    smaller than QSYS_QMAXSDU_CFG_7), but won't be considered as eligible
    for scheduling either, because the min_gate_len[7] (10000 ns) minus the
    guard band determined by QSYS_QMAXSDU_CFG_7 (1230 octets * 8 ns per
    octet == 9840 ns) minus the guard band auto-added for L1 overhead by
    QSYS::HSCH_MISC_CFG.FRM_ADJ (20 octets * 8 ns per octet == 160 octets)
    leaves 0 ns for scheduling in the queue system proper.
    
    Investigating the hardware behavior, it becomes apparent that the queue
    system needs precisely 33 ns of 'gate open' time in order to consider a
    frame as eligible for scheduling to a tc. So the solution to this
    problem is to amend vsc9959_tas_guard_bands_update(), by giving the
    per-tc guard bands less space by exactly 33 ns, just enough for one
    frame to be scheduled in that interval. This allows the queue system to
    make forward progress for that port-tc, and prevents it from hanging.
    
    Fixes: 297c4de6 ("net: dsa: felix: re-enable TAS guard band mode")
    Reported-by: default avatarXiaoliang Yang <xiaoliang.yang_1@nxp.com>
    Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    11afdc65
felix_vsc9959.c 84.9 KB