• Joe Lawrence's avatar
    team: avoid race condition in scheduling delayed work · 47549650
    Joe Lawrence authored
    When team_notify_peers and team_mcast_rejoin are called, they both reset
    their respective .count_pending atomic variable. Then when the actual
    worker function is executed, the variable is atomically decremented.
    This pattern introduces a potential race condition where the
    .count_pending rolls over and the worker function keeps rescheduling
    until .count_pending decrements to zero again:
    
    THREAD 1                           THREAD 2
    
    ========                           ========
    team_notify_peers(teamX)
      atomic_set count_pending = 1
      schedule_delayed_work
                                       team_notify_peers(teamX)
                                       atomic_set count_pending = 1
    team_notify_peers_work
      atomic_dec_and_test
        count_pending = 0
      (return)
                                       schedule_delayed_work
                                       team_notify_peers_work
                                       atomic_dec_and_test
                                         count_pending = -1
                                       schedule_delayed_work
                                       (repeat until count_pending = 0)
    
    Instead of assigning a new value to .count_pending, use atomic_add to
    tack-on the additional desired worker function invocations.
    Signed-off-by: default avatarJoe Lawrence <joe.lawrence@stratus.com>
    Acked-by: default avatarJiri Pirko <jiri@resnulli.us>
    Fixes: fc423ff0 ("team: add peer notification")
    Fixes: 492b200e ("team: add support for sending multicast rejoins")
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    47549650
team.c 68.6 KB