Commit 0f7dc697 authored by Jakub Kicinski's avatar Jakub Kicinski Committed by Ziyang Xuan
Browse files

tls: suppress wakeups unless we have a full record

mainline inclusion
from mainline-v6.5-rc1
commit 121dca78
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I8QSMO

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=121dca784fc0f6c022493a5d23d86b3cc20380f4



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

TLS does not override .poll() so TLS-enabled socket will generate
an event whenever data arrives at the TCP socket. This leads to
unnecessary wakeups on slow connections.

Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Conflicts:
	net/tls/tls_main.c
Signed-off-by: default avatarZiyang Xuan <william.xuanziyang@huawei.com>
parent 2380c87d
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -333,6 +333,39 @@ static void tls_sk_proto_close(struct sock *sk, long timeout)
		tls_ctx_free(sk, ctx);
}

static __poll_t tls_sk_poll(struct file *file, struct socket *sock,
			    struct poll_table_struct *wait)
{
	struct tls_sw_context_rx *ctx;
	struct tls_context *tls_ctx;
	struct sock *sk = sock->sk;
	struct sk_psock *psock;
	__poll_t mask = 0;
	u8 shutdown;
	int state;

	mask = tcp_poll(file, sock, wait);

	state = inet_sk_state_load(sk);
	shutdown = READ_ONCE(sk->sk_shutdown);
	if (unlikely(state != TCP_ESTABLISHED || shutdown & RCV_SHUTDOWN))
		return mask;

	tls_ctx = tls_get_ctx(sk);
	ctx = tls_sw_ctx_rx(tls_ctx);
	psock = sk_psock_get(sk);

	if (skb_queue_empty_lockless(&ctx->rx_list) &&
	    (ctx->recv_pkt == NULL) &&
	    sk_psock_queue_empty(psock))
		mask &= ~(EPOLLIN | EPOLLRDNORM);

	if (psock)
		sk_psock_put(sk, psock);

	return mask;
}

static int do_tls_getsockopt_conf(struct sock *sk, char __user *optval,
				  int __user *optlen, int tx)
{
@@ -691,9 +724,11 @@ static void build_proto_ops(struct proto_ops ops[TLS_NUM_CONFIG][TLS_NUM_CONFIG]

	ops[TLS_BASE][TLS_SW  ] = ops[TLS_BASE][TLS_BASE];
	ops[TLS_BASE][TLS_SW  ].splice_read	= tls_sw_splice_read;
	ops[TLS_BASE][TLS_SW  ].poll		= tls_sk_poll;

	ops[TLS_SW  ][TLS_SW  ] = ops[TLS_SW  ][TLS_BASE];
	ops[TLS_SW  ][TLS_SW  ].splice_read	= tls_sw_splice_read;
	ops[TLS_SW  ][TLS_SW  ].poll		= tls_sk_poll;

#ifdef CONFIG_TLS_DEVICE
	ops[TLS_HW  ][TLS_BASE] = ops[TLS_BASE][TLS_BASE];