Commit 5ed9128f authored by Yipeng Zou's avatar Yipeng Zou
Browse files

smart_grid: introduce /proc/pid/smart_grid_level

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


CVE: NA

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

Now, we can use /pro/pid/smart_grid_level to {read,set} task current qos
level.

This allows to determine the scope of dynamic partitioning of the task
in smart_grid.

SCHED_GRID_QOS_TASK_LEVEL was defined different QoS level. The lower number
has the higher priority. (E.g. 0 was the highest).

Signed-off-by: default avatarYipeng Zou <zouyipeng@huawei.com>
parent f0f516f1
Loading
Loading
Loading
Loading
+78 −0
Original line number Diff line number Diff line
@@ -93,6 +93,10 @@
#include <linux/sched/coredump.h>
#include <linux/sched/debug.h>
#include <linux/sched/stat.h>
#ifdef CONFIG_QOS_SCHED_SMART_GRID
#include <linux/sched/grid_qos.h>
#include <linux/sched.h>
#endif
#include <linux/posix-timers.h>
#include <linux/time_namespace.h>
#include <linux/resctrl.h>
@@ -3493,6 +3497,77 @@ static int proc_stack_depth(struct seq_file *m, struct pid_namespace *ns,
}
#endif /* CONFIG_STACKLEAK_METRICS */

#ifdef CONFIG_QOS_SCHED_SMART_GRID
static int smart_grid_level_show(struct seq_file *m, void *v)
{
	struct inode *inode = m->private;
	struct task_struct *p;

	p = get_proc_task(inode);
	if (!p)
		return -ESRCH;

	if (p->grid_qos != NULL)
		seq_printf(m, "%d\n", p->grid_qos->stat.class_lvl);

	put_task_struct(p);

	return 0;
}

static int smart_grid_level_open(struct inode *inode, struct file *filp)
{
	return single_open(filp, smart_grid_level_show, inode);
}

static ssize_t smart_grid_level_write(struct file *file, const char __user *buf,
				      size_t count, loff_t *offset)
{
	struct inode *inode = file_inode(file);
	struct task_struct *p;
	char buffer[TASK_COMM_LEN];
	const size_t maxlen = sizeof(buffer) - 1;
	unsigned int level = SCHED_GRID_QOS_TASK_LEVEL_MAX;
	int ret = 0;

	memset(buffer, 0, sizeof(buffer));
	if (copy_from_user(buffer, buf, count > maxlen ? maxlen : count))
		return -EFAULT;

	p = get_proc_task(inode);
	if (!p)
		return -ESRCH;

	if (kstrtouint(buffer, 10, &level)) {
		put_task_struct(p);
		return -EINVAL;
	}

	if (level >= SCHED_GRID_QOS_TASK_LEVEL_MAX) {
		put_task_struct(p);
		return -EINVAL;
	}

	if (p->grid_qos != NULL &&
	    p->grid_qos->stat.set_class_lvl != NULL)
		ret = p->grid_qos->stat.set_class_lvl(&p->grid_qos->stat, level);

	put_task_struct(p);

	if (ret)
		return ret;
	return count;
}

static const struct file_operations proc_pid_sg_level_operations = {
	.open		= smart_grid_level_open,
	.read		= seq_read,
	.write		= smart_grid_level_write,
	.llseek		= seq_lseek,
	.release	= single_release,
};
#endif

/*
 * Thread groups
 */
@@ -3516,6 +3591,9 @@ static const struct pid_entry tgid_base_stuff[] = {
#ifdef CONFIG_SCHED_DEBUG
	REG("sched",      S_IRUGO|S_IWUSR, proc_pid_sched_operations),
#endif
#ifdef CONFIG_QOS_SCHED_SMART_GRID
	REG("smart_grid_level", 0644, proc_pid_sg_level_operations),
#endif
#ifdef CONFIG_SCHED_AUTOGROUP
	REG("autogroup",  S_IRUGO|S_IWUSR, proc_pid_sched_autogroup_operations),
#endif
+10 −1
Original line number Diff line number Diff line
@@ -17,6 +17,15 @@ enum sched_grid_qos_class {
	SCHED_GRID_QOS_CLASS_LEVEL_NR
};

/*
 * SCHED_GRID_QOS_TASK_LEVEL was defined different QoS level.
 * The lower number has the higher priority. (E.g. 0 was the highest)
 * The enum sched_grid_qos_class defined the max level, the lowest level.
 */
#define SCHED_GRID_QOS_TASK_LEVEL_HIGHEST SCHED_GRID_QOS_CLASS_LEVEL_1
#define SCHED_GRID_QOS_TASK_LEVEL_MAX	(SCHED_GRID_QOS_CLASS_LEVEL_NR)
#define SCHED_GRID_QOS_TASK_LEVEL_DEFAULT (SCHED_GRID_QOS_CLASS_LEVEL_NR - 1)

enum {
	SCHED_GRID_QOS_IPS_INDEX = 0,
	SCHED_GRID_QOS_MEMBOUND_RATIO_INDEX = 1,
@@ -50,7 +59,7 @@ struct sched_grid_qos_sample {

struct sched_grid_qos_stat {
	enum sched_grid_qos_class class_lvl;
	int (*set_class_lvl)(struct sched_grid_qos_stat *qos_stat);
	int (*set_class_lvl)(struct sched_grid_qos_stat *qos_stat, int level);
	struct sched_grid_qos_sample sample[SCHED_GRID_QOS_SAMPLE_NR];
};

+15 −0
Original line number Diff line number Diff line
@@ -19,8 +19,20 @@
#include <linux/sched/grid_qos.h>
#include "internal.h"

static int qos_stat_set_class_level(struct sched_grid_qos_stat *qos_stat, int level)
{
	if (qos_stat == NULL || level >= SCHED_GRID_QOS_TASK_LEVEL_MAX)
		return -EINVAL;

	qos_stat->class_lvl = level;
	return 0;
}

void qos_stat_init(struct sched_grid_qos_stat *stat)
{
	if (stat == NULL)
		return;

	stat->sample[SCHED_GRID_QOS_IPS_INDEX].name = "ips";
	stat->sample[SCHED_GRID_QOS_IPS_INDEX].index = SCHED_GRID_QOS_IPS_INDEX;
	stat->sample[SCHED_GRID_QOS_MEMBOUND_RATIO_INDEX].name = "membound_ratio";
@@ -29,4 +41,7 @@ void qos_stat_init(struct sched_grid_qos_stat *stat)
	stat->sample[SCHED_GRID_QOS_MEMBANDWIDTH_INDEX].name = "memband_width";
	stat->sample[SCHED_GRID_QOS_MEMBANDWIDTH_INDEX].index =
		SCHED_GRID_QOS_MEMBANDWIDTH_INDEX;

	stat->set_class_lvl = qos_stat_set_class_level;
	stat->class_lvl = SCHED_GRID_QOS_TASK_LEVEL_DEFAULT;
}