Reputation: 3510
I'm porting 3.14 to an ARM-based SOC which was successfully running the 3.2 kernel.
I'm getting stuck in the code that calibrates jiffies.
calibrate_delay_converge()-init/calibrate.c
/* wait for "start of" clock tick */
ticks = jiffies;
while (ticks == jiffies) <---- infinite loop waiting for jiffies to change
; /* nothing */
/* Go .. */
jiffies isn't being updated. Where does jiffies get updated? I'm looking for smoking gun code like jiffies++ or a .S file updating jiffies.
I went down the rabbit hole of the timers and interrupt system in Linux. The timer interrupt isn't enabled (in the PL190 HW). I'm hoping if I can track from the bottom up (where jiffies SHOULD be called), I can find why the interrupt(s) aren't being enabled.
Upvotes: 3
Views: 3403
Reputation: 20842
Look at do_timer(). It was moved to kernel/time/timekeeping.c at some point in the past few years.
jiffies does not directly get incremented, it gets assigned the low order 32-bit of jiffies_64
/*
* The 64-bit jiffies value is not atomic - you MUST NOT read it
* without sampling the sequence number in xtime_lock.
* jiffies is defined in the linker script...
*/
void do_timer(unsigned long ticks)
{
jiffies_64 += ticks;
update_wall_time();
calc_global_load(ticks);
}
In 3.2 it is http://lxr.free-electrons.com/source/kernel/time/timekeeping.c?v=3.2#L1192
jiffies gets the value from jiffies_64 here in the machine specific file:
http://lxr.free-electrons.com/source/arch/arm/kernel/vmlinux.lds.S?v=3.2
36 #ifndef __ARMEB__
37 jiffies = jiffies_64;
38 #else
39 jiffies = jiffies_64 + 4;
40 #endif
Upvotes: 7