From b634e6299e2ac8867a3478871fbad4cc0a7176b8 Mon Sep 17 00:00:00 2001 From: Stephen Dickey Date: Tue, 27 Jul 2021 15:52:10 -0700 Subject: [PATCH] sched/walt: sysctl node to allow capture of walt issues It is necessary to maintain debug checks in the walt code while preventing errant crashes in released code. Create a sysctl node that will control whether walt issues will crash the system, and create a macro to take advantage of it. Support the debug strings required by walt, so that this can be easily incorporated into walt files. Change-Id: Ie81cefe3c6d730574599f8d804d010f4a917bba7 Signed-off-by: Stephen Dickey --- kernel/sched/walt/sysctl.c | 10 ++++++ kernel/sched/walt/walt.c | 64 ++++++++++++++++++------------------ kernel/sched/walt/walt.h | 19 ++++++++++- kernel/sched/walt/walt_cfs.c | 4 +-- 4 files changed, 62 insertions(+), 35 deletions(-) diff --git a/kernel/sched/walt/sysctl.c b/kernel/sched/walt/sysctl.c index 8bfe41973a78..6e559502a28f 100644 --- a/kernel/sched/walt/sysctl.c +++ b/kernel/sched/walt/sysctl.c @@ -61,6 +61,7 @@ unsigned int sysctl_sched_many_wakeup_threshold = WALT_MANY_WAKEUP_DEFAULT; const int sched_user_hint_max = 1000; unsigned int sysctl_walt_rtg_cfs_boost_prio = 99; /* disabled by default */ unsigned int sysctl_sched_sync_hint_enable = 1; +unsigned int sysctl_panic_on_walt_bug; /* range is [1 .. INT_MAX] */ static int sysctl_task_read_pid = 1; @@ -711,6 +712,15 @@ struct ctl_table walt_table[] = { .extra1 = SYSCTL_ZERO, .extra2 = SYSCTL_ONE, }, + { + .procname = "panic_on_walt_bug", + .data = &sysctl_panic_on_walt_bug, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, + .extra1 = SYSCTL_ZERO, + .extra2 = SYSCTL_INT_MAX, + }, { .procname = "sched_lib_name", .data = sched_lib_name, diff --git a/kernel/sched/walt/walt.c b/kernel/sched/walt/walt.c index 128636ceb12a..fd35652ff5e0 100644 --- a/kernel/sched/walt/walt.c +++ b/kernel/sched/walt/walt.c @@ -296,7 +296,7 @@ fixup_cumulative_runnable_avg(struct rq *rq, printk_deferred("WALT-BUG on CPU %d task %s(%d) not on rq %d", raw_smp_processor_id(), p->comm, p->pid, rq->cpu); walt_task_dump(p); - SCHED_BUG_ON(1); + WALT_PANIC(1); } if (cumulative_runnable_avg_scaled < 0) { @@ -304,7 +304,7 @@ fixup_cumulative_runnable_avg(struct rq *rq, raw_smp_processor_id(), wts->demand_scaled, stats->cumulative_runnable_avg_scaled); walt_task_dump(p); - SCHED_BUG_ON(1); + WALT_PANIC(1); } stats->cumulative_runnable_avg_scaled = (u64)cumulative_runnable_avg_scaled; @@ -313,7 +313,7 @@ fixup_cumulative_runnable_avg(struct rq *rq, raw_smp_processor_id(), wts->pred_demand_scaled, stats->pred_demands_sum_scaled); walt_task_dump(p); - SCHED_BUG_ON(1); + WALT_PANIC(1); } stats->pred_demands_sum_scaled = (u64)pred_demands_sum_scaled; } @@ -390,7 +390,7 @@ update_window_start(struct rq *rq, u64 wallclock, int event) if (delta < 0) { printk_deferred("WALT-BUG CPU%d; wallclock=%llu is lesser than window_start=%llu", rq->cpu, wallclock, wrq->window_start); - SCHED_BUG_ON(1); + WALT_PANIC(1); } if (delta < sched_ravg_window) return old_window_start; @@ -699,10 +699,10 @@ static inline void account_load_subtractions(struct rq *rq) ls[i].new_subs = 0; } - SCHED_BUG_ON((s64)wrq->prev_runnable_sum < 0); - SCHED_BUG_ON((s64)wrq->curr_runnable_sum < 0); - SCHED_BUG_ON((s64)wrq->nt_prev_runnable_sum < 0); - SCHED_BUG_ON((s64)wrq->nt_curr_runnable_sum < 0); + WALT_PANIC((s64)wrq->prev_runnable_sum < 0); + WALT_PANIC((s64)wrq->curr_runnable_sum < 0); + WALT_PANIC((s64)wrq->nt_prev_runnable_sum < 0); + WALT_PANIC((s64)wrq->nt_curr_runnable_sum < 0); } static inline void create_subtraction_entry(struct rq *rq, u64 ws, int index) @@ -816,7 +816,7 @@ static inline void inter_cluster_migration_fixup src_wrq->curr_runnable_sum, wts->curr_window_cpu[task_cpu]); walt_task_dump(p); - SCHED_BUG_ON(1); + WALT_PANIC(1); } src_wrq->curr_runnable_sum -= wts->curr_window_cpu[task_cpu]; @@ -826,7 +826,7 @@ static inline void inter_cluster_migration_fixup src_wrq->prev_runnable_sum, wts->prev_window_cpu[task_cpu]); walt_task_dump(p); - SCHED_BUG_ON(1); + WALT_PANIC(1); } src_wrq->prev_runnable_sum -= wts->prev_window_cpu[task_cpu]; @@ -841,7 +841,7 @@ static inline void inter_cluster_migration_fixup src_wrq->nt_curr_runnable_sum, wts->curr_window_cpu[task_cpu]); walt_task_dump(p); - SCHED_BUG_ON(1); + WALT_PANIC(1); } src_wrq->nt_curr_runnable_sum -= wts->curr_window_cpu[task_cpu]; @@ -853,7 +853,7 @@ static inline void inter_cluster_migration_fixup src_wrq->nt_prev_runnable_sum, wts->prev_window_cpu[task_cpu]); walt_task_dump(p); - SCHED_BUG_ON(1); + WALT_PANIC(1); } src_wrq->nt_prev_runnable_sum -= wts->prev_window_cpu[task_cpu]; @@ -978,7 +978,7 @@ static void fixup_busy_time(struct task_struct *p, int new_cpu) if (task_rq(p) != src_rq) { printk_deferred("WALT-BUG on CPU %d task %s(%d) not on src_rq %d", raw_smp_processor_id(), p->comm, p->pid, src_rq->cpu); - SCHED_BUG_ON(1); + WALT_PANIC(1); } walt_update_task_ravg(task_rq(p)->curr, task_rq(p), @@ -1754,7 +1754,7 @@ static void update_cpu_busy_time(struct task_struct *p, struct rq *rq, * started at wallclock - irqtime. */ - SCHED_BUG_ON(!is_idle_task(p)); + WALT_PANIC(!is_idle_task(p)); mark_start = wallclock - irqtime; /* @@ -2123,7 +2123,7 @@ update_task_rq_cpu_cycles(struct task_struct *p, struct rq *rq, int event, printk_deferred("WALT-BUG pid=%u CPU%d wallclock=%llu < mark_start=%llu event=%d irqtime=%llu", p->pid, rq->cpu, wallclock, wts->mark_start, event, irqtime); - SCHED_BUG_ON((s64)time_delta < 0); + WALT_PANIC((s64)time_delta < 0); } wrq->task_exec_scale = DIV64_U64_ROUNDUP(cycles_delta * @@ -2448,13 +2448,13 @@ static void init_cpu_array(void) cpu_array = kcalloc(num_sched_clusters, sizeof(cpumask_t *), GFP_ATOMIC | __GFP_NOFAIL); if (!cpu_array) - SCHED_BUG_ON(1); + WALT_PANIC(1); for (i = 0; i < num_sched_clusters; i++) { cpu_array[i] = kcalloc(num_sched_clusters, sizeof(cpumask_t), GFP_ATOMIC | __GFP_NOFAIL); if (!cpu_array[i]) - SCHED_BUG_ON(1); + WALT_PANIC(1); } } @@ -2463,7 +2463,7 @@ static void build_cpu_array(void) int i; if (!cpu_array) - SCHED_BUG_ON(1); + WALT_PANIC(1); /* Construct cpu_array row by row */ for (i = 0; i < num_sched_clusters; i++) { int j, k = 1; @@ -2578,7 +2578,7 @@ static void walt_update_cluster_topology(void) * walt_update_cluster_topology() must be called AFTER policies * for all cpus are initialized. If not, simply BUG(). */ - SCHED_BUG_ON(!policy); + WALT_PANIC(!policy); if (policy) { cluster->max_possible_freq = policy->cpuinfo.max_freq; @@ -3169,7 +3169,7 @@ static void transfer_busy_time(struct rq *rq, p->pid, cpu, event, *src_curr_runnable_sum, wts->curr_window_cpu[cpu]); walt_task_dump(p); - SCHED_BUG_ON(1); + WALT_PANIC(1); } *src_curr_runnable_sum -= wts->curr_window_cpu[cpu]; @@ -3178,7 +3178,7 @@ static void transfer_busy_time(struct rq *rq, p->pid, cpu, event, *src_prev_runnable_sum, wts->prev_window_cpu[cpu]); walt_task_dump(p); - SCHED_BUG_ON(1); + WALT_PANIC(1); } *src_prev_runnable_sum -= wts->prev_window_cpu[cpu]; @@ -3190,7 +3190,7 @@ static void transfer_busy_time(struct rq *rq, *src_nt_curr_runnable_sum, wts->curr_window_cpu[cpu]); walt_task_dump(p); - SCHED_BUG_ON(1); + WALT_PANIC(1); } *src_nt_curr_runnable_sum -= wts->curr_window_cpu[cpu]; @@ -3202,7 +3202,7 @@ static void transfer_busy_time(struct rq *rq, *src_nt_prev_runnable_sum, wts->prev_window_cpu[cpu]); walt_task_dump(p); - SCHED_BUG_ON(1); + WALT_PANIC(1); } *src_nt_prev_runnable_sum -= wts->prev_window_cpu[cpu]; @@ -3229,7 +3229,7 @@ static void transfer_busy_time(struct rq *rq, p->pid, cpu, event, *src_curr_runnable_sum, wts->curr_window); walt_task_dump(p); - SCHED_BUG_ON(1); + WALT_PANIC(1); } *src_curr_runnable_sum -= wts->curr_window; @@ -3238,7 +3238,7 @@ static void transfer_busy_time(struct rq *rq, p->pid, cpu, event, *src_prev_runnable_sum, wts->prev_window); walt_task_dump(p); - SCHED_BUG_ON(1); + WALT_PANIC(1); } *src_prev_runnable_sum -= wts->prev_window; @@ -3249,7 +3249,7 @@ static void transfer_busy_time(struct rq *rq, *src_nt_curr_runnable_sum, wts->curr_window); walt_task_dump(p); - SCHED_BUG_ON(1); + WALT_PANIC(1); } *src_nt_curr_runnable_sum -= wts->curr_window; @@ -3259,7 +3259,7 @@ static void transfer_busy_time(struct rq *rq, *src_nt_prev_runnable_sum, wts->prev_window); walt_task_dump(p); - SCHED_BUG_ON(1); + WALT_PANIC(1); } *src_nt_prev_runnable_sum -= wts->prev_window; } @@ -3840,7 +3840,7 @@ static void android_rvh_enqueue_task(void *unused, struct rq *rq, struct task_st printk_deferred("WALT-BUG enqueuing on rq %d when task->cpu is %d\n", cpu_of(rq), p->cpu); walt_task_dump(p); - SCHED_BUG_ON(1); + WALT_PANIC(1); } /* catch double enqueue */ @@ -3848,7 +3848,7 @@ static void android_rvh_enqueue_task(void *unused, struct rq *rq, struct task_st printk_deferred("WALT-BUG double enqueue detected: task_cpu=%d new_cpu=%d\n", task_cpu(p), cpu_of(rq)); walt_task_dump(p); - SCHED_BUG_ON(1); + WALT_PANIC(1); } wts->prev_on_rq = 1; wts->prev_on_rq_cpu = cpu_of(rq); @@ -3885,7 +3885,7 @@ static void android_rvh_dequeue_task(void *unused, struct rq *rq, struct task_st printk_deferred("WALT-BUG dequeue cpu %d not same as enqueue %d\n", cpu_of(rq), wts->prev_on_rq_cpu); walt_task_dump(p); - SCHED_BUG_ON(1); + WALT_PANIC(1); } /* no longer on a cpu */ @@ -3896,7 +3896,7 @@ static void android_rvh_dequeue_task(void *unused, struct rq *rq, struct task_st printk_deferred("WALT-BUG double dequeue detected: task_cpu=%d new_cpu=%d\n", task_cpu(p), cpu_of(rq)); walt_task_dump(p); - SCHED_BUG_ON(1); + WALT_PANIC(1); } wts->prev_on_rq = 2; @@ -4043,7 +4043,7 @@ static void android_rvh_schedule(void *unused, struct task_struct *prev, if (is_idle_task(next)) if (wrq->walt_stats.cumulative_runnable_avg_scaled != 0) { printk_deferred("WALT-BUG next=idle cra!=0\n"); - SCHED_BUG_ON(1); + WALT_PANIC(1); } } else { walt_update_task_ravg(prev, rq, TASK_UPDATE, wallclock, 0); diff --git a/kernel/sched/walt/walt.h b/kernel/sched/walt/walt.h index cb992ba262a0..f4fb1653472d 100644 --- a/kernel/sched/walt/walt.h +++ b/kernel/sched/walt/walt.h @@ -230,6 +230,7 @@ extern unsigned int sysctl_walt_rtg_cfs_boost_prio; extern __read_mostly unsigned int sysctl_sched_force_lb_enable; extern const int sched_user_hint_max; extern unsigned int sysctl_sched_dynamic_tp_enable; +extern unsigned int sysctl_panic_on_walt_bug; extern int sched_dynamic_tp_handler(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos); @@ -907,7 +908,7 @@ extern void walt_rq_dump(int cpu); extern void walt_dump(void); extern int in_sched_bug; -#define SCHED_BUG_ON(condition) \ +#define WALT_PANIC(condition) \ ({ \ if (unlikely(!!(condition)) && !in_sched_bug) { \ in_sched_bug = 1; \ @@ -916,4 +917,20 @@ extern int in_sched_bug; } \ }) +#define WALT_PANIC_SENTINEL 0x4544DEAD + +/* + * crash if walt bugs are fatal, otherwise return immediately. + * output format and arguments to console + */ +#define WALT_BUG(p, format, args...) \ +({ \ + if (unlikely(sysctl_panic_on_walt_bug == WALT_PANIC_SENTINEL)) {\ + printk_deferred("WALT-BUG " format, args); \ + if (p) \ + walt_task_dump(p); \ + WALT_PANIC(1); \ + } \ +}) + #endif /* _WALT_H */ diff --git a/kernel/sched/walt/walt_cfs.c b/kernel/sched/walt/walt_cfs.c index 9a463143cb73..6ada1faf6507 100644 --- a/kernel/sched/walt/walt_cfs.c +++ b/kernel/sched/walt/walt_cfs.c @@ -1216,7 +1216,7 @@ static void walt_cfs_replace_next_task_fair(void *unused, struct rq *rq, struct printk_deferred("WALT-BUG picked %s(%d) on_cpu=%d on_rq=%d p->cpu=%d cpu_of(rq)=%d kthread=%d\n", (*p)->comm, (*p)->pid, (*p)->on_cpu, (*p)->on_rq, (*p)->cpu, cpu_of(rq), ((*p)->flags & PF_KTHREAD)); - SCHED_BUG_ON(1); + WALT_PANIC(1); } /* We don't have MVP tasks queued */ @@ -1237,7 +1237,7 @@ static void walt_cfs_replace_next_task_fair(void *unused, struct rq *rq, struct printk_deferred("WALT-BUG picked %s(%d) on_cpu=%d on_rq=%d p->cpu=%d cpu_of(rq)=%d kthread=%d\n", (*p)->comm, (*p)->pid, (*p)->on_cpu, (*p)->on_rq, (*p)->cpu, cpu_of(rq), ((*p)->flags & PF_KTHREAD)); - SCHED_BUG_ON(1); + WALT_PANIC(1); } trace_walt_cfs_mvp_pick_next(mvp, wts, walt_cfs_mvp_task_limit(mvp));