• Vladimir Oltean's avatar
    net: dsa: sja1105: bring deferred xmit implementation in line with ocelot-8021q · d38049bb
    Vladimir Oltean authored
    When the ocelot-8021q driver was converted to deferred xmit as part of
    commit 8d5f7954 ("net: dsa: felix: break at first CPU port during
    init and teardown"), the deferred implementation was deliberately made
    subtly different from what sja1105 has.
    
    The implementation differences lied on the following observations:
    
    - There might be a race between these two lines in tag_sja1105.c:
    
           skb_queue_tail(&sp->xmit_queue, skb_get(skb));
           kthread_queue_work(sp->xmit_worker, &sp->xmit_work);
    
      and the skb dequeue logic in sja1105_port_deferred_xmit(). For
      example, the xmit_work might be already queued, however the work item
      has just finished walking through the skb queue. Because we don't
      check the return code from kthread_queue_work, we don't do anything if
      the work item is already queued.
    
      However, nobody will take that skb and send it, at least until the
      next timestampable skb is sent. This creates additional (and
      avoidable) TX timestamping latency.
    
      To close that race, what the ocelot-8021q driver does is it doesn't
      keep a single work item per port, and a skb timestamping queue, but
      rather dynamically allocates a work item per packet.
    
    - It is also unnecessary to have more than one kthread that does the
      work. So delete the per-port kthread allocations and replace them with
      a single kthread which is global to the switch.
    
    This change brings the two implementations in line by applying those
    observations to the sja1105 driver as well.
    Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    d38049bb
sja1105_main.c 97 KB