diff options
| author | Joonwoo Park <joonwoop@codeaurora.org> | 2016-04-28 15:22:12 -0700 |
|---|---|---|
| committer | Kyle Yan <kyan@codeaurora.org> | 2016-06-09 15:07:35 -0700 |
| commit | 54c0b0001b508a5dbd383cdf6e24e01064b32bbd (patch) | |
| tree | 2eebefcdf261e4d45710f88e8a9eba68533de051 /kernel/sched | |
| parent | 28e33ce739bca5f7e5aef4f4fd6282aa5300e67d (diff) | |
sched: preserve CPU cycle counter in rq
Preserve cycle counter in rq in preparation for wait time accounting
while CPU idle fix.
Change-Id: I469263c90e12f39bb36bde5ed26298b7c1c77597
Signed-off-by: Joonwoo Park <joonwoop@codeaurora.org>
Diffstat (limited to 'kernel/sched')
| -rw-r--r-- | kernel/sched/core.c | 119 | ||||
| -rw-r--r-- | kernel/sched/sched.h | 6 |
2 files changed, 55 insertions, 70 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index e145b5640b12..0da080688ddd 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1745,11 +1745,6 @@ static void update_cluster_topology(void) { } #define SCHED_MIN_FREQ 1 -struct cpu_cycle { - u64 cycles; - u64 time; -}; - #if defined(CONFIG_SCHED_HMP) /* @@ -1942,14 +1937,13 @@ update_window_start(struct rq *rq, u64 wallclock) #define DIV64_U64_ROUNDUP(X, Y) div64_u64((X) + (Y - 1), Y) -static inline u64 scale_exec_time(u64 delta, struct rq *rq, - const struct cpu_cycle *cc) +static inline u64 scale_exec_time(u64 delta, struct rq *rq) { int cpu = cpu_of(rq); int sf; - delta = DIV64_U64_ROUNDUP(delta * cc->cycles, - max_possible_freq * cc->time); + delta = DIV64_U64_ROUNDUP(delta * rq->cc.cycles, + max_possible_freq * rq->cc.time); sf = DIV_ROUND_UP(cpu_efficiency(cpu) * 1024, max_possible_efficiency); delta *= sf; @@ -2393,8 +2387,7 @@ void update_task_pred_demand(struct rq *rq, struct task_struct *p, int event) * Account cpu activity in its busy time counters (rq->curr/prev_runnable_sum) */ static void update_cpu_busy_time(struct task_struct *p, struct rq *rq, - int event, u64 wallclock, u64 irqtime, - const struct cpu_cycle *cc) + int event, u64 wallclock, u64 irqtime) { int new_window, nr_full_windows = 0; int p_is_curr_task = (p == rq->curr); @@ -2527,7 +2520,7 @@ static void update_cpu_busy_time(struct task_struct *p, struct rq *rq, delta = wallclock - mark_start; else delta = irqtime; - delta = scale_exec_time(delta, rq, cc); + delta = scale_exec_time(delta, rq); *curr_runnable_sum += delta; if (new_task) *nt_curr_runnable_sum += delta; @@ -2553,15 +2546,14 @@ static void update_cpu_busy_time(struct task_struct *p, struct rq *rq, if (!nr_full_windows) { /* A full window hasn't elapsed, account partial * contribution to previous completed window. */ - delta = scale_exec_time(window_start - mark_start, rq, - cc); + delta = scale_exec_time(window_start - mark_start, rq); if (!exiting_task(p)) p->ravg.prev_window += delta; } else { /* Since at least one full window has elapsed, * the contribution to the previous window is the * full window (window_size). */ - delta = scale_exec_time(window_size, rq, cc); + delta = scale_exec_time(window_size, rq); if (!exiting_task(p)) p->ravg.prev_window = delta; } @@ -2571,7 +2563,7 @@ static void update_cpu_busy_time(struct task_struct *p, struct rq *rq, *nt_prev_runnable_sum += delta; /* Account piece of busy time in the current window. */ - delta = scale_exec_time(wallclock - window_start, rq, cc); + delta = scale_exec_time(wallclock - window_start, rq); *curr_runnable_sum += delta; if (new_task) *nt_curr_runnable_sum += delta; @@ -2598,15 +2590,14 @@ static void update_cpu_busy_time(struct task_struct *p, struct rq *rq, if (!nr_full_windows) { /* A full window hasn't elapsed, account partial * contribution to previous completed window. */ - delta = scale_exec_time(window_start - mark_start, rq, - cc); + delta = scale_exec_time(window_start - mark_start, rq); if (!is_idle_task(p) && !exiting_task(p)) p->ravg.prev_window += delta; } else { /* Since at least one full window has elapsed, * the contribution to the previous window is the * full window (window_size). */ - delta = scale_exec_time(window_size, rq, cc); + delta = scale_exec_time(window_size, rq); if (!is_idle_task(p) && !exiting_task(p)) p->ravg.prev_window = delta; } @@ -2618,7 +2609,7 @@ static void update_cpu_busy_time(struct task_struct *p, struct rq *rq, *nt_prev_runnable_sum += delta; /* Account piece of busy time in the current window. */ - delta = scale_exec_time(wallclock - window_start, rq, cc); + delta = scale_exec_time(wallclock - window_start, rq); *curr_runnable_sum += delta; if (new_task) *nt_curr_runnable_sum += delta; @@ -2646,7 +2637,7 @@ static void update_cpu_busy_time(struct task_struct *p, struct rq *rq, /* Roll window over. If IRQ busy time was just in the current * window then that is all that need be accounted. */ if (mark_start > window_start) { - *curr_runnable_sum = scale_exec_time(irqtime, rq, cc); + *curr_runnable_sum = scale_exec_time(irqtime, rq); return; } @@ -2655,12 +2646,12 @@ static void update_cpu_busy_time(struct task_struct *p, struct rq *rq, delta = window_start - mark_start; if (delta > window_size) delta = window_size; - delta = scale_exec_time(delta, rq, cc); + delta = scale_exec_time(delta, rq); *prev_runnable_sum += delta; /* Process the remaining IRQ busy time in the current window. */ delta = wallclock - window_start; - rq->curr_runnable_sum = scale_exec_time(delta, rq, cc); + rq->curr_runnable_sum = scale_exec_time(delta, rq); return; } @@ -2690,7 +2681,7 @@ update_task_pred_demand(struct rq *rq, struct task_struct *p, int event) } static inline void update_cpu_busy_time(struct task_struct *p, struct rq *rq, - int event, u64 wallclock, u64 irqtime, const struct cpu_cycle *cc) + int event, u64 wallclock, u64 irqtime) { } @@ -2709,34 +2700,33 @@ static void update_task_cpu_cycles(struct task_struct *p, int cpu) p->cpu_cycles = cpu_cycle_counter_cb.get_cpu_cycle_counter(cpu); } -static struct cpu_cycle -get_task_cpu_cycles(struct task_struct *p, struct rq *rq, int event, - u64 wallclock) +static void +update_task_rq_cpu_cycles(struct task_struct *p, struct rq *rq, int event, + u64 wallclock) { u64 cur_cycles; - struct cpu_cycle cc; int cpu = cpu_of(rq); + lockdep_assert_held(&rq->lock); + if (!use_cycle_counter) { - cc.cycles = cpu_cur_freq(cpu); - cc.time = 1; - return cc; + rq->cc.cycles = cpu_cur_freq(cpu); + rq->cc.time = 1; + return; } cur_cycles = cpu_cycle_counter_cb.get_cpu_cycle_counter(cpu); if (unlikely(cur_cycles < p->cpu_cycles)) - cc.cycles = cur_cycles + (U64_MAX - p->cpu_cycles); + rq->cc.cycles = cur_cycles + (U64_MAX - p->cpu_cycles); else - cc.cycles = cur_cycles - p->cpu_cycles; - cc.cycles = cc.cycles * NSEC_PER_MSEC; - cc.time = wallclock - p->ravg.mark_start; - BUG_ON((s64)cc.time < 0); + rq->cc.cycles = cur_cycles - p->cpu_cycles; + rq->cc.cycles = rq->cc.cycles * NSEC_PER_MSEC; + rq->cc.time = wallclock - p->ravg.mark_start; + BUG_ON((s64)rq->cc.time < 0); p->cpu_cycles = cur_cycles; - trace_sched_get_task_cpu_cycles(cpu, event, cc.cycles, cc.time); - - return cc; + trace_sched_get_task_cpu_cycles(cpu, event, rq->cc.cycles, rq->cc.time); } static int account_busy_for_task_demand(struct task_struct *p, int event) @@ -2824,10 +2814,9 @@ done: trace_sched_update_history(rq, p, runtime, samples, event); } -static void add_to_task_demand(struct rq *rq, struct task_struct *p, - u64 delta, const struct cpu_cycle *cc) +static void add_to_task_demand(struct rq *rq, struct task_struct *p, u64 delta) { - delta = scale_exec_time(delta, rq, cc); + delta = scale_exec_time(delta, rq); p->ravg.sum += delta; if (unlikely(p->ravg.sum > sched_ravg_window)) p->ravg.sum = sched_ravg_window; @@ -2884,8 +2873,7 @@ static void add_to_task_demand(struct rq *rq, struct task_struct *p, * depends on it! */ static void update_task_demand(struct task_struct *p, struct rq *rq, - int event, u64 wallclock, - const struct cpu_cycle *cc) + int event, u64 wallclock) { u64 mark_start = p->ravg.mark_start; u64 delta, window_start = rq->window_start; @@ -2908,7 +2896,7 @@ static void update_task_demand(struct task_struct *p, struct rq *rq, if (!new_window) { /* The simple case - busy time contained within the existing * window. */ - add_to_task_demand(rq, p, wallclock - mark_start, cc); + add_to_task_demand(rq, p, wallclock - mark_start); return; } @@ -2919,12 +2907,12 @@ static void update_task_demand(struct task_struct *p, struct rq *rq, window_start -= (u64)nr_full_windows * (u64)window_size; /* Process (window_start - mark_start) first */ - add_to_task_demand(rq, p, window_start - mark_start, cc); + add_to_task_demand(rq, p, window_start - mark_start); /* Push new sample(s) into task's demand history */ update_history(rq, p, p->ravg.sum, 1, event); if (nr_full_windows) - update_history(rq, p, scale_exec_time(window_size, rq, cc), + update_history(rq, p, scale_exec_time(window_size, rq), nr_full_windows, event); /* Roll window_start back to current to process any remainder @@ -2933,18 +2921,16 @@ static void update_task_demand(struct task_struct *p, struct rq *rq, /* Process (wallclock - window_start) next */ mark_start = window_start; - add_to_task_demand(rq, p, wallclock - mark_start, cc); + add_to_task_demand(rq, p, wallclock - mark_start); } /* Reflect task activity on its demand and cpu's busy time statistics */ -static struct cpu_cycle +static void update_task_ravg(struct task_struct *p, struct rq *rq, int event, u64 wallclock, u64 irqtime) { - struct cpu_cycle cc = { .cycles = SCHED_MIN_FREQ, .time = 1 }; - if (sched_use_pelt || !rq->window_start || sched_disable_window_stats) - return cc; + return; lockdep_assert_held(&rq->lock); @@ -2955,18 +2941,16 @@ update_task_ravg(struct task_struct *p, struct rq *rq, int event, goto done; } - cc = get_task_cpu_cycles(p, rq, event, wallclock); - update_task_demand(p, rq, event, wallclock, &cc); - update_cpu_busy_time(p, rq, event, wallclock, irqtime, &cc); + update_task_rq_cpu_cycles(p, rq, event, wallclock); + update_task_demand(p, rq, event, wallclock); + update_cpu_busy_time(p, rq, event, wallclock, irqtime); update_task_pred_demand(rq, p, event); done: trace_sched_update_task_ravg(p, rq, event, wallclock, irqtime, - cc.cycles, cc.time, + rq->cc.cycles, rq->cc.time, _group_cpu_time(p->grp, cpu_of(rq))); p->ravg.mark_start = wallclock; - - return cc; } void sched_account_irqtime(int cpu, struct task_struct *curr, @@ -3259,7 +3243,6 @@ void sched_get_cpus_busy(struct sched_load *busy, int early_detection[cpus]; int cpu, i = 0; unsigned int window_size; - struct cpu_cycle cc; u64 max_prev_sum = 0; int max_busy_cpu = cpumask_first(query_cpus); struct related_thread_group *grp; @@ -3283,9 +3266,9 @@ void sched_get_cpus_busy(struct sched_load *busy, for_each_cpu(cpu, query_cpus) { rq = cpu_rq(cpu); - cc = update_task_ravg(rq->curr, rq, TASK_UPDATE, - sched_ktime_clock(), 0); - cur_freq[i] = cpu_cycles_to_freq(i, cc.cycles, cc.time); + update_task_ravg(rq->curr, rq, TASK_UPDATE, sched_ktime_clock(), + 0); + cur_freq[i] = cpu_cycles_to_freq(i, rq->cc.cycles, rq->cc.time); load[i] = rq->old_busy_time = rq->prev_runnable_sum; nload[i] = rq->nt_prev_runnable_sum; @@ -3644,7 +3627,7 @@ static void set_preferred_cluster(struct related_thread_group *grp) #ifdef CONFIG_SCHED_FREQ_INPUT -static struct cpu_cycle +static void update_task_ravg(struct task_struct *p, struct rq *rq, int event, u64 wallclock, u64 irqtime); @@ -4222,16 +4205,10 @@ static inline int update_preferred_cluster(struct related_thread_group *grp, static inline void fixup_busy_time(struct task_struct *p, int new_cpu) { } -static struct cpu_cycle +static void update_task_ravg(struct task_struct *p, struct rq *rq, int event, u64 wallclock, u64 irqtime) { - static const struct cpu_cycle cc = { - .cycles = SCHED_MIN_FREQ, - .time = 1 - }; - - return cc; } static inline void mark_task_starting(struct task_struct *p) {} @@ -10962,6 +10939,8 @@ void __init sched_init(void) rq->avg_irqload = 0; rq->irqload_ts = 0; rq->static_cpu_pwr_cost = 0; + rq->cc.cycles = SCHED_MIN_FREQ; + rq->cc.time = 1; /* * All cpus part of same cluster by default. This avoids the diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 3d5a89cc6eef..7c5fd1ca78bc 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -427,6 +427,11 @@ extern struct sched_cluster *sched_cluster[NR_CPUS]; extern int group_will_fit(struct sched_cluster *cluster, struct related_thread_group *grp, u64 demand); +struct cpu_cycle { + u64 cycles; + u64 time; +}; + #define for_each_sched_cluster(cluster) \ list_for_each_entry_rcu(cluster, &cluster_head, list) @@ -749,6 +754,7 @@ struct rq { u64 irqload_ts; unsigned int static_cpu_pwr_cost; struct task_struct *ed_task; + struct cpu_cycle cc; #ifdef CONFIG_SCHED_FREQ_INPUT u64 old_busy_time, old_busy_time_group; |
