Unverified Commit 35e6f352 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!3037 introduce smart_grid zone

Merge Pull Request from: @ci-robot 
 
PR sync from: Yipeng Zou <zouyipeng@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/TLDEU6OI5TRYQDVYOG7ULBDJZUFZHFIO/ 
The patch sets include two parts:

1. patch 1~15,20: Rebase smart_grid from openeuler-1.0-LTS to OLK-5.10
2. patch 16~19: introduce smart_grid zone qos and cpufreq

Since v7:

1. Update x86 openeuler_defconfig

Since v6:

1. check is timer active in affinity timer

Since v5:

1. Fix race condition in smart_grid_governor_enable.
2. Fix race condition in stop_auto_affinity.
3. Fix some str to int input in smart_grid_level_write.

Since v4:

1. Place the highest level task in current domain level itself in
sched_grid_prefer_cpus

Since v3:

1. fix CI warning

Since v2:

1. static alloc sg_zone cpumask.
2. fix some warning


Hui Tang (13):
  sched: Introduce smart grid scheduling strategy for cfs
  sched: fix smart grid usage count
  sched: fix WARN found by deadlock detect
  sched: Fix negative count for jump label
  sched: Fix timer storm for smart grid
  sched: fix dereference NULL pointers
  sched: Fix memory leak on error branch
  sched: clear credit count in error branch
  sched: Adjust few parameters range for smart grid
  sched: Delete redundant updates to p->prefer_cpus
  sched: Fix memory leak for smart grid
  sched: Fix null pointer derefrence for sd->span

Wang ShaoBo (2):
  sched: smart grid: init sched_grid_qos structure on QOS purpose
  config: enable CONFIG_QOS_SCHED_SMART_GRID by default

Yipeng Zou (5):
  sched: introduce smart grid qos zone
  smart_grid: introduce /proc/pid/smart_grid_level
  smart_grid: introduce smart_grid_strategy_ctrl sysctl
  smart_grid: cpufreq: introduce smart_grid cpufreq control
  sched: smart grid: check is active in affinity timer


-- 
2.34.1
 
https://gitee.com/openeuler/kernel/issues/I7F7KV
https://gitee.com/openeuler/kernel/issues/I7G6SW
https://gitee.com/openeuler/kernel/issues/I7BQZ0
https://gitee.com/openeuler/kernel/issues/I7D98G
https://gitee.com/openeuler/kernel/issues/I7CGD0
https://gitee.com/openeuler/kernel/issues/I7EBNA
https://gitee.com/openeuler/kernel/issues/I7HFZV
https://gitee.com/openeuler/kernel/issues/I7DA63
https://gitee.com/openeuler/kernel/issues/I7ZBSR
https://gitee.com/openeuler/kernel/issues/I7FBJM
https://gitee.com/openeuler/kernel/issues/I7EBSH
https://gitee.com/openeuler/kernel/issues/I7EEF3
https://gitee.com/openeuler/kernel/issues/I7DSX6
https://gitee.com/openeuler/kernel/issues/I7EA1X 
 
Link:https://gitee.com/openeuler/kernel/pulls/3037

 

Reviewed-by: default avatarZhang Jianhua <chris.zjh@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parents 411657bf 6046a54e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -160,6 +160,7 @@ CONFIG_FAIR_GROUP_SCHED=y
CONFIG_CFS_BANDWIDTH=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_QOS_SCHED_DYNAMIC_AFFINITY=y
CONFIG_QOS_SCHED_SMART_GRID=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_RDMA=y
CONFIG_CGROUP_FREEZER=y
+1 −0
Original line number Diff line number Diff line
@@ -165,6 +165,7 @@ CONFIG_FAIR_GROUP_SCHED=y
CONFIG_CFS_BANDWIDTH=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_QOS_SCHED_DYNAMIC_AFFINITY=y
# CONFIG_QOS_SCHED_SMART_GRID is not set
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_RDMA=y
CONFIG_CGROUP_FREEZER=y
+232 −0
Original line number Diff line number Diff line
@@ -2689,6 +2689,235 @@ int cpufreq_boost_enabled(void)
}
EXPORT_SYMBOL_GPL(cpufreq_boost_enabled);

#ifdef CONFIG_QOS_SCHED_SMART_GRID

struct smart_grid_zone {
	char governor_name[SMART_GRID_ZONE_NR][CPUFREQ_NAME_LEN];
	unsigned int enable;
	struct irq_work irq_work;
	struct work_struct work;
	unsigned int is_init;
};

static struct smart_grid_zone sg_zone;
static DEFINE_MUTEX(sg_zone_lock);

#define SG_WRITE_BUFF_LEN	30

void cpufreq_smart_grid_start_sync(void)
{
	if (likely(sg_zone.is_init))
		irq_work_queue(&sg_zone.irq_work);
}

static ssize_t show_smart_grid_governor(struct kobject *kobj,
					struct kobj_attribute *attr, char *buf)
{
	int len = 0;
	int gov_index;

	mutex_lock(&sg_zone_lock);
	if (!sg_zone.enable) {
		mutex_unlock(&sg_zone_lock);
		return sprintf(buf, "smart_grid governor disable\n");
	}

	for (gov_index = 0; gov_index < SMART_GRID_ZONE_NR; gov_index++)
		len += sprintf(buf + len, "smart_grid-%d: %s\n", gov_index,
								 sg_zone.governor_name[gov_index]);

	mutex_unlock(&sg_zone_lock);
	return len;
}

static ssize_t store_smart_grid_governor(struct kobject *kobj, struct kobj_attribute *attr,
					 const char *buf, size_t count)
{
	struct cpufreq_governor *target_gov = NULL;
	unsigned int current_level;
	char *level_string = NULL;
	char buf_string[SG_WRITE_BUFF_LEN];
	char *gov_string = buf_string;
	char save_string[CPUFREQ_NAME_LEN];
	int ret;

	mutex_lock(&sg_zone_lock);
	if (!sg_zone.enable) {
		ret = -EINVAL;
		goto fail;
	}

	if (strscpy(buf_string, buf, SG_WRITE_BUFF_LEN) <= 0) {
		ret = -EINVAL;
		goto fail;
	}

	level_string = strsep(&gov_string, "-");
	if (level_string == NULL) {
		ret = -EINVAL;
		goto fail;
	}

	if (kstrtouint(level_string, 10, &current_level)) {
		ret = -EINVAL;
		goto fail;
	}

	if (current_level >= SMART_GRID_ZONE_NR) {
		ret = -EINVAL;
		goto fail;
	}

	if (sscanf(gov_string, "%15s", save_string) != 1) {
		ret = -EINVAL;
		goto fail;
	}

	target_gov = cpufreq_parse_governor(save_string);
	if (target_gov == NULL) {
		ret = -EINVAL;
		goto fail;
	}
	module_put(target_gov->owner);

	strscpy(sg_zone.governor_name[current_level], save_string, CPUFREQ_NAME_LEN);
	cpufreq_smart_grid_start_sync();
	mutex_unlock(&sg_zone_lock);
	return count;

fail:
	mutex_unlock(&sg_zone_lock);
	return ret;
}
define_one_global_rw(smart_grid_governor);

static ssize_t show_smart_grid_governor_enable(struct kobject *kobj,
					       struct kobj_attribute *attr, char *buf)
{
	return sprintf(buf, "%u\n", sg_zone.enable);
}

static void smart_grid_irq_work(struct irq_work *irq_work)
{
	struct smart_grid_zone *zone;

	zone = container_of(irq_work, struct smart_grid_zone, irq_work);
	schedule_work_on(smp_processor_id(), &zone->work);
}

static void smart_grid_work_handler(struct work_struct *work)
{
	struct smart_grid_zone *zone;
	struct cpufreq_governor *target_gov = NULL;
	struct cpufreq_policy *policy = NULL;
	unsigned int cpu;
	int gov_index;

	zone = container_of(work, struct smart_grid_zone, work);

	mutex_lock(&sg_zone_lock);
	if (!sg_zone.enable) {
		mutex_unlock(&sg_zone_lock);
		return;
	}

	for (gov_index = 0; gov_index < SMART_GRID_ZONE_NR; gov_index++) {
		target_gov = cpufreq_parse_governor(sg_zone.governor_name[gov_index]);
		if (target_gov == NULL)
			continue;

		for_each_cpu(cpu, sched_grid_zone_cpumask(gov_index)) {
			if (cpu_is_offline(cpu))
				continue;

			policy = cpufreq_cpu_acquire(cpu);
			if (policy == NULL)
				continue;

			if (policy->governor == target_gov) {
				cpufreq_cpu_release(policy);
				continue;
			}
			/*Try to switch governor */
			store_scaling_governor(policy, sg_zone.governor_name[gov_index],
					       CPUFREQ_NAME_LEN);
			cpufreq_cpu_release(policy);
		}
		module_put(target_gov->owner);
	}
	mutex_unlock(&sg_zone_lock);
}

static void sg_zone_set_enable(void)
{
	int gov_index;

	/* Set default smart_grid governor */
	for (gov_index = 0; gov_index < SMART_GRID_ZONE_NR; gov_index++) {
		if (!gov_index)
			strscpy(sg_zone.governor_name[gov_index], "performance", CPUFREQ_NAME_LEN);
		else
			strscpy(sg_zone.governor_name[gov_index], "powersave", CPUFREQ_NAME_LEN);
	}

	sg_zone.enable = 1;
	cpufreq_smart_grid_start_sync();
}

static void sg_zone_set_disable(void)
{
	sg_zone.enable = 0;
}

static ssize_t store_smart_grid_governor_enable(struct kobject *kobj, struct kobj_attribute *attr,
						const char *buf, size_t count)
{
	unsigned int enable;

	if (kstrtouint(buf, 10, &enable))
		return -EINVAL;

	if (enable > 1)
		return -EINVAL;

	mutex_lock(&sg_zone_lock);
	if (sg_zone.enable == enable) {
		mutex_unlock(&sg_zone_lock);
		return -EINVAL;
	}

	if (enable)
		sg_zone_set_enable();
	else
		sg_zone_set_disable();

	mutex_unlock(&sg_zone_lock);
	return count;
}
define_one_global_rw(smart_grid_governor_enable);

static int create_smart_grid_sysfs_file(void)
{
	int ret;

	ret = sysfs_create_file(cpufreq_global_kobject, &smart_grid_governor.attr);
	if (ret)
		pr_err("%s: cannot register global smart_grid_governor sysfs file\n",
		       __func__);

	ret = sysfs_create_file(cpufreq_global_kobject, &smart_grid_governor_enable.attr);
	if (ret)
		pr_err("%s: cannot register global smart_grid_governor_enable sysfs file\n",
		       __func__);

	init_irq_work(&sg_zone.irq_work, smart_grid_irq_work);
	INIT_WORK(&sg_zone.work, smart_grid_work_handler);
	sg_zone.enable = 0;
	sg_zone.is_init = 1;
	return ret;
}
#endif

/*********************************************************************
 *               REGISTER / UNREGISTER CPUFREQ DRIVER                *
 *********************************************************************/
@@ -2861,6 +3090,9 @@ static int __init cpufreq_core_init(void)
	if (!strlen(default_governor))
		strncpy(default_governor, gov->name, CPUFREQ_NAME_LEN);

#ifdef CONFIG_QOS_SCHED_SMART_GRID
	create_smart_grid_sysfs_file();
#endif
	return 0;
}
module_param(off, int, 0444);
+13 −0
Original line number Diff line number Diff line
@@ -389,6 +389,16 @@ static void task_cpus_allowed(struct seq_file *m, struct task_struct *task)
		   cpumask_pr_args(task->cpus_ptr));
}

#ifdef CONFIG_QOS_SCHED_DYNAMIC_AFFINITY
static void task_cpus_preferred(struct seq_file *m, struct task_struct *task)
{
	seq_printf(m, "Cpus_preferred:\t%*pb\n",
		   cpumask_pr_args(task->prefer_cpus));
	seq_printf(m, "Cpus_preferred_list:\t%*pbl\n",
		   cpumask_pr_args(task->prefer_cpus));
}
#endif

static inline void task_core_dumping(struct seq_file *m, struct mm_struct *mm)
{
	seq_put_decimal_ull(m, "CoreDumping:\t", !!mm->core_state);
@@ -427,6 +437,9 @@ int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
	task_cpus_allowed(m, task);
	cpuset_task_status_allowed(m, task);
	task_context_switch_counts(m, task);
#ifdef CONFIG_QOS_SCHED_DYNAMIC_AFFINITY
	task_cpus_preferred(m, task);
#endif
	return 0;
}

+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
Loading