diff options
Diffstat (limited to 'kernel/sched.c')
-rw-r--r-- | kernel/sched.c | 63 |
1 files changed, 37 insertions, 26 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index b0afd8db1396..45e17b83b7f1 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -263,6 +263,7 @@ struct rq { | |||
263 | 263 | ||
264 | unsigned int clock_warps, clock_overflows; | 264 | unsigned int clock_warps, clock_overflows; |
265 | unsigned int clock_unstable_events; | 265 | unsigned int clock_unstable_events; |
266 | u64 tick_timestamp; | ||
266 | 267 | ||
267 | atomic_t nr_iowait; | 268 | atomic_t nr_iowait; |
268 | 269 | ||
@@ -341,8 +342,11 @@ static void __update_rq_clock(struct rq *rq) | |||
341 | /* | 342 | /* |
342 | * Catch too large forward jumps too: | 343 | * Catch too large forward jumps too: |
343 | */ | 344 | */ |
344 | if (unlikely(delta > 2*TICK_NSEC)) { | 345 | if (unlikely(clock + delta > rq->tick_timestamp + TICK_NSEC)) { |
345 | clock++; | 346 | if (clock < rq->tick_timestamp + TICK_NSEC) |
347 | clock = rq->tick_timestamp + TICK_NSEC; | ||
348 | else | ||
349 | clock++; | ||
346 | rq->clock_overflows++; | 350 | rq->clock_overflows++; |
347 | } else { | 351 | } else { |
348 | if (unlikely(delta > rq->clock_max_delta)) | 352 | if (unlikely(delta > rq->clock_max_delta)) |
@@ -3102,7 +3106,7 @@ static void run_rebalance_domains(struct softirq_action *h) | |||
3102 | if (need_resched()) | 3106 | if (need_resched()) |
3103 | break; | 3107 | break; |
3104 | 3108 | ||
3105 | rebalance_domains(balance_cpu, SCHED_IDLE); | 3109 | rebalance_domains(balance_cpu, CPU_IDLE); |
3106 | 3110 | ||
3107 | rq = cpu_rq(balance_cpu); | 3111 | rq = cpu_rq(balance_cpu); |
3108 | if (time_after(this_rq->next_balance, rq->next_balance)) | 3112 | if (time_after(this_rq->next_balance, rq->next_balance)) |
@@ -3308,9 +3312,16 @@ void scheduler_tick(void) | |||
3308 | int cpu = smp_processor_id(); | 3312 | int cpu = smp_processor_id(); |
3309 | struct rq *rq = cpu_rq(cpu); | 3313 | struct rq *rq = cpu_rq(cpu); |
3310 | struct task_struct *curr = rq->curr; | 3314 | struct task_struct *curr = rq->curr; |
3315 | u64 next_tick = rq->tick_timestamp + TICK_NSEC; | ||
3311 | 3316 | ||
3312 | spin_lock(&rq->lock); | 3317 | spin_lock(&rq->lock); |
3313 | __update_rq_clock(rq); | 3318 | __update_rq_clock(rq); |
3319 | /* | ||
3320 | * Let rq->clock advance by at least TICK_NSEC: | ||
3321 | */ | ||
3322 | if (unlikely(rq->clock < next_tick)) | ||
3323 | rq->clock = next_tick; | ||
3324 | rq->tick_timestamp = rq->clock; | ||
3314 | update_cpu_load(rq); | 3325 | update_cpu_load(rq); |
3315 | if (curr != rq->idle) /* FIXME: needed? */ | 3326 | if (curr != rq->idle) /* FIXME: needed? */ |
3316 | curr->sched_class->task_tick(rq, curr); | 3327 | curr->sched_class->task_tick(rq, curr); |
@@ -6317,7 +6328,7 @@ int partition_sched_domains(cpumask_t *partition1, cpumask_t *partition2) | |||
6317 | } | 6328 | } |
6318 | 6329 | ||
6319 | #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT) | 6330 | #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT) |
6320 | int arch_reinit_sched_domains(void) | 6331 | static int arch_reinit_sched_domains(void) |
6321 | { | 6332 | { |
6322 | int err; | 6333 | int err; |
6323 | 6334 | ||
@@ -6346,24 +6357,6 @@ static ssize_t sched_power_savings_store(const char *buf, size_t count, int smt) | |||
6346 | return ret ? ret : count; | 6357 | return ret ? ret : count; |
6347 | } | 6358 | } |
6348 | 6359 | ||
6349 | int sched_create_sysfs_power_savings_entries(struct sysdev_class *cls) | ||
6350 | { | ||
6351 | int err = 0; | ||
6352 | |||
6353 | #ifdef CONFIG_SCHED_SMT | ||
6354 | if (smt_capable()) | ||
6355 | err = sysfs_create_file(&cls->kset.kobj, | ||
6356 | &attr_sched_smt_power_savings.attr); | ||
6357 | #endif | ||
6358 | #ifdef CONFIG_SCHED_MC | ||
6359 | if (!err && mc_capable()) | ||
6360 | err = sysfs_create_file(&cls->kset.kobj, | ||
6361 | &attr_sched_mc_power_savings.attr); | ||
6362 | #endif | ||
6363 | return err; | ||
6364 | } | ||
6365 | #endif | ||
6366 | |||
6367 | #ifdef CONFIG_SCHED_MC | 6360 | #ifdef CONFIG_SCHED_MC |
6368 | static ssize_t sched_mc_power_savings_show(struct sys_device *dev, char *page) | 6361 | static ssize_t sched_mc_power_savings_show(struct sys_device *dev, char *page) |
6369 | { | 6362 | { |
@@ -6374,8 +6367,8 @@ static ssize_t sched_mc_power_savings_store(struct sys_device *dev, | |||
6374 | { | 6367 | { |
6375 | return sched_power_savings_store(buf, count, 0); | 6368 | return sched_power_savings_store(buf, count, 0); |
6376 | } | 6369 | } |
6377 | SYSDEV_ATTR(sched_mc_power_savings, 0644, sched_mc_power_savings_show, | 6370 | static SYSDEV_ATTR(sched_mc_power_savings, 0644, sched_mc_power_savings_show, |
6378 | sched_mc_power_savings_store); | 6371 | sched_mc_power_savings_store); |
6379 | #endif | 6372 | #endif |
6380 | 6373 | ||
6381 | #ifdef CONFIG_SCHED_SMT | 6374 | #ifdef CONFIG_SCHED_SMT |
@@ -6388,8 +6381,26 @@ static ssize_t sched_smt_power_savings_store(struct sys_device *dev, | |||
6388 | { | 6381 | { |
6389 | return sched_power_savings_store(buf, count, 1); | 6382 | return sched_power_savings_store(buf, count, 1); |
6390 | } | 6383 | } |
6391 | SYSDEV_ATTR(sched_smt_power_savings, 0644, sched_smt_power_savings_show, | 6384 | static SYSDEV_ATTR(sched_smt_power_savings, 0644, sched_smt_power_savings_show, |
6392 | sched_smt_power_savings_store); | 6385 | sched_smt_power_savings_store); |
6386 | #endif | ||
6387 | |||
6388 | int sched_create_sysfs_power_savings_entries(struct sysdev_class *cls) | ||
6389 | { | ||
6390 | int err = 0; | ||
6391 | |||
6392 | #ifdef CONFIG_SCHED_SMT | ||
6393 | if (smt_capable()) | ||
6394 | err = sysfs_create_file(&cls->kset.kobj, | ||
6395 | &attr_sched_smt_power_savings.attr); | ||
6396 | #endif | ||
6397 | #ifdef CONFIG_SCHED_MC | ||
6398 | if (!err && mc_capable()) | ||
6399 | err = sysfs_create_file(&cls->kset.kobj, | ||
6400 | &attr_sched_mc_power_savings.attr); | ||
6401 | #endif | ||
6402 | return err; | ||
6403 | } | ||
6393 | #endif | 6404 | #endif |
6394 | 6405 | ||
6395 | /* | 6406 | /* |