Commit ee319799 authored by Hui Tang's avatar Hui Tang
Browse files

sched: Add ioctl to get relationship

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


CVE: NA

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

Introduce ioctl interfaces to get relationship for task,
which facilitating the acquisition and use of relationship
in user mode.

Signed-off-by: default avatarHui Tang <tanghui20@huawei.com>
parent 13515974
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
#include <linux/nodemask.h>
#include <linux/jump_label.h>
#include <linux/refcount.h>
#include <uapi/linux/sched_ctrl.h>

#define FAULT_NODES_MAX 4

@@ -127,6 +128,12 @@ 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
sctl_sched_get_net_relationship(struct task_struct *tsk,
				struct sctl_net_relationship_info *info);
extern void
sctl_sched_get_mem_relationship(struct task_struct *tsk,
				struct sctl_mem_relationship_info *info);
extern void sched_get_mm_relationship(struct task_struct *tsk,
			       struct bpf_relationship_get_args *args);
extern void sched_get_relationship(struct task_struct *tsk,
+57 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _LINUX_SCHED_CTRL_H
#define _LINUX_SCHED_CTRL_H

#include <linux/types.h>


#define SCTL_IOC_MAGIC	'X'

/* get task relationship */
#define SCTL_GET_RSHIP		\
	_IOR(SCTL_IOC_MAGIC, 0, struct sctl_get_relationship_args)

#define SCTL_IOC_MAXNR	1

#define SCTL_MAX_NUMNODES 16
#define SCTL_STR_MAX 64
#define NR_TASK_FAULTS_TYPE 2

#define NO_RSHIP (-1)

struct grp_hdr {
	int gid;
	char preferred_nid[SCTL_STR_MAX];
	int nr_tasks;
};

struct sctl_net_relationship_info {
	int valid;
	struct grp_hdr grp_hdr;
	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_bytes;
	unsigned long grp_rxtx_bytes;
};

struct sctl_mem_relationship_info {
	int valid;
	struct grp_hdr grp_hdr;
	int nodes_num;
	unsigned long total_faults;
	unsigned long grp_total_faults;
	unsigned long faults[SCTL_MAX_NUMNODES][NR_TASK_FAULTS_TYPE];
	unsigned long faults_cpu[SCTL_MAX_NUMNODES][NR_TASK_FAULTS_TYPE];
	unsigned long grp_faults[SCTL_MAX_NUMNODES][NR_TASK_FAULTS_TYPE];
	unsigned long grp_faults_cpu[SCTL_MAX_NUMNODES][NR_TASK_FAULTS_TYPE];
};

struct sctl_get_relationship_args {
	int tid;
	struct sctl_net_relationship_info nrsi;
	struct sctl_mem_relationship_info mrsi;
};
#endif /* _LINUX_SCHED_CTRL_H */
+1 −1
Original line number Diff line number Diff line
@@ -40,4 +40,4 @@ obj-$(CONFIG_SCHED_CORE) += core_sched.o
obj-$(CONFIG_BPF_SCHED) += bpf_sched.o
obj-$(CONFIG_BPF_SCHED) += bpf_topology.o
obj-$(CONFIG_QOS_SCHED_SMART_GRID) += grid/
obj-$(CONFIG_SCHED_TASK_RELATIONSHIP) += relationship.o
obj-$(CONFIG_SCHED_TASK_RELATIONSHIP) += relationship.o relationship_ioctl.o
+49 −0
Original line number Diff line number Diff line
@@ -3043,6 +3043,55 @@ static inline void update_scan_period(struct task_struct *p, int new_cpu)
#endif /* CONFIG_NUMA_BALANCING */

#ifdef CONFIG_SCHED_TASK_RELATIONSHIP
void sctl_sched_get_mem_relationship(struct task_struct *tsk,
			       struct sctl_mem_relationship_info *info)
{
#ifdef CONFIG_NUMA_BALANCING
	struct task_relationship *rship = tsk->rship;
	int nid, priv, cpu_idx, mem_idx;
	struct numa_group *grp;

	info->valid = false;
	if (unlikely(!rship) || !tsk->numa_faults)
		return;

	memset(info, 0, sizeof(*info));
	info->valid = true;
	info->nodes_num = nr_node_ids;
	info->grp_hdr.gid = NO_RSHIP;
	info->total_faults = tsk->total_numa_faults;

	rcu_read_lock();

	grp = rcu_dereference(tsk->numa_group);
	if (grp) {
		info->grp_hdr.gid = grp->gid;
		info->grp_hdr.nr_tasks = grp->nr_tasks;
		snprintf(info->grp_hdr.preferred_nid, SCTL_STR_MAX, "%*pbl",
			nodemask_pr_args(&grp->preferred_nid));
	}

	for_each_online_node(nid) {
		if (nid >= SCTL_MAX_NUMNODES)
			break;

		for (priv = 0; priv < NR_NUMA_HINT_FAULT_TYPES; priv++) {
			cpu_idx = task_faults_idx(NUMA_CPU, nid, priv);
			mem_idx = task_faults_idx(NUMA_MEM, nid, priv);
			info->faults[nid][priv] = tsk->numa_faults[mem_idx];
			info->faults_cpu[nid][priv] = tsk->numa_faults[cpu_idx];

			if (grp) {
				info->grp_faults[nid][priv] = grp->faults[mem_idx];
				info->grp_faults_cpu[nid][priv] = grp->faults_cpu[mem_idx];
				info->grp_total_faults = grp->total_faults;
			}
		}
	}

	rcu_read_unlock();
#endif
}

#ifdef CONFIG_BPF_SCHED
void sched_get_mm_relationship(struct task_struct *tsk,
+31 −0
Original line number Diff line number Diff line
@@ -366,6 +366,37 @@ void sched_get_relationship(struct task_struct *tsk,
	rcu_read_unlock();
}

void sctl_sched_get_net_relationship(struct task_struct *tsk,
				     struct sctl_net_relationship_info *info)
{
	struct task_relationship *rship = tsk->rship;
	struct net_group *grp;

	memset(info, 0, sizeof(*info));
	info->valid = true;
	info->nic_nid = rship->nic_nid;
	info->rx_dev_idx = rship->rx_dev_idx;
	info->rx_dev_queue_idx = rship->rx_dev_queue_idx;
	info->rx_dev_netns_cookie = rship->rx_dev_netns_cookie;
	info->rxtx_remote_bytes = rship->rxtx_remote_bytes;
	info->rxtx_bytes = rship->rxtx_bytes;

	info->grp_hdr.gid = NO_RSHIP;

	rcu_read_lock();

	grp = rcu_dereference(rship->net_group);
	if (grp) {
		info->grp_hdr.gid = grp->hdr.gid;
		info->grp_hdr.nr_tasks = grp->hdr.nr_tasks;
		snprintf(info->grp_hdr.preferred_nid, SCTL_STR_MAX, "%*pbl",
			nodemask_pr_args(&grp->hdr.preferred_nid));
		info->grp_rxtx_bytes = grp->rxtx_bytes;
	}

	rcu_read_unlock();
}

void task_relationship_free(struct task_struct *tsk, bool reset)
{
	if (!task_relationship_used())
Loading