Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 372943
b: refs/heads/master
c: 265f22a
h: refs/heads/master
i:
  372941: 019dc7d
  372939: 4226508
  372935: 3eed976
  372927: 1208329
v: v3
  • Loading branch information
Frederic Weisbecker committed May 4, 2013
1 parent c006c71 commit 06f0f4f
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 73c30828771acafb0a5e3a1c4cf75e6c5dc5f98a
refs/heads/master: 265f22a975c1e4cc3a4d1f94a3ec53ffbb6f5b9f
1 change: 1 addition & 0 deletions trunk/include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -1862,6 +1862,7 @@ static inline void wake_up_nohz_cpu(int cpu) { }

#ifdef CONFIG_NO_HZ_FULL
extern bool sched_can_stop_tick(void);
extern u64 scheduler_tick_max_deferment(void);
#else
static inline bool sched_can_stop_tick(void) { return false; }
#endif
Expand Down
30 changes: 30 additions & 0 deletions trunk/kernel/sched/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2736,8 +2736,35 @@ void scheduler_tick(void)
rq->idle_balance = idle_cpu(cpu);
trigger_load_balance(rq, cpu);
#endif
rq_last_tick_reset(rq);
}

#ifdef CONFIG_NO_HZ_FULL
/**
* scheduler_tick_max_deferment
*
* Keep at least one tick per second when a single
* active task is running because the scheduler doesn't
* yet completely support full dynticks environment.
*
* This makes sure that uptime, CFS vruntime, load
* balancing, etc... continue to move forward, even
* with a very low granularity.
*/
u64 scheduler_tick_max_deferment(void)
{
struct rq *rq = this_rq();
unsigned long next, now = ACCESS_ONCE(jiffies);

next = rq->last_sched_tick + HZ;

if (time_before_eq(next, now))
return 0;

return jiffies_to_usecs(next - now) * NSEC_PER_USEC;
}
#endif

notrace unsigned long get_parent_ip(unsigned long addr)
{
if (in_lock_functions(addr)) {
Expand Down Expand Up @@ -6993,6 +7020,9 @@ void __init sched_init(void)
#ifdef CONFIG_NO_HZ_COMMON
rq->nohz_flags = 0;
#endif
#ifdef CONFIG_NO_HZ_FULL
rq->last_sched_tick = 0;
#endif
#endif
init_rq_hrtick(rq);
atomic_set(&rq->nr_iowait, 0);
Expand Down
1 change: 1 addition & 0 deletions trunk/kernel/sched/idle_task.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ select_task_rq_idle(struct task_struct *p, int sd_flag, int flags)
static void pre_schedule_idle(struct rq *rq, struct task_struct *prev)
{
idle_exit_fair(rq);
rq_last_tick_reset(rq);
}

static void post_schedule_idle(struct rq *rq)
Expand Down
10 changes: 10 additions & 0 deletions trunk/kernel/sched/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,9 @@ struct rq {
#ifdef CONFIG_NO_HZ_COMMON
u64 nohz_stamp;
unsigned long nohz_flags;
#endif
#ifdef CONFIG_NO_HZ_FULL
unsigned long last_sched_tick;
#endif
int skip_clock_update;

Expand Down Expand Up @@ -1090,6 +1093,13 @@ static inline void dec_nr_running(struct rq *rq)
rq->nr_running--;
}

static inline void rq_last_tick_reset(struct rq *rq)
{
#ifdef CONFIG_NO_HZ_FULL
rq->last_sched_tick = jiffies;
#endif
}

extern void update_rq_clock(struct rq *rq);

extern void activate_task(struct rq *rq, struct task_struct *p, int flags);
Expand Down
7 changes: 7 additions & 0 deletions trunk/kernel/time/tick-sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,13 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts,
time_delta = KTIME_MAX;
}

#ifdef CONFIG_NO_HZ_FULL
if (!ts->inidle) {
time_delta = min(time_delta,
scheduler_tick_max_deferment());
}
#endif

/*
* calculate the expiry time for the next timer wheel
* timer. delta_jiffies >= NEXT_TIMER_MAX_DELTA signals
Expand Down

0 comments on commit 06f0f4f

Please sign in to comment.