lkml.org 
[lkml]   [2018]   [Nov]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 4.18 047/350] xsk: do not call synchronize_net() under RCU read lock
Date
4.18-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Björn Töpel <bjorn.topel@intel.com>

[ Upstream commit cee271678d0e3177a25d0fcb2fa5e051d48e4262 ]

The XSKMAP update and delete functions called synchronize_net(), which
can sleep. It is not allowed to sleep during an RCU read section.

Instead we need to make sure that the sock sk_destruct (xsk_destruct)
function is asynchronously called after an RCU grace period. Setting
the SOCK_RCU_FREE flag for XDP sockets takes care of this.

Fixes: fbfc504a24f5 ("bpf: introduce new bpf AF_XDP map type BPF_MAP_TYPE_XSKMAP")
Reported-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Björn Töpel <bjorn.topel@intel.com>
Acked-by: Song Liu <songliubraving@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/bpf/xskmap.c | 10 ++--------
net/xdp/xsk.c | 2 ++
2 files changed, 4 insertions(+), 8 deletions(-)

--- a/kernel/bpf/xskmap.c
+++ b/kernel/bpf/xskmap.c
@@ -191,11 +191,8 @@ static int xsk_map_update_elem(struct bp
sock_hold(sock->sk);

old_xs = xchg(&m->xsk_map[i], xs);
- if (old_xs) {
- /* Make sure we've flushed everything. */
- synchronize_net();
+ if (old_xs)
sock_put((struct sock *)old_xs);
- }

sockfd_put(sock);
return 0;
@@ -211,11 +208,8 @@ static int xsk_map_delete_elem(struct bp
return -EINVAL;

old_xs = xchg(&m->xsk_map[k], NULL);
- if (old_xs) {
- /* Make sure we've flushed everything. */
- synchronize_net();
+ if (old_xs)
sock_put((struct sock *)old_xs);
- }

return 0;
}
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -744,6 +744,8 @@ static int xsk_create(struct net *net, s
sk->sk_destruct = xsk_destruct;
sk_refcnt_debug_inc(sk);

+ sock_set_flag(sk, SOCK_RCU_FREE);
+
xs = xdp_sk(sk);
mutex_init(&xs->mutex);
spin_lock_init(&xs->tx_completion_lock);

\
 
 \ /
  Last update: 2018-11-12 00:42    [W:1.251 / U:0.100 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site