lkml.org 
[lkml]   [2021]   [Jun]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.10 082/137] wireguard: use synchronize_net rather than synchronize_rcu
    Date
    From: Jason A. Donenfeld <Jason@zx2c4.com>

    commit 24b70eeeb4f46c09487f8155239ebfb1f875774a upstream.

    Many of the synchronization points are sometimes called under the rtnl
    lock, which means we should use synchronize_net rather than
    synchronize_rcu. Under the hood, this expands to using the expedited
    flavor of function in the event that rtnl is held, in order to not stall
    other concurrent changes.

    This fixes some very, very long delays when removing multiple peers at
    once, which would cause some operations to take several minutes.

    Fixes: e7096c131e51 ("net: WireGuard secure network tunnel")
    Cc: stable@vger.kernel.org
    Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/net/wireguard/peer.c | 6 +++---
    drivers/net/wireguard/socket.c | 2 +-
    2 files changed, 4 insertions(+), 4 deletions(-)

    --- a/drivers/net/wireguard/peer.c
    +++ b/drivers/net/wireguard/peer.c
    @@ -89,7 +89,7 @@ static void peer_make_dead(struct wg_pee
    /* Mark as dead, so that we don't allow jumping contexts after. */
    WRITE_ONCE(peer->is_dead, true);

    - /* The caller must now synchronize_rcu() for this to take effect. */
    + /* The caller must now synchronize_net() for this to take effect. */
    }

    static void peer_remove_after_dead(struct wg_peer *peer)
    @@ -161,7 +161,7 @@ void wg_peer_remove(struct wg_peer *peer
    lockdep_assert_held(&peer->device->device_update_lock);

    peer_make_dead(peer);
    - synchronize_rcu();
    + synchronize_net();
    peer_remove_after_dead(peer);
    }

    @@ -179,7 +179,7 @@ void wg_peer_remove_all(struct wg_device
    peer_make_dead(peer);
    list_add_tail(&peer->peer_list, &dead_peers);
    }
    - synchronize_rcu();
    + synchronize_net();
    list_for_each_entry_safe(peer, temp, &dead_peers, peer_list)
    peer_remove_after_dead(peer);
    }
    --- a/drivers/net/wireguard/socket.c
    +++ b/drivers/net/wireguard/socket.c
    @@ -430,7 +430,7 @@ void wg_socket_reinit(struct wg_device *
    if (new4)
    wg->incoming_port = ntohs(inet_sk(new4)->inet_sport);
    mutex_unlock(&wg->socket_update_lock);
    - synchronize_rcu();
    + synchronize_net();
    sock_free(old4);
    sock_free(old6);
    }

    \
     
     \ /
      Last update: 2021-06-08 21:32    [W:5.874 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site