Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
timers: fix build error in !oneshot case
x86: c1e_idle: don't mark TSC unstable if CPU has invariant TSC
x86: prevent C-states hang on AMD C1E enabled machines
clockevents: prevent mode mismatch on cpu online
clockevents: check broadcast device not tick device
clockevents: prevent stale tick_next_period for onlining CPUs
x86: prevent stale state of c1e_mask across CPU offline/online
clockevents: prevent cpu online to interfere with nohz

+50 -15
+12 -5
arch/x86/kernel/process.c
··· 246 246 return 1; 247 247 } 248 248 249 + static cpumask_t c1e_mask = CPU_MASK_NONE; 250 + static int c1e_detected; 251 + 252 + void c1e_remove_cpu(int cpu) 253 + { 254 + cpu_clear(cpu, c1e_mask); 255 + } 256 + 249 257 /* 250 258 * C1E aware idle routine. We check for C1E active in the interrupt 251 259 * pending message MSR. If we detect C1E, then we handle it the same ··· 261 253 */ 262 254 static void c1e_idle(void) 263 255 { 264 - static cpumask_t c1e_mask = CPU_MASK_NONE; 265 - static int c1e_detected; 266 - 267 256 if (need_resched()) 268 257 return; 269 258 ··· 270 265 rdmsr(MSR_K8_INT_PENDING_MSG, lo, hi); 271 266 if (lo & K8_INTP_C1E_ACTIVE_MASK) { 272 267 c1e_detected = 1; 273 - mark_tsc_unstable("TSC halt in C1E"); 274 - printk(KERN_INFO "System has C1E enabled\n"); 268 + if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) 269 + mark_tsc_unstable("TSC halt in AMD C1E"); 270 + printk(KERN_INFO "System has AMD C1E enabled\n"); 271 + set_cpu_cap(&boot_cpu_data, X86_FEATURE_AMDC1E); 275 272 } 276 273 } 277 274
+1
arch/x86/kernel/process_32.c
··· 88 88 cpu_clear(cpu, cpu_callin_map); 89 89 90 90 numa_remove_cpu(cpu); 91 + c1e_remove_cpu(cpu); 91 92 } 92 93 93 94 /* We don't actually take CPU down, just spin without interrupts. */
+2
arch/x86/kernel/process_64.c
··· 93 93 static inline void play_dead(void) 94 94 { 95 95 idle_task_exit(); 96 + c1e_remove_cpu(raw_smp_processor_id()); 97 + 96 98 mb(); 97 99 /* Ack it */ 98 100 __get_cpu_var(cpu_state) = CPU_DEAD;
+2
include/asm-x86/acpi.h
··· 140 140 boot_cpu_data.x86_model <= 0x05 && 141 141 boot_cpu_data.x86_mask < 0x0A) 142 142 return 1; 143 + else if (boot_cpu_has(X86_FEATURE_AMDC1E)) 144 + return 1; 143 145 else 144 146 return max_cstate; 145 147 }
+1
include/asm-x86/cpufeature.h
··· 81 81 #define X86_FEATURE_LFENCE_RDTSC (3*32+18) /* Lfence synchronizes RDTSC */ 82 82 #define X86_FEATURE_11AP (3*32+19) /* Bad local APIC aka 11AP */ 83 83 #define X86_FEATURE_NOPL (3*32+20) /* The NOPL (0F 1F) instructions */ 84 + #define X86_FEATURE_AMDC1E (3*32+21) /* AMD C1E detected */ 84 85 85 86 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ 86 87 #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */
+2
include/asm-x86/idle.h
··· 10 10 void enter_idle(void); 11 11 void exit_idle(void); 12 12 13 + void c1e_remove_cpu(int cpu); 14 + 13 15 #endif
+10 -2
kernel/time/tick-broadcast.c
··· 235 235 case CLOCK_EVT_NOTIFY_BROADCAST_FORCE: 236 236 if (!cpu_isset(cpu, tick_broadcast_mask)) { 237 237 cpu_set(cpu, tick_broadcast_mask); 238 - if (td->mode == TICKDEV_MODE_PERIODIC) 238 + if (bc->mode == TICKDEV_MODE_PERIODIC) 239 239 clockevents_shutdown(dev); 240 240 } 241 241 if (*reason == CLOCK_EVT_NOTIFY_BROADCAST_FORCE) ··· 245 245 if (!tick_broadcast_force && 246 246 cpu_isset(cpu, tick_broadcast_mask)) { 247 247 cpu_clear(cpu, tick_broadcast_mask); 248 - if (td->mode == TICKDEV_MODE_PERIODIC) 248 + if (bc->mode == TICKDEV_MODE_PERIODIC) 249 249 tick_setup_periodic(dev, 0); 250 250 } 251 251 break; ··· 573 573 cpu_clear(cpu, tick_broadcast_oneshot_mask); 574 574 575 575 spin_unlock_irqrestore(&tick_broadcast_lock, flags); 576 + } 577 + 578 + /* 579 + * Check, whether the broadcast device is in one shot mode 580 + */ 581 + int tick_broadcast_oneshot_active(void) 582 + { 583 + return tick_broadcast_device.mode == TICKDEV_MODE_ONESHOT; 576 584 } 577 585 578 586 #endif
+6 -4
kernel/time/tick-common.c
··· 33 33 */ 34 34 ktime_t tick_next_period; 35 35 ktime_t tick_period; 36 - int tick_do_timer_cpu __read_mostly = -1; 36 + int tick_do_timer_cpu __read_mostly = TICK_DO_TIMER_BOOT; 37 37 DEFINE_SPINLOCK(tick_device_lock); 38 38 39 39 /* ··· 109 109 if (!tick_device_is_functional(dev)) 110 110 return; 111 111 112 - if (dev->features & CLOCK_EVT_FEAT_PERIODIC) { 112 + if ((dev->features & CLOCK_EVT_FEAT_PERIODIC) && 113 + !tick_broadcast_oneshot_active()) { 113 114 clockevents_set_mode(dev, CLOCK_EVT_MODE_PERIODIC); 114 115 } else { 115 116 unsigned long seq; ··· 149 148 * If no cpu took the do_timer update, assign it to 150 149 * this cpu: 151 150 */ 152 - if (tick_do_timer_cpu == -1) { 151 + if (tick_do_timer_cpu == TICK_DO_TIMER_BOOT) { 153 152 tick_do_timer_cpu = cpu; 154 153 tick_next_period = ktime_get(); 155 154 tick_period = ktime_set(0, NSEC_PER_SEC / HZ); ··· 301 300 if (*cpup == tick_do_timer_cpu) { 302 301 int cpu = first_cpu(cpu_online_map); 303 302 304 - tick_do_timer_cpu = (cpu != NR_CPUS) ? cpu : -1; 303 + tick_do_timer_cpu = (cpu != NR_CPUS) ? cpu : 304 + TICK_DO_TIMER_NONE; 305 305 } 306 306 spin_unlock_irqrestore(&tick_device_lock, flags); 307 307 }
+7
kernel/time/tick-internal.h
··· 1 1 /* 2 2 * tick internal variable and functions used by low/high res code 3 3 */ 4 + 5 + #define TICK_DO_TIMER_NONE -1 6 + #define TICK_DO_TIMER_BOOT -2 7 + 4 8 DECLARE_PER_CPU(struct tick_device, tick_cpu_device); 5 9 extern spinlock_t tick_device_lock; 6 10 extern ktime_t tick_next_period; ··· 35 31 extern void tick_broadcast_switch_to_oneshot(void); 36 32 extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup); 37 33 extern int tick_resume_broadcast_oneshot(struct clock_event_device *bc); 34 + extern int tick_broadcast_oneshot_active(void); 38 35 # else /* BROADCAST */ 39 36 static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) 40 37 { ··· 44 39 static inline void tick_broadcast_oneshot_control(unsigned long reason) { } 45 40 static inline void tick_broadcast_switch_to_oneshot(void) { } 46 41 static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { } 42 + static inline int tick_broadcast_oneshot_active(void) { return 0; } 47 43 # endif /* !BROADCAST */ 48 44 49 45 #else /* !ONESHOT */ ··· 74 68 { 75 69 return 0; 76 70 } 71 + static inline int tick_broadcast_oneshot_active(void) { return 0; } 77 72 #endif /* !TICK_ONESHOT */ 78 73 79 74 /*
+7 -4
kernel/time/tick-sched.c
··· 75 75 incr * ticks); 76 76 } 77 77 do_timer(++ticks); 78 + 79 + /* Keep the tick_next_period variable up to date */ 80 + tick_next_period = ktime_add(last_jiffies_update, tick_period); 78 81 } 79 82 write_sequnlock(&xtime_lock); 80 83 } ··· 224 221 */ 225 222 if (unlikely(!cpu_online(cpu))) { 226 223 if (cpu == tick_do_timer_cpu) 227 - tick_do_timer_cpu = -1; 224 + tick_do_timer_cpu = TICK_DO_TIMER_NONE; 228 225 } 229 226 230 227 if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) ··· 306 303 * invoked. 307 304 */ 308 305 if (cpu == tick_do_timer_cpu) 309 - tick_do_timer_cpu = -1; 306 + tick_do_timer_cpu = TICK_DO_TIMER_NONE; 310 307 311 308 ts->idle_sleeps++; 312 309 ··· 471 468 * this duty, then the jiffies update is still serialized by 472 469 * xtime_lock. 473 470 */ 474 - if (unlikely(tick_do_timer_cpu == -1)) 471 + if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE)) 475 472 tick_do_timer_cpu = cpu; 476 473 477 474 /* Check, if the jiffies need an update */ ··· 573 570 * this duty, then the jiffies update is still serialized by 574 571 * xtime_lock. 575 572 */ 576 - if (unlikely(tick_do_timer_cpu == -1)) 573 + if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE)) 577 574 tick_do_timer_cpu = cpu; 578 575 #endif 579 576