lkml.org 
[lkml]   [2021]   [Jul]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.10 085/167] net/tcp_fastopen: fix data races around tfo_active_disable_stamp
    Date
    From: Eric Dumazet <edumazet@google.com>

    [ Upstream commit 6f20c8adb1813467ea52c1296d52c4e95978cb2f ]

    tfo_active_disable_stamp is read and written locklessly.
    We need to annotate these accesses appropriately.

    Then, we need to perform the atomic_inc(tfo_active_disable_times)
    after the timestamp has been updated, and thus add barriers
    to make sure tcp_fastopen_active_should_disable() wont read
    a stale timestamp.

    Fixes: cf1ef3f0719b ("net/tcp_fastopen: Disable active side TFO in certain scenarios")
    Signed-off-by: Eric Dumazet <edumazet@google.com>
    Cc: Wei Wang <weiwan@google.com>
    Cc: Yuchung Cheng <ycheng@google.com>
    Cc: Neal Cardwell <ncardwell@google.com>
    Acked-by: Wei Wang <weiwan@google.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    net/ipv4/tcp_fastopen.c | 19 ++++++++++++++++---
    1 file changed, 16 insertions(+), 3 deletions(-)

    diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
    index af2814c9342a..08548ff23d83 100644
    --- a/net/ipv4/tcp_fastopen.c
    +++ b/net/ipv4/tcp_fastopen.c
    @@ -507,8 +507,15 @@ void tcp_fastopen_active_disable(struct sock *sk)
    {
    struct net *net = sock_net(sk);

    + /* Paired with READ_ONCE() in tcp_fastopen_active_should_disable() */
    + WRITE_ONCE(net->ipv4.tfo_active_disable_stamp, jiffies);
    +
    + /* Paired with smp_rmb() in tcp_fastopen_active_should_disable().
    + * We want net->ipv4.tfo_active_disable_stamp to be updated first.
    + */
    + smp_mb__before_atomic();
    atomic_inc(&net->ipv4.tfo_active_disable_times);
    - net->ipv4.tfo_active_disable_stamp = jiffies;
    +
    NET_INC_STATS(net, LINUX_MIB_TCPFASTOPENBLACKHOLE);
    }

    @@ -526,10 +533,16 @@ bool tcp_fastopen_active_should_disable(struct sock *sk)
    if (!tfo_da_times)
    return false;

    + /* Paired with smp_mb__before_atomic() in tcp_fastopen_active_disable() */
    + smp_rmb();
    +
    /* Limit timout to max: 2^6 * initial timeout */
    multiplier = 1 << min(tfo_da_times - 1, 6);
    - timeout = multiplier * tfo_bh_timeout * HZ;
    - if (time_before(jiffies, sock_net(sk)->ipv4.tfo_active_disable_stamp + timeout))
    +
    + /* Paired with the WRITE_ONCE() in tcp_fastopen_active_disable(). */
    + timeout = READ_ONCE(sock_net(sk)->ipv4.tfo_active_disable_stamp) +
    + multiplier * tfo_bh_timeout * HZ;
    + if (time_before(jiffies, timeout))
    return true;

    /* Mark check bit so we can check for successful active TFO
    --
    2.30.2


    \
     
     \ /
      Last update: 2021-07-26 18:43    [W:3.584 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site