From e69be16db7deae018902b0ceb62db8eaf7b74437 Mon Sep 17 00:00:00 2001 From: Pavel Tikhomirov Date: Thu, 29 Jul 2021 11:27:13 +0300 Subject: [PATCH] sockets: c/r bufer size locks When one sets socket buffer sizes with setsockopt(SO_{SND,RCV}BUF*), kernel sets coresponding SOCK_SNDBUF_LOCK or SOCK_RCVBUF_LOCK flags on struct sock. It means that such a socket with explicitly changed buffer size can not be auto-adjusted by kernel (e.g. if there is free memory kernel can auto-increase default socket buffers to improve perfomance). (see tcp_fixup_rcvbuf() and tcp_sndbuf_expand()) CRIU is always changing buf sizes on restore, that means that all sockets receive lock flags on struct sock and become non-auto-adjusted after migration. In some cases it can decrease perfomance of network connections quite a lot. So let's c/r socket buf locks (SO_BUF_LOCKS), so that sockets for which auto-adjustment is available does not lose it. Reviewed-by: Alexander Mikhalitsyn Signed-off-by: Pavel Tikhomirov --- criu/sockets.c | 8 ++++++++ images/sk-opts.proto | 2 ++ 2 files changed, 10 insertions(+) diff --git a/criu/sockets.c b/criu/sockets.c index 65aa82950..db772707b 100644 --- a/criu/sockets.c +++ b/criu/sockets.c @@ -519,6 +519,10 @@ int restore_socket_opts(int sk, SkOptsEntry *soe) /* setsockopt() multiplies the input values by 2 */ ret |= userns_call(sk_setbufs, 0, bufs, sizeof(bufs), sk); + if (soe->has_so_buf_lock) { + pr_debug("\trestore buf_lock %d for socket\n", soe->so_buf_lock); + ret |= restore_opt(sk, SOL_SOCKET, SO_BUF_LOCK, &soe->so_buf_lock); + } if (soe->has_so_priority) { pr_debug("\trestore priority %d for socket\n", soe->so_priority); ret |= restore_opt(sk, SOL_SOCKET, SO_PRIORITY, &soe->so_priority); @@ -619,6 +623,10 @@ int dump_socket_opts(int sk, SkOptsEntry *soe) ret |= dump_opt(sk, SOL_SOCKET, SO_SNDBUF, &soe->so_sndbuf); ret |= dump_opt(sk, SOL_SOCKET, SO_RCVBUF, &soe->so_rcvbuf); + if (kdat.has_sockopt_buf_lock) { + soe->has_so_buf_lock = true; + ret |= dump_opt(sk, SOL_SOCKET, SO_BUF_LOCK, &soe->so_buf_lock); + } soe->has_so_priority = true; ret |= dump_opt(sk, SOL_SOCKET, SO_PRIORITY, &soe->so_priority); soe->has_so_rcvlowat = true; diff --git a/images/sk-opts.proto b/images/sk-opts.proto index 2377f6b62..1d24d47cc 100644 --- a/images/sk-opts.proto +++ b/images/sk-opts.proto @@ -31,6 +31,8 @@ message sk_opts_entry { optional uint32 tcp_keepintvl = 22; optional uint32 so_oobinline = 23; optional uint32 so_linger = 24; + + optional uint32 so_buf_lock = 25; } enum sk_shutdown {