Unverified Commit 696d5f9c authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!4993 v3 kworker: Fix the problem of ipsan performance degradation

Merge Pull Request from: @ci-robot 
 
PR sync from: jiangdongxu <jiangdongxu1@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/QYG7ARLERJFEKODKJGAYOGTV3NNM6IVV/ 
From: Shao Denghui <shaodenghui@huawei.com>

When the current downstream FS tests IPSAN, it is found that the performance on ARM is much worse than that on X86, and the test data of IPSAN fluctuates greatly. After analysis, the reason is that when iscsi issues IO, the task is sent to kworker for processing by iscsi_xmitworker.
 
The workqueue created by iscsi can automatically identify the CPU of the soft interrupt currently processed by iscsi, and automatically schedule the workqueue to the corresponding NUMA node.

Shao Denghui (3):
  workqueue: add member for NUMA aware order workqueue and implement
    NUMA affinity for single thread workqueue
  iscsi: use dynamic single thread workqueue to improve performance
  Add kernel compilation configuration options


-- 
2.33.0
 
https://gitee.com/openeuler/kernel/issues/I94XYA 
 
Link:https://gitee.com/openeuler/kernel/pulls/4993

 

Reviewed-by: default avatarLiu Chao <liuchao173@huawei.com>
Reviewed-by: default avatarXu Kuohai <xukuohai@huawei.com>
Reviewed-by: default avatarWei Li <liwei391@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parents f1e6c574 066e7bd4
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -29,4 +29,6 @@ source "lib/Kconfig"

source "lib/Kconfig.debug"

source "lib/Kconfig.openeuler"

source "Documentation/Kconfig"
+1 −0
Original line number Diff line number Diff line
@@ -1036,6 +1036,7 @@ CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y
CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y
CONFIG_PID_MAX_PER_NAMESPACE=y
CONFIG_FREEZER=y
CONFIG_KWORKER_NUMA_AFFINITY=y

#
# Executable file formats
+1 −0
Original line number Diff line number Diff line
@@ -1033,6 +1033,7 @@ CONFIG_ARCH_HAS_SYNC_CORE_BEFORE_USERMODE=y
CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y
CONFIG_PID_MAX_PER_NAMESPACE=y
CONFIG_FREEZER=y
CONFIG_KWORKER_NUMA_AFFINITY=y

#
# Executable file formats
+13 −0
Original line number Diff line number Diff line
@@ -170,6 +170,9 @@ static void iscsi_sw_tcp_data_ready(struct sock *sk)
	struct iscsi_sw_tcp_conn *tcp_sw_conn;
	struct iscsi_tcp_conn *tcp_conn;
	struct iscsi_conn *conn;
#ifdef KWORKER_NUMA_AFFINITY
	int current_cpu;
#endif

	trace_sk_data_ready(sk);

@@ -180,6 +183,16 @@ static void iscsi_sw_tcp_data_ready(struct sock *sk)
		return;
	}
	tcp_conn = conn->dd_data;

#ifdef KWORKER_NUMA_AFFINITY
	/* save intimate cpu when in softirq */
	if (!sock_owned_by_user_nocheck(sk)) {
		current_cpu = smp_processor_id();
		if (conn->intimate_cpu != current_cpu)
			conn->intimate_cpu = current_cpu;
	}
#endif

	tcp_sw_conn = tcp_conn->dd_data;

	if (tcp_sw_conn->queue_recv)
+22 −2
Original line number Diff line number Diff line
@@ -89,9 +89,20 @@ inline void iscsi_conn_queue_xmit(struct iscsi_conn *conn)
{
	struct Scsi_Host *shost = conn->session->host;
	struct iscsi_host *ihost = shost_priv(shost);
#ifdef KWORKER_NUMA_AFFINITY
	int intimate_cpu = conn->intimate_cpu;

	if (ihost->workq) {
		/* we expect it to be excuted on the same numa of the intimate cpu */
		if ((intimate_cpu >= 0) && cpu_possible(intimate_cpu))
			queue_work_on(intimate_cpu, ihost->workq, &conn->xmitwork);
		else
			queue_work(ihost->workq, &conn->xmitwork);
	}
#else
	if (ihost->workq)
		queue_work(ihost->workq, &conn->xmitwork);
#endif
}
EXPORT_SYMBOL_GPL(iscsi_conn_queue_xmit);

@@ -2907,9 +2918,15 @@ struct Scsi_Host *iscsi_host_alloc(const struct scsi_host_template *sht,
	ihost = shost_priv(shost);

	if (xmit_can_sleep) {
#ifdef KWORKER_NUMA_AFFINITY
		/* this kind of workqueue only support single work */
		ihost->workq = alloc_ordered_workqueue("iscsi_q_%d", __WQ_LEGACY | WQ_MEM_RECLAIM |
							__WQ_DYNAMIC, shost->host_no);
#else
		ihost->workq = alloc_workqueue("iscsi_q_%d",
				WQ_SYSFS | __WQ_LEGACY | WQ_MEM_RECLAIM | WQ_UNBOUND,
				1, shost->host_no);
#endif
		if (!ihost->workq)
			goto free_host;
	}
@@ -3190,6 +3207,9 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size,
	conn->c_stage = ISCSI_CONN_INITIAL_STAGE;
	conn->id = conn_idx;
	conn->exp_statsn = 0;
#ifdef KWORKER_NUMA_AFFINITY
	conn->intimate_cpu = -1;
#endif

	timer_setup(&conn->transport_timer, iscsi_check_transport_timeouts, 0);

Loading