diff options
Diffstat (limited to 'kernel/timer.c')
| -rw-r--r-- | kernel/timer.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/kernel/timer.c b/kernel/timer.c index c3a874f1393c..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++; |
