Commit 9c52cafd authored by Litao Jiao's avatar Litao Jiao
Browse files

anolis: net/smc: Introduce multiple tcp listen works to enhance tcp_listen_work

anolis inclusion
from anolis-v5.10-134
commit c9aebf36d4dcc5005f8f58f5202c58f668a33380
category: performance
bugzilla: https://gitee.com/openeuler/kernel/issues/I782PA
CVE: NA

Reference: https://gitee.com/anolis/hpn-cloud-kernel/commit/c9aebf36d4dcc5005f8f58f5202c58f668a33380



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

ANBZ: #1742

Introduce multiple tcp listen works to enhance tcp_listen_work, as
each tcp listen work can be enqueued independently to workqueue and
can be executed concurrently. Since kernel_accept cannot accept
concurrently, too many tcp listen works will only lead to excessive
kernel_accept competition and waste CPU, the number of the tcp listen
works is now set to 2, which has been tested to be the best performance.

Signed-off-by: default avatarGuangguan Wang <guangguan.wang@linux.alibaba.com>
Acked-by: default avatarTony Lu <tonylu@linux.alibaba.com>
Link: https://gitee.com/anolis/cloud-kernel/pulls/577
Link: https://gitee.com/anolis/cloud-kernel/pulls/906


Signed-off-by: default avatarLitao Jiao <jiaolitao@sangfor.com.cn>
parent 5ea54f58
Loading
Loading
Loading
Loading
+12 −4
Original line number Diff line number Diff line
@@ -255,6 +255,7 @@ static struct sock *smc_sock_alloc(struct net *net, struct socket *sock,
	struct smc_sock *smc;
	struct proto *prot;
	struct sock *sk;
	int i = 0;

	prot = (protocol == SMCPROTO_SMC6) ? &smc_proto6 : &smc_proto;
	sk = sk_alloc(net, PF_SMC, GFP_KERNEL, prot, 0);
@@ -266,7 +267,11 @@ static struct sock *smc_sock_alloc(struct net *net, struct socket *sock,
	sk->sk_destruct = smc_destruct;
	sk->sk_protocol = protocol;
	smc = smc_sk(sk);
	INIT_WORK(&smc->tcp_listen_work, smc_tcp_listen_work);
	for (i = 0; i < SMC_MAX_TCP_LISTEN_WORKS; i++) {
		smc->tcp_listen_works[i].smc = smc;
		INIT_WORK(&smc->tcp_listen_works[i].work, smc_tcp_listen_work);
	}
	atomic_set(&smc->tcp_listen_work_seq, 0);
	INIT_WORK(&smc->connect_work, smc_connect_work);
	INIT_DELAYED_WORK(&smc->conn.tx_work, smc_tx_work);
	INIT_LIST_HEAD(&smc->accept_q);
@@ -1850,8 +1855,9 @@ static void smc_listen_work(struct work_struct *work)

static void smc_tcp_listen_work(struct work_struct *work)
{
	struct smc_sock *lsmc = container_of(work, struct smc_sock,
					     tcp_listen_work);
	struct smc_tcp_listen_work *twork =
		container_of(work, struct smc_tcp_listen_work, work);
	struct smc_sock *lsmc = twork->smc;
	struct sock *lsk = &lsmc->sk;
	struct smc_sock *new_smc;
	int rc = 0;
@@ -1892,8 +1898,10 @@ static void smc_clcsock_data_ready(struct sock *listen_clcsock)
		return;
	lsmc->clcsk_data_ready(listen_clcsock);
	if (lsmc->sk.sk_state == SMC_LISTEN) {
		int idx = atomic_fetch_inc(&lsmc->tcp_listen_work_seq) %
				  SMC_MAX_TCP_LISTEN_WORKS;
		sock_hold(&lsmc->sk); /* sock_put in smc_tcp_listen_work() */
		if (!queue_work(smc_tcp_ls_wq, &lsmc->tcp_listen_work))
		if (!queue_work(smc_tcp_ls_wq, &lsmc->tcp_listen_works[idx].work))
			sock_put(&lsmc->sk);
	}
}
+10 −1
Original line number Diff line number Diff line
@@ -220,6 +220,13 @@ struct smc_connection {
	u8			out_of_sync : 1; /* out of sync with peer */
};

#define SMC_MAX_TCP_LISTEN_WORKS 2

struct smc_tcp_listen_work {
	struct smc_sock *smc;
	struct work_struct	work;
};

struct smc_sock {				/* smc sock container */
	struct sock		sk;
	struct socket		*clcsock;	/* internal tcp socket */
@@ -228,7 +235,9 @@ struct smc_sock { /* smc sock container */
	struct smc_connection	conn;		/* smc connection */
	struct smc_sock		*listen_smc;	/* listen parent */
	struct work_struct	connect_work;	/* handle non-blocking connect*/
	struct work_struct	tcp_listen_work;/* handle tcp socket accepts */
	struct smc_tcp_listen_work	tcp_listen_works[SMC_MAX_TCP_LISTEN_WORKS];
						/* handle tcp socket accepts */
	atomic_t		tcp_listen_work_seq;/* used to select tcp_listen_works */
	struct work_struct	smc_listen_work;/* prepare new accept socket */
	struct list_head	accept_q;	/* sockets to be accepted */
	spinlock_t		accept_q_lock;	/* protects accept_q */
+3 −1
Original line number Diff line number Diff line
@@ -199,6 +199,7 @@ int smc_close_active(struct smc_sock *smc)
	long timeout;
	int rc = 0;
	int rc1 = 0;
	int i = 0;

	timeout = current->flags & PF_EXITING ?
		  0 : sock_flag(sk, SOCK_LINGER) ?
@@ -220,7 +221,8 @@ int smc_close_active(struct smc_sock *smc)
		}
		smc_close_cleanup_listen(sk);
		release_sock(sk);
		flush_work(&smc->tcp_listen_work);
		for (i = 0; i < SMC_MAX_TCP_LISTEN_WORKS; i++)
			flush_work(&smc->tcp_listen_works[i].work);
		lock_sock(sk);
		break;
	case SMC_ACTIVE: