Loading fs/proc/base.c +117 −0 Original line number Diff line number Diff line Loading @@ -2874,6 +2874,121 @@ static int proc_tgid_io_accounting(struct seq_file *m, struct pid_namespace *ns, } #endif /* CONFIG_TASK_IO_ACCOUNTING */ #ifdef CONFIG_SCHED_WALT static ssize_t proc_sched_task_boost_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct task_struct *task = get_proc_task(file_inode(file)); char buffer[PROC_NUMBUF]; int sched_boost; size_t len; if (!task) return -ESRCH; sched_boost = task->boost; put_task_struct(task); len = scnprintf(buffer, sizeof(buffer), "%d\n", sched_boost); return simple_read_from_buffer(buf, count, ppos, buffer, len); } static ssize_t proc_sched_task_boost_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { struct task_struct *task = get_proc_task(file_inode(file)); char buffer[PROC_NUMBUF]; int sched_boost; int err; if (!task) return -ESRCH; memset(buffer, 0, sizeof(buffer)); if (count > sizeof(buffer) - 1) count = sizeof(buffer) - 1; if (copy_from_user(buffer, buf, count)) { err = -EFAULT; goto out; } err = kstrtoint(strstrip(buffer), 0, &sched_boost); if (err) goto out; if (sched_boost < TASK_BOOST_NONE || sched_boost >= TASK_BOOST_END) { err = -EINVAL; goto out; } task->boost = sched_boost; if (sched_boost == 0) task->boost_period = 0; out: put_task_struct(task); return err < 0 ? err : count; } static ssize_t proc_sched_task_boost_period_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct task_struct *task = get_proc_task(file_inode(file)); char buffer[PROC_NUMBUF]; u64 sched_boost_period_ms = 0; size_t len; if (!task) return -ESRCH; sched_boost_period_ms = div64_ul(task->boost_period, 1000000UL); put_task_struct(task); len = snprintf(buffer, sizeof(buffer), "%llu\n", sched_boost_period_ms); return simple_read_from_buffer(buf, count, ppos, buffer, len); } static ssize_t proc_sched_task_boost_period_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { struct task_struct *task = get_proc_task(file_inode(file)); char buffer[PROC_NUMBUF]; unsigned int sched_boost_period; int err; if (!task) return -ESRCH; memset(buffer, 0, sizeof(buffer)); if (count > sizeof(buffer) - 1) count = sizeof(buffer) - 1; if (copy_from_user(buffer, buf, count)) { err = -EFAULT; goto out; } err = kstrtouint(strstrip(buffer), 0, &sched_boost_period); if (err) goto out; if (task->boost == 0 && sched_boost_period) { /* setting boost period without boost is invalid */ err = -EINVAL; goto out; } task->boost_period = (u64)sched_boost_period * 1000 * 1000; task->boost_expires = sched_clock() + task->boost_period; out: put_task_struct(task); return err < 0 ? err : count; } static const struct file_operations proc_task_boost_enabled_operations = { .read = proc_sched_task_boost_read, .write = proc_sched_task_boost_write, .llseek = generic_file_llseek, }; static const struct file_operations proc_task_boost_period_operations = { .read = proc_sched_task_boost_period_read, .write = proc_sched_task_boost_period_write, .llseek = generic_file_llseek, }; #endif /* CONFIG_SCHED_WALT */ #ifdef CONFIG_USER_NS static int proc_id_map_open(struct inode *inode, struct file *file, const struct seq_operations *seq_ops) Loading Loading @@ -3067,6 +3182,8 @@ static const struct pid_entry tgid_base_stuff[] = { REG("sched_init_task_load", 00644, proc_pid_sched_init_task_load_operations), REG("sched_group_id", 00666, proc_pid_sched_group_id_operations), REG("sched_boost", 0666, proc_task_boost_enabled_operations), REG("sched_boost_period_ms", 0666, proc_task_boost_period_operations), #endif #ifdef CONFIG_SCHED_DEBUG REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), Loading include/linux/sched.h +15 −0 Original line number Diff line number Diff line Loading @@ -129,6 +129,14 @@ enum fps { FPS120 = 120, }; enum task_boost_type { TASK_BOOST_NONE = 0, TASK_BOOST_ON_MID, TASK_BOOST_ON_MAX, TASK_BOOST_STRICT_MAX, TASK_BOOST_END, }; #ifdef CONFIG_DEBUG_ATOMIC_SLEEP /* Loading Loading @@ -540,6 +548,7 @@ extern void __weak sched_update_cpu_freq_min_max(const cpumask_t *cpus, u32 fmin, u32 fmax); extern void __weak free_task_load_ptrs(struct task_struct *p); extern void __weak sched_set_refresh_rate(enum fps fps); extern int set_task_boost(int boost, u64 period); #define RAVG_HIST_SIZE_MAX 5 #define NUM_BUSY_BUCKETS 10 Loading Loading @@ -607,6 +616,8 @@ static inline void sched_update_cpu_freq_min_max(const cpumask_t *cpus, u32 fmin, u32 fmax) { } static inline void sched_set_refresh_rate(enum fps fps) { } static inline void set_task_boost(int boost, u64 period) { } #endif /* CONFIG_SCHED_WALT */ struct sched_rt_entity { Loading Loading @@ -806,7 +817,11 @@ struct task_struct { const struct sched_class *sched_class; struct sched_entity se; struct sched_rt_entity rt; #ifdef CONFIG_SCHED_WALT int boost; u64 boost_period; u64 boost_expires; u64 last_sleep_ts; bool wake_up_idle; struct ravg ravg; Loading include/linux/sched/topology.h +4 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,10 @@ struct sched_domain_shared { atomic_t ref; atomic_t nr_busy_cpus; int has_idle_cores; #ifdef CONFIG_SCHED_WALT bool overutilized; #endif }; struct sched_domain { Loading include/trace/events/sched.h +8 −2 Original line number Diff line number Diff line Loading @@ -1017,6 +1017,7 @@ TRACE_EVENT(sched_task_util, __field(int, start_cpu) __field(int, unfilter) __field(unsigned long, cpus_allowed) __field(int, task_boost) ), TP_fast_assign( Loading @@ -1042,15 +1043,20 @@ TRACE_EVENT(sched_task_util, #endif __entry->cpus_allowed = cpumask_bits(&p->cpus_mask)[0]; #ifdef CONFIG_SCHED_WALT __entry->task_boost = per_task_boost(p); #else __entry->task_boost = 0; #endif ), TP_printk("pid=%d comm=%s util=%lu prev_cpu=%d candidates=%#lx best_energy_cpu=%d sync=%d need_idle=%d fastpath=%d placement_boost=%d latency=%llu stune_boosted=%d is_rtg=%d rtg_skip_min=%d start_cpu=%d unfilter=%d affinity=%lx", TP_printk("pid=%d comm=%s util=%lu prev_cpu=%d candidates=%#lx best_energy_cpu=%d sync=%d need_idle=%d fastpath=%d placement_boost=%d latency=%llu stune_boosted=%d is_rtg=%d rtg_skip_min=%d start_cpu=%d unfilter=%d affinity=%lx task_boost=%d", __entry->pid, __entry->comm, __entry->util, __entry->prev_cpu, __entry->candidates, __entry->best_energy_cpu, __entry->sync, __entry->need_idle, __entry->fastpath, __entry->placement_boost, __entry->latency, __entry->stune_boosted, __entry->is_rtg, __entry->rtg_skip_min, __entry->start_cpu, __entry->unfilter, __entry->cpus_allowed) __entry->unfilter, __entry->cpus_allowed, __entry->task_boost) ) /* Loading kernel/sched/core.c +23 −0 Original line number Diff line number Diff line Loading @@ -2751,6 +2751,9 @@ static void __sched_fork(unsigned long clone_flags, struct task_struct *p) #ifdef CONFIG_SCHED_WALT p->last_sleep_ts = 0; p->wake_up_idle = false; p->boost = 0; p->boost_expires = 0; p->boost_period = 0; #endif INIT_LIST_HEAD(&p->se.group_node); Loading Loading @@ -8392,6 +8395,26 @@ void dequeue_task_core(struct rq *rq, struct task_struct *p, int flags) } #ifdef CONFIG_SCHED_WALT /* *@boost:should be 0,1,2. *@period:boost time based on ms units. */ int set_task_boost(int boost, u64 period) { if (boost < TASK_BOOST_NONE || boost >= TASK_BOOST_END) return -EINVAL; if (boost) { current->boost = boost; current->boost_period = (u64)period * 1000 * 1000; current->boost_expires = sched_clock() + current->boost_period; } else { current->boost = 0; current->boost_expires = 0; current->boost_period = 0; } return 0; } void sched_account_irqtime(int cpu, struct task_struct *curr, u64 delta, u64 wallclock) { Loading Loading
fs/proc/base.c +117 −0 Original line number Diff line number Diff line Loading @@ -2874,6 +2874,121 @@ static int proc_tgid_io_accounting(struct seq_file *m, struct pid_namespace *ns, } #endif /* CONFIG_TASK_IO_ACCOUNTING */ #ifdef CONFIG_SCHED_WALT static ssize_t proc_sched_task_boost_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct task_struct *task = get_proc_task(file_inode(file)); char buffer[PROC_NUMBUF]; int sched_boost; size_t len; if (!task) return -ESRCH; sched_boost = task->boost; put_task_struct(task); len = scnprintf(buffer, sizeof(buffer), "%d\n", sched_boost); return simple_read_from_buffer(buf, count, ppos, buffer, len); } static ssize_t proc_sched_task_boost_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { struct task_struct *task = get_proc_task(file_inode(file)); char buffer[PROC_NUMBUF]; int sched_boost; int err; if (!task) return -ESRCH; memset(buffer, 0, sizeof(buffer)); if (count > sizeof(buffer) - 1) count = sizeof(buffer) - 1; if (copy_from_user(buffer, buf, count)) { err = -EFAULT; goto out; } err = kstrtoint(strstrip(buffer), 0, &sched_boost); if (err) goto out; if (sched_boost < TASK_BOOST_NONE || sched_boost >= TASK_BOOST_END) { err = -EINVAL; goto out; } task->boost = sched_boost; if (sched_boost == 0) task->boost_period = 0; out: put_task_struct(task); return err < 0 ? err : count; } static ssize_t proc_sched_task_boost_period_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct task_struct *task = get_proc_task(file_inode(file)); char buffer[PROC_NUMBUF]; u64 sched_boost_period_ms = 0; size_t len; if (!task) return -ESRCH; sched_boost_period_ms = div64_ul(task->boost_period, 1000000UL); put_task_struct(task); len = snprintf(buffer, sizeof(buffer), "%llu\n", sched_boost_period_ms); return simple_read_from_buffer(buf, count, ppos, buffer, len); } static ssize_t proc_sched_task_boost_period_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { struct task_struct *task = get_proc_task(file_inode(file)); char buffer[PROC_NUMBUF]; unsigned int sched_boost_period; int err; if (!task) return -ESRCH; memset(buffer, 0, sizeof(buffer)); if (count > sizeof(buffer) - 1) count = sizeof(buffer) - 1; if (copy_from_user(buffer, buf, count)) { err = -EFAULT; goto out; } err = kstrtouint(strstrip(buffer), 0, &sched_boost_period); if (err) goto out; if (task->boost == 0 && sched_boost_period) { /* setting boost period without boost is invalid */ err = -EINVAL; goto out; } task->boost_period = (u64)sched_boost_period * 1000 * 1000; task->boost_expires = sched_clock() + task->boost_period; out: put_task_struct(task); return err < 0 ? err : count; } static const struct file_operations proc_task_boost_enabled_operations = { .read = proc_sched_task_boost_read, .write = proc_sched_task_boost_write, .llseek = generic_file_llseek, }; static const struct file_operations proc_task_boost_period_operations = { .read = proc_sched_task_boost_period_read, .write = proc_sched_task_boost_period_write, .llseek = generic_file_llseek, }; #endif /* CONFIG_SCHED_WALT */ #ifdef CONFIG_USER_NS static int proc_id_map_open(struct inode *inode, struct file *file, const struct seq_operations *seq_ops) Loading Loading @@ -3067,6 +3182,8 @@ static const struct pid_entry tgid_base_stuff[] = { REG("sched_init_task_load", 00644, proc_pid_sched_init_task_load_operations), REG("sched_group_id", 00666, proc_pid_sched_group_id_operations), REG("sched_boost", 0666, proc_task_boost_enabled_operations), REG("sched_boost_period_ms", 0666, proc_task_boost_period_operations), #endif #ifdef CONFIG_SCHED_DEBUG REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), Loading
include/linux/sched.h +15 −0 Original line number Diff line number Diff line Loading @@ -129,6 +129,14 @@ enum fps { FPS120 = 120, }; enum task_boost_type { TASK_BOOST_NONE = 0, TASK_BOOST_ON_MID, TASK_BOOST_ON_MAX, TASK_BOOST_STRICT_MAX, TASK_BOOST_END, }; #ifdef CONFIG_DEBUG_ATOMIC_SLEEP /* Loading Loading @@ -540,6 +548,7 @@ extern void __weak sched_update_cpu_freq_min_max(const cpumask_t *cpus, u32 fmin, u32 fmax); extern void __weak free_task_load_ptrs(struct task_struct *p); extern void __weak sched_set_refresh_rate(enum fps fps); extern int set_task_boost(int boost, u64 period); #define RAVG_HIST_SIZE_MAX 5 #define NUM_BUSY_BUCKETS 10 Loading Loading @@ -607,6 +616,8 @@ static inline void sched_update_cpu_freq_min_max(const cpumask_t *cpus, u32 fmin, u32 fmax) { } static inline void sched_set_refresh_rate(enum fps fps) { } static inline void set_task_boost(int boost, u64 period) { } #endif /* CONFIG_SCHED_WALT */ struct sched_rt_entity { Loading Loading @@ -806,7 +817,11 @@ struct task_struct { const struct sched_class *sched_class; struct sched_entity se; struct sched_rt_entity rt; #ifdef CONFIG_SCHED_WALT int boost; u64 boost_period; u64 boost_expires; u64 last_sleep_ts; bool wake_up_idle; struct ravg ravg; Loading
include/linux/sched/topology.h +4 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,10 @@ struct sched_domain_shared { atomic_t ref; atomic_t nr_busy_cpus; int has_idle_cores; #ifdef CONFIG_SCHED_WALT bool overutilized; #endif }; struct sched_domain { Loading
include/trace/events/sched.h +8 −2 Original line number Diff line number Diff line Loading @@ -1017,6 +1017,7 @@ TRACE_EVENT(sched_task_util, __field(int, start_cpu) __field(int, unfilter) __field(unsigned long, cpus_allowed) __field(int, task_boost) ), TP_fast_assign( Loading @@ -1042,15 +1043,20 @@ TRACE_EVENT(sched_task_util, #endif __entry->cpus_allowed = cpumask_bits(&p->cpus_mask)[0]; #ifdef CONFIG_SCHED_WALT __entry->task_boost = per_task_boost(p); #else __entry->task_boost = 0; #endif ), TP_printk("pid=%d comm=%s util=%lu prev_cpu=%d candidates=%#lx best_energy_cpu=%d sync=%d need_idle=%d fastpath=%d placement_boost=%d latency=%llu stune_boosted=%d is_rtg=%d rtg_skip_min=%d start_cpu=%d unfilter=%d affinity=%lx", TP_printk("pid=%d comm=%s util=%lu prev_cpu=%d candidates=%#lx best_energy_cpu=%d sync=%d need_idle=%d fastpath=%d placement_boost=%d latency=%llu stune_boosted=%d is_rtg=%d rtg_skip_min=%d start_cpu=%d unfilter=%d affinity=%lx task_boost=%d", __entry->pid, __entry->comm, __entry->util, __entry->prev_cpu, __entry->candidates, __entry->best_energy_cpu, __entry->sync, __entry->need_idle, __entry->fastpath, __entry->placement_boost, __entry->latency, __entry->stune_boosted, __entry->is_rtg, __entry->rtg_skip_min, __entry->start_cpu, __entry->unfilter, __entry->cpus_allowed) __entry->unfilter, __entry->cpus_allowed, __entry->task_boost) ) /* Loading
kernel/sched/core.c +23 −0 Original line number Diff line number Diff line Loading @@ -2751,6 +2751,9 @@ static void __sched_fork(unsigned long clone_flags, struct task_struct *p) #ifdef CONFIG_SCHED_WALT p->last_sleep_ts = 0; p->wake_up_idle = false; p->boost = 0; p->boost_expires = 0; p->boost_period = 0; #endif INIT_LIST_HEAD(&p->se.group_node); Loading Loading @@ -8392,6 +8395,26 @@ void dequeue_task_core(struct rq *rq, struct task_struct *p, int flags) } #ifdef CONFIG_SCHED_WALT /* *@boost:should be 0,1,2. *@period:boost time based on ms units. */ int set_task_boost(int boost, u64 period) { if (boost < TASK_BOOST_NONE || boost >= TASK_BOOST_END) return -EINVAL; if (boost) { current->boost = boost; current->boost_period = (u64)period * 1000 * 1000; current->boost_expires = sched_clock() + current->boost_period; } else { current->boost = 0; current->boost_expires = 0; current->boost_period = 0; } return 0; } void sched_account_irqtime(int cpu, struct task_struct *curr, u64 delta, u64 wallclock) { Loading