diff options
author | Jeff Garzik <jeff@garzik.org> | 2006-04-12 17:52:52 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-04-12 17:52:52 -0400 |
commit | 32ea89ecb25789b1b7db28146558587a42f3b372 (patch) | |
tree | c5b3b33523b353f2eab2d8dcd2b3f069826cdc48 /kernel/timer.c | |
parent | 58a7ce64426394a46e80cdc9440cc1e7c195e85d (diff) | |
parent | a145410dccdb44f81d3b56763ef9b6f721f4e47c (diff) |
Merge branch 'master'
Diffstat (limited to 'kernel/timer.c')
-rw-r--r-- | kernel/timer.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/kernel/timer.c b/kernel/timer.c index 6b812c04737b..883773788836 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -81,9 +81,10 @@ struct tvec_t_base_s { | |||
81 | } ____cacheline_aligned_in_smp; | 81 | } ____cacheline_aligned_in_smp; |
82 | 82 | ||
83 | typedef struct tvec_t_base_s tvec_base_t; | 83 | typedef struct tvec_t_base_s tvec_base_t; |
84 | static DEFINE_PER_CPU(tvec_base_t *, tvec_bases); | 84 | |
85 | tvec_base_t boot_tvec_bases; | 85 | tvec_base_t boot_tvec_bases; |
86 | EXPORT_SYMBOL(boot_tvec_bases); | 86 | EXPORT_SYMBOL(boot_tvec_bases); |
87 | static DEFINE_PER_CPU(tvec_base_t *, tvec_bases) = { &boot_tvec_bases }; | ||
87 | 88 | ||
88 | static inline void set_running_timer(tvec_base_t *base, | 89 | static inline void set_running_timer(tvec_base_t *base, |
89 | struct timer_list *timer) | 90 | struct timer_list *timer) |
@@ -1224,28 +1225,36 @@ static int __devinit init_timers_cpu(int cpu) | |||
1224 | { | 1225 | { |
1225 | int j; | 1226 | int j; |
1226 | tvec_base_t *base; | 1227 | tvec_base_t *base; |
1228 | static char __devinitdata tvec_base_done[NR_CPUS]; | ||
1227 | 1229 | ||
1228 | base = per_cpu(tvec_bases, cpu); | 1230 | if (!tvec_base_done[cpu]) { |
1229 | if (!base) { | ||
1230 | static char boot_done; | 1231 | static char boot_done; |
1231 | 1232 | ||
1232 | /* | ||
1233 | * Cannot do allocation in init_timers as that runs before the | ||
1234 | * allocator initializes (and would waste memory if there are | ||
1235 | * more possible CPUs than will ever be installed/brought up). | ||
1236 | */ | ||
1237 | if (boot_done) { | 1233 | if (boot_done) { |
1234 | /* | ||
1235 | * The APs use this path later in boot | ||
1236 | */ | ||
1238 | base = kmalloc_node(sizeof(*base), GFP_KERNEL, | 1237 | base = kmalloc_node(sizeof(*base), GFP_KERNEL, |
1239 | cpu_to_node(cpu)); | 1238 | cpu_to_node(cpu)); |
1240 | if (!base) | 1239 | if (!base) |
1241 | return -ENOMEM; | 1240 | return -ENOMEM; |
1242 | memset(base, 0, sizeof(*base)); | 1241 | memset(base, 0, sizeof(*base)); |
1242 | per_cpu(tvec_bases, cpu) = base; | ||
1243 | } else { | 1243 | } else { |
1244 | base = &boot_tvec_bases; | 1244 | /* |
1245 | * This is for the boot CPU - we use compile-time | ||
1246 | * static initialisation because per-cpu memory isn't | ||
1247 | * ready yet and because the memory allocators are not | ||
1248 | * initialised either. | ||
1249 | */ | ||
1245 | boot_done = 1; | 1250 | boot_done = 1; |
1251 | base = &boot_tvec_bases; | ||
1246 | } | 1252 | } |
1247 | per_cpu(tvec_bases, cpu) = base; | 1253 | tvec_base_done[cpu] = 1; |
1254 | } else { | ||
1255 | base = per_cpu(tvec_bases, cpu); | ||
1248 | } | 1256 | } |
1257 | |||
1249 | spin_lock_init(&base->lock); | 1258 | spin_lock_init(&base->lock); |
1250 | for (j = 0; j < TVN_SIZE; j++) { | 1259 | for (j = 0; j < TVN_SIZE; j++) { |
1251 | INIT_LIST_HEAD(base->tv5.vec + j); | 1260 | INIT_LIST_HEAD(base->tv5.vec + j); |
@@ -1455,7 +1464,7 @@ static void time_interpolator_update(long delta_nsec) | |||
1455 | */ | 1464 | */ |
1456 | if (jiffies % INTERPOLATOR_ADJUST == 0) | 1465 | if (jiffies % INTERPOLATOR_ADJUST == 0) |
1457 | { | 1466 | { |
1458 | if (time_interpolator->skips == 0 && time_interpolator->offset > TICK_NSEC) | 1467 | if (time_interpolator->skips == 0 && time_interpolator->offset > tick_nsec) |
1459 | time_interpolator->nsec_per_cyc--; | 1468 | time_interpolator->nsec_per_cyc--; |
1460 | if (time_interpolator->ns_skipped > INTERPOLATOR_MAX_SKIP && time_interpolator->offset == 0) | 1469 | if (time_interpolator->ns_skipped > INTERPOLATOR_MAX_SKIP && time_interpolator->offset == 0) |
1461 | time_interpolator->nsec_per_cyc++; | 1470 | time_interpolator->nsec_per_cyc++; |
@@ -1479,8 +1488,7 @@ register_time_interpolator(struct time_interpolator *ti) | |||
1479 | unsigned long flags; | 1488 | unsigned long flags; |
1480 | 1489 | ||
1481 | /* Sanity check */ | 1490 | /* Sanity check */ |
1482 | if (ti->frequency == 0 || ti->mask == 0) | 1491 | BUG_ON(ti->frequency == 0 || ti->mask == 0); |
1483 | BUG(); | ||
1484 | 1492 | ||
1485 | ti->nsec_per_cyc = ((u64)NSEC_PER_SEC << ti->shift) / ti->frequency; | 1493 | ti->nsec_per_cyc = ((u64)NSEC_PER_SEC << ti->shift) / ti->frequency; |
1486 | spin_lock(&time_interpolator_lock); | 1494 | spin_lock(&time_interpolator_lock); |