Skip to content

Commit

Permalink
sched: make early bootup sched_clock() use safer
Browse files Browse the repository at this point in the history
do not call sched_clock() too early. Not only might rq->idle
not be set up - but pure per-cpu data might not be accessible
either.

this solves an ia64 early bootup hang with CONFIG_PRINTK_TIME=y.

Tested-by: Tony Luck <tony.luck@gmail.com>
Acked-by: Tony Luck <tony.luck@gmail.com>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Ingo Molnar committed Feb 25, 2008
1 parent bfa274e commit 6892b75
Showing 1 changed file with 10 additions and 4 deletions.
14 changes: 10 additions & 4 deletions kernel/sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,8 @@ const_debug unsigned int sysctl_sched_nr_migrate = 32;
*/
unsigned int sysctl_sched_rt_period = 1000000;

static __read_mostly int scheduler_running;

/*
* part of the period that we allow rt tasks to run in us.
* default: 0.95s
Expand All @@ -689,14 +691,16 @@ unsigned long long cpu_clock(int cpu)
unsigned long flags;
struct rq *rq;

local_irq_save(flags);
rq = cpu_rq(cpu);
/*
* Only call sched_clock() if the scheduler has already been
* initialized (some code might call cpu_clock() very early):
*/
if (rq->idle)
update_rq_clock(rq);
if (unlikely(!scheduler_running))
return 0;

local_irq_save(flags);
rq = cpu_rq(cpu);
update_rq_clock(rq);
now = rq->clock;
local_irq_restore(flags);

Expand Down Expand Up @@ -7284,6 +7288,8 @@ void __init sched_init(void)
* During early bootup we pretend to be a normal task:
*/
current->sched_class = &fair_sched_class;

scheduler_running = 1;
}

#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP
Expand Down

0 comments on commit 6892b75

Please sign in to comment.