Преглед изворни кода

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

Pull timer fixes from Thomas Gleixner:

 - Cure for not using zalloc in the first place, which leads to random
   crashes with CPUMASK_OFF_STACK.

 - Revert a user space visible change which broke udev

 - Add a missing cpu_online early return introduced by the new full
   dyntick conversions

 - Plug a long standing race in the timer wheel cpu hotplug code.
   Sigh...

 - Cleanup NOHZ per cpu data on cpu down to prevent stale data on cpu
   up.

* 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  time: Revert ALWAYS_USE_PERSISTENT_CLOCK compile time optimizaitons
  timer: Don't reinitialize the cpu base lock during CPU_UP_PREPARE
  tick: Don't invoke tick_nohz_stop_sched_tick() if the cpu is offline
  tick: Cleanup NOHZ per cpu data on cpu down
  tick: Use zalloc_cpumask_var for allocating offstack cpumasks
Linus Torvalds пре 12 година
родитељ
комит
cc51bf6e6d
7 измењених фајлова са 8 додато и 19 уклоњено
  1. 0 1
      arch/x86/Kconfig
  2. 0 2
      drivers/rtc/Kconfig
  3. 0 4
      include/linux/time.h
  4. 0 5
      kernel/time/Kconfig
  5. 5 5
      kernel/time/tick-broadcast.c
  6. 2 1
      kernel/time/tick-sched.c
  7. 1 1
      kernel/timer.c

+ 0 - 1
arch/x86/Kconfig

@@ -108,7 +108,6 @@ config X86
 	select GENERIC_CLOCKEVENTS_BROADCAST if X86_64 || (X86_32 && X86_LOCAL_APIC)
 	select GENERIC_CLOCKEVENTS_BROADCAST if X86_64 || (X86_32 && X86_LOCAL_APIC)
 	select GENERIC_TIME_VSYSCALL if X86_64
 	select GENERIC_TIME_VSYSCALL if X86_64
 	select KTIME_SCALAR if X86_32
 	select KTIME_SCALAR if X86_32
-	select ALWAYS_USE_PERSISTENT_CLOCK
 	select GENERIC_STRNCPY_FROM_USER
 	select GENERIC_STRNCPY_FROM_USER
 	select GENERIC_STRNLEN_USER
 	select GENERIC_STRNLEN_USER
 	select HAVE_CONTEXT_TRACKING if X86_64
 	select HAVE_CONTEXT_TRACKING if X86_64

+ 0 - 2
drivers/rtc/Kconfig

@@ -20,7 +20,6 @@ if RTC_CLASS
 config RTC_HCTOSYS
 config RTC_HCTOSYS
 	bool "Set system time from RTC on startup and resume"
 	bool "Set system time from RTC on startup and resume"
 	default y
 	default y
-	depends on !ALWAYS_USE_PERSISTENT_CLOCK
 	help
 	help
 	  If you say yes here, the system time (wall clock) will be set using
 	  If you say yes here, the system time (wall clock) will be set using
 	  the value read from a specified RTC device. This is useful to avoid
 	  the value read from a specified RTC device. This is useful to avoid
@@ -29,7 +28,6 @@ config RTC_HCTOSYS
 config RTC_SYSTOHC
 config RTC_SYSTOHC
 	bool "Set the RTC time based on NTP synchronization"
 	bool "Set the RTC time based on NTP synchronization"
 	default y
 	default y
-	depends on !ALWAYS_USE_PERSISTENT_CLOCK
 	help
 	help
 	  If you say yes here, the system time (wall clock) will be stored
 	  If you say yes here, the system time (wall clock) will be stored
 	  in the RTC specified by RTC_HCTOSYS_DEVICE approximately every 11
 	  in the RTC specified by RTC_HCTOSYS_DEVICE approximately every 11

+ 0 - 4
include/linux/time.h

@@ -117,14 +117,10 @@ static inline bool timespec_valid_strict(const struct timespec *ts)
 
 
 extern bool persistent_clock_exist;
 extern bool persistent_clock_exist;
 
 
-#ifdef ALWAYS_USE_PERSISTENT_CLOCK
-#define has_persistent_clock()	true
-#else
 static inline bool has_persistent_clock(void)
 static inline bool has_persistent_clock(void)
 {
 {
 	return persistent_clock_exist;
 	return persistent_clock_exist;
 }
 }
-#endif
 
 
 extern void read_persistent_clock(struct timespec *ts);
 extern void read_persistent_clock(struct timespec *ts);
 extern void read_boot_clock(struct timespec *ts);
 extern void read_boot_clock(struct timespec *ts);

+ 0 - 5
kernel/time/Kconfig

@@ -12,11 +12,6 @@ config CLOCKSOURCE_WATCHDOG
 config ARCH_CLOCKSOURCE_DATA
 config ARCH_CLOCKSOURCE_DATA
 	bool
 	bool
 
 
-# Platforms has a persistent clock
-config ALWAYS_USE_PERSISTENT_CLOCK
-	bool
-	default n
-
 # Timekeeping vsyscall support
 # Timekeeping vsyscall support
 config GENERIC_TIME_VSYSCALL
 config GENERIC_TIME_VSYSCALL
 	bool
 	bool

+ 5 - 5
kernel/time/tick-broadcast.c

@@ -786,11 +786,11 @@ bool tick_broadcast_oneshot_available(void)
 
 
 void __init tick_broadcast_init(void)
 void __init tick_broadcast_init(void)
 {
 {
-	alloc_cpumask_var(&tick_broadcast_mask, GFP_NOWAIT);
-	alloc_cpumask_var(&tmpmask, GFP_NOWAIT);
+	zalloc_cpumask_var(&tick_broadcast_mask, GFP_NOWAIT);
+	zalloc_cpumask_var(&tmpmask, GFP_NOWAIT);
 #ifdef CONFIG_TICK_ONESHOT
 #ifdef CONFIG_TICK_ONESHOT
-	alloc_cpumask_var(&tick_broadcast_oneshot_mask, GFP_NOWAIT);
-	alloc_cpumask_var(&tick_broadcast_pending_mask, GFP_NOWAIT);
-	alloc_cpumask_var(&tick_broadcast_force_mask, GFP_NOWAIT);
+	zalloc_cpumask_var(&tick_broadcast_oneshot_mask, GFP_NOWAIT);
+	zalloc_cpumask_var(&tick_broadcast_pending_mask, GFP_NOWAIT);
+	zalloc_cpumask_var(&tick_broadcast_force_mask, GFP_NOWAIT);
 #endif
 #endif
 }
 }

+ 2 - 1
kernel/time/tick-sched.c

@@ -717,6 +717,7 @@ static bool can_stop_idle_tick(int cpu, struct tick_sched *ts)
 	if (unlikely(!cpu_online(cpu))) {
 	if (unlikely(!cpu_online(cpu))) {
 		if (cpu == tick_do_timer_cpu)
 		if (cpu == tick_do_timer_cpu)
 			tick_do_timer_cpu = TICK_DO_TIMER_NONE;
 			tick_do_timer_cpu = TICK_DO_TIMER_NONE;
+		return false;
 	}
 	}
 
 
 	if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE))
 	if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE))
@@ -1168,7 +1169,7 @@ void tick_cancel_sched_timer(int cpu)
 		hrtimer_cancel(&ts->sched_timer);
 		hrtimer_cancel(&ts->sched_timer);
 # endif
 # endif
 
 
-	ts->nohz_mode = NOHZ_MODE_INACTIVE;
+	memset(ts, 0, sizeof(*ts));
 }
 }
 #endif
 #endif
 
 

+ 1 - 1
kernel/timer.c

@@ -1539,12 +1539,12 @@ static int __cpuinit init_timers_cpu(int cpu)
 			boot_done = 1;
 			boot_done = 1;
 			base = &boot_tvec_bases;
 			base = &boot_tvec_bases;
 		}
 		}
+		spin_lock_init(&base->lock);
 		tvec_base_done[cpu] = 1;
 		tvec_base_done[cpu] = 1;
 	} else {
 	} else {
 		base = per_cpu(tvec_bases, cpu);
 		base = per_cpu(tvec_bases, cpu);
 	}
 	}
 
 
-	spin_lock_init(&base->lock);
 
 
 	for (j = 0; j < TVN_SIZE; j++) {
 	for (j = 0; j < TVN_SIZE; j++) {
 		INIT_LIST_HEAD(base->tv5.vec + j);
 		INIT_LIST_HEAD(base->tv5.vec + j);