[Devel] [PATCH RH7] sock: allow reading and changing sk_userlocks with setsockopt

Pavel Tikhomirov ptikhomirov at virtuozzo.com
Thu Jul 29 17:28:56 MSK 2021


SOCK_SNDBUF_LOCK and SOCK_RCVBUF_LOCK flags disable automatic socket
buffers adjustment done by kernel (see tcp_fixup_rcvbuf() and
tcp_sndbuf_expand()). If we've just created a new socket this adjustment
is enabled on it, but if one changes the socket buffer size by
setsockopt(SO_{SND,RCV}BUF*) it becomes disabled.

CRIU needs to call setsockopt(SO_{SND,RCV}BUF*) on each socket on
restore as it first needs to increase buffer sizes for packet queues
restore and second it needs to restore back original buffer sizes. So
after CRIU restore all sockets become non-auto-adjustable, which can
decrease network perfomance of dumped applications significantly.

CRIU need to be able to restore sockets with enabled/disabled adjustment
to the same state it was before dump, so let's add special setsockopt
for it.

Notes:
- Use big number for SO_BUF_LOCK - 1072 in mainstream current available
number is 72, but we better not use it to exclude later compatibility
problems;
- For several arch-es like alpha, mips, parisc and sparc we need to
separately define setsockopt numbers, but as Virtuozzo is x86_64 only
we can skip them.

https://jira.sw.ru/browse/PSBM-131580

Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
This also need to go to VZ8 kernel.
---
 include/uapi/asm-generic/socket.h |  2 ++
 net/core/sock.c                   | 10 ++++++++++
 2 files changed, 12 insertions(+)

diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h
index aa97305f500e..39680b80dcd9 100644
--- a/include/uapi/asm-generic/socket.h
+++ b/include/uapi/asm-generic/socket.h
@@ -84,4 +84,6 @@
 
 #define SCM_TIMESTAMPING_PKTINFO	58
 
+#define SO_BUF_LOCK		1072
+
 #endif /* __ASM_GENERIC_SOCKET_H */
diff --git a/net/core/sock.c b/net/core/sock.c
index 44e91c8c0f0a..0b2f95de7494 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1029,6 +1029,13 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
 					 sk->sk_max_pacing_rate);
 		break;
 
+	case SO_BUF_LOCK:
+		val = val & (SOCK_SNDBUF_LOCK | SOCK_RCVBUF_LOCK);
+		sk->sk_userlocks = (sk->sk_userlocks &
+				    ~(SOCK_SNDBUF_LOCK | SOCK_RCVBUF_LOCK))
+				   | val;
+		break;
+
 	default:
 		ret = -ENOPROTOOPT;
 		break;
@@ -1285,6 +1292,9 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
 	case SO_MAX_PACING_RATE:
 		v.val = sk->sk_max_pacing_rate;
 		break;
+	case SO_BUF_LOCK:
+		v.val = sk->sk_userlocks & (SOCK_SNDBUF_LOCK | SOCK_RCVBUF_LOCK);
+		break;
 
 	default:
 		return -ENOPROTOOPT;
-- 
2.31.1



More information about the Devel mailing list