Commit 2ac826b2 authored by Hui Tang's avatar Hui Tang
Browse files

sched: Introduce task relationship by net and memory

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I9GZAQ


CVE: NA

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

There may be some relationships between threads, such as
network communication, memory sharing, etc.

Generally, threads that have relationships may have better
performance when they are scheduled to the same smt, cluster
or numa, because they share certain resources.

This patch is in the scheduler, and provides a mechanism to
identify and maintain the affinity relationship. Currently,
the memory and network parts have been implemented, and other
relationships will be extended in the future.

Signed-off-by: default avatarHui Tang <tanghui20@huawei.com>
parent 9de44ea0
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@
#include <linux/sched/coredump.h>
#include <linux/sched/signal.h>
#include <linux/sched/numa_balancing.h>
#include <linux/sched/relationship.h>
#include <linux/sched/task.h>
#include <linux/pagemap.h>
#include <linux/perf_event.h>
@@ -1822,6 +1823,7 @@ static int bprm_execve(struct linux_binprm *bprm,
	rseq_execve(current);
	acct_update_integrals(current);
	task_numa_free(current, false);
	task_relationship_free(current, true);
	return retval;

out:
+5 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <linux/resource.h>
#include <linux/latencytop.h>
#include <linux/sched/prio.h>
#include <linux/sched/relationship.h>
#include <linux/sched/types.h>
#include <linux/signal_types.h>
#include <linux/mm_types_task.h>
@@ -1468,7 +1469,11 @@ struct task_struct {
#else
	KABI_RESERVE(13)
#endif
#if defined(CONFIG_SCHED_TASK_RELATIONSHIP) && !defined(__GENKSYMS__)
	KABI_USE(14, struct task_relationship *rship)
#else
	KABI_RESERVE(14)
#endif
	KABI_RESERVE(15)
	KABI_RESERVE(16)
	KABI_AUX_PTR(task_struct)
+137 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_SCHED_RELATIONSHIP_H
#define _LINUX_SCHED_RELATIONSHIP_H

#include <linux/nodemask.h>
#include <linux/jump_label.h>
#include <linux/refcount.h>

#define FAULT_NODES_MAX 4

struct task_struct;
struct rq;

#ifdef CONFIG_SCHED_DEBUG
struct seq_file;
#endif

struct fault_array_info {
	int nid;
	unsigned long val;
};

struct relationship_hdr {
	refcount_t refcount;
	spinlock_t lock;
	int nr_tasks;
	int gid;
	nodemask_t preferred_nid;
};

enum net_req_type {
	NET_RS_TYPE_INVALID = 0,
	NET_RS_TYPE_LOCAL,
	NET_RS_TYPE_RX,
	NET_RS_TYPE_TX,
	NET_RS_TYPE_MAX
};

struct net_relationship_req {
	enum net_req_type net_rship_type;
	pid_t rx_pid;
	pid_t tx_pid;
	int nic_nid;
	int rx_dev_idx;
	int rx_dev_queue_idx;
	u64 rx_dev_netns_cookie;
	unsigned long rxtx_bytes;

	/* reserved */
	unsigned long rxtx_cnt;
};

struct net_relationship_callback {
	struct callback_head twork;
	atomic_t active;
	pid_t src_pid;
	struct net_relationship_req req;
};

struct net_group {
	struct rcu_head rcu;
	struct relationship_hdr hdr;
	unsigned long rxtx_bytes;

	/* reserved */
	unsigned long rxtx_cnt;
};

struct numa_fault_ext {
	struct fault_array_info faults_ordered[FAULT_NODES_MAX];
};

struct task_relationship {
	/* network relationship */
	struct net_group __rcu *net_group;
	spinlock_t net_lock;
	int nic_nid;
	int rx_dev_idx;
	int rx_dev_queue_idx;
	unsigned long rx_dev_netns_cookie;
	unsigned long rxtx_remote_bytes;
	unsigned long rxtx_remote_update_next;
	unsigned long rxtx_remote_buffer;
	unsigned long rxtx_bytes;
	unsigned long rxtx_buffer;
	unsigned long rxtx_update_next;
	struct net_relationship_callback cb;

	/* extras numa fault data */
	struct numa_fault_ext faults;
};

extern void task_relationship_enable(void);
extern void task_relationship_disable(void);

#ifdef CONFIG_SCHED_DEBUG
extern void sched_show_relationship(struct task_struct *p, struct seq_file *m);
#endif

#ifdef CONFIG_SCHED_TASK_RELATIONSHIP
extern int sched_relationship_fork(struct task_struct *p);
extern void sched_relationship_free(struct task_struct *p);
void task_relationship_free(struct task_struct *tsk, bool reset);
extern bool task_relationship_supported(struct task_struct *tsk);
extern int sched_net_relationship_submit(struct net_relationship_req *req);
extern void numa_faults_update_and_sort(int nid, int new,
					  struct fault_array_info *stats);

DECLARE_STATIC_KEY_FALSE(__relationship_switch);
static inline bool task_relationship_used(void)
{
	return static_branch_unlikely(&__relationship_switch);
}
#else
static inline bool task_relationship_used(void)
{
	return false;
}

static inline int sched_relationship_fork(struct task_struct *p)
{
	return 0;
}

static inline void sched_relationship_free(struct task_struct *p) {}

static inline void
task_relationship_free(struct task_struct *tsk, bool reset) {}

static inline int
sched_net_relationship_submit(struct net_relationship_req *req)
{
	return 0;
}
#endif

#endif
+10 −0
Original line number Diff line number Diff line
@@ -1081,6 +1081,16 @@ config QOS_SCHED_DYNAMIC_AFFINITY
	 of taskgroup is below threshold setted, otherwise make taskgroup to use
	 cpus allowed.

config SCHED_TASK_RELATIONSHIP
	bool "task relationship"
	depends on NUMA_BALANCING
	default n
	help
	 This feature enables the scheduler to identify tasks relationship by
	 page fault, SPE, socket and other IPC method.

	 If in doubt, say N.

config UCLAMP_TASK_GROUP
	bool "Utilization clamping per group of tasks"
	depends on CGROUP_SCHED
+3 −0
Original line number Diff line number Diff line
@@ -217,6 +217,9 @@ struct task_struct init_task
#ifdef CONFIG_QOS_SCHED_DYNAMIC_AFFINITY
	.prefer_cpus	= NULL,
#endif
#ifdef CONFIG_SCHED_TASK_RELATIONSHIP
	.rship		= NULL,
#endif
#ifdef CONFIG_SECCOMP_FILTER
	.seccomp	= { .filter_count = ATOMIC_INIT(0) },
#endif
Loading