diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-06-15 19:52:35 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-06-15 19:52:35 -0400 |
| commit | a95f9b6e092ed862278e08266207c7ab231076b4 (patch) | |
| tree | c5daf86ce89b3033c051dfc7b2955981d6add16d | |
| parent | a41b0e71563166762ee9d4905f3aa518a9348ed4 (diff) | |
| parent | 4a1e001d2bb75c47a9cdbbfb66ae51daff1ddcba (diff) | |
Merge branch 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull core updates (RCU and locking) from Ingo Molnar:
"Most of the diffstat comes from the RCU slow boot regression fixes,
but there's also a debuggability improvements/fixes."
* 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
memblock: Document memblock_is_region_{memory,reserved}()
rcu: Precompute RCU_FAST_NO_HZ timer offsets
rcu: Move RCU_FAST_NO_HZ per-CPU variables to rcu_dynticks structure
rcu: Update RCU_FAST_NO_HZ tracing for lazy callbacks
rcu: RCU_FAST_NO_HZ detection of callback adoption
spinlock: Indicate that a lockup is only suspected
kdump: Execute kmsg_dump(KMSG_DUMP_PANIC) after smp_send_stop()
panic: Make panic_on_oops configurable
| -rw-r--r-- | include/linux/rcutiny.h | 6 | ||||
| -rw-r--r-- | include/linux/rcutree.h | 2 | ||||
| -rw-r--r-- | include/trace/events/rcu.h | 1 | ||||
| -rw-r--r-- | kernel/panic.c | 6 | ||||
| -rw-r--r-- | kernel/rcutree.c | 2 | ||||
| -rw-r--r-- | kernel/rcutree.h | 14 | ||||
| -rw-r--r-- | kernel/rcutree_plugin.h | 165 | ||||
| -rw-r--r-- | kernel/time/tick-sched.c | 7 | ||||
| -rw-r--r-- | lib/Kconfig.debug | 20 | ||||
| -rw-r--r-- | lib/spinlock_debug.c | 2 | ||||
| -rw-r--r-- | mm/memblock.c | 20 |
11 files changed, 160 insertions, 85 deletions
diff --git a/include/linux/rcutiny.h b/include/linux/rcutiny.h index adb5e5a38cae..854dc4c5c271 100644 --- a/include/linux/rcutiny.h +++ b/include/linux/rcutiny.h | |||
| @@ -87,8 +87,9 @@ static inline void kfree_call_rcu(struct rcu_head *head, | |||
| 87 | 87 | ||
| 88 | #ifdef CONFIG_TINY_RCU | 88 | #ifdef CONFIG_TINY_RCU |
| 89 | 89 | ||
| 90 | static inline int rcu_needs_cpu(int cpu) | 90 | static inline int rcu_needs_cpu(int cpu, unsigned long *delta_jiffies) |
| 91 | { | 91 | { |
| 92 | *delta_jiffies = ULONG_MAX; | ||
| 92 | return 0; | 93 | return 0; |
| 93 | } | 94 | } |
| 94 | 95 | ||
| @@ -96,8 +97,9 @@ static inline int rcu_needs_cpu(int cpu) | |||
| 96 | 97 | ||
| 97 | int rcu_preempt_needs_cpu(void); | 98 | int rcu_preempt_needs_cpu(void); |
| 98 | 99 | ||
| 99 | static inline int rcu_needs_cpu(int cpu) | 100 | static inline int rcu_needs_cpu(int cpu, unsigned long *delta_jiffies) |
| 100 | { | 101 | { |
| 102 | *delta_jiffies = ULONG_MAX; | ||
| 101 | return rcu_preempt_needs_cpu(); | 103 | return rcu_preempt_needs_cpu(); |
| 102 | } | 104 | } |
| 103 | 105 | ||
diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h index 3c6083cde4fc..952b79339304 100644 --- a/include/linux/rcutree.h +++ b/include/linux/rcutree.h | |||
| @@ -32,7 +32,7 @@ | |||
| 32 | 32 | ||
| 33 | extern void rcu_init(void); | 33 | extern void rcu_init(void); |
| 34 | extern void rcu_note_context_switch(int cpu); | 34 | extern void rcu_note_context_switch(int cpu); |
| 35 | extern int rcu_needs_cpu(int cpu); | 35 | extern int rcu_needs_cpu(int cpu, unsigned long *delta_jiffies); |
| 36 | extern void rcu_cpu_stall_reset(void); | 36 | extern void rcu_cpu_stall_reset(void); |
| 37 | 37 | ||
| 38 | /* | 38 | /* |
diff --git a/include/trace/events/rcu.h b/include/trace/events/rcu.h index 1480900c511c..d274734b2aa4 100644 --- a/include/trace/events/rcu.h +++ b/include/trace/events/rcu.h | |||
| @@ -289,6 +289,7 @@ TRACE_EVENT(rcu_dyntick, | |||
| 289 | * "In holdoff": Nothing to do, holding off after unsuccessful attempt. | 289 | * "In holdoff": Nothing to do, holding off after unsuccessful attempt. |
| 290 | * "Begin holdoff": Attempt failed, don't retry until next jiffy. | 290 | * "Begin holdoff": Attempt failed, don't retry until next jiffy. |
| 291 | * "Dyntick with callbacks": Entering dyntick-idle despite callbacks. | 291 | * "Dyntick with callbacks": Entering dyntick-idle despite callbacks. |
| 292 | * "Dyntick with lazy callbacks": Entering dyntick-idle w/lazy callbacks. | ||
| 292 | * "More callbacks": Still more callbacks, try again to clear them out. | 293 | * "More callbacks": Still more callbacks, try again to clear them out. |
| 293 | * "Callbacks drained": All callbacks processed, off to dyntick idle! | 294 | * "Callbacks drained": All callbacks processed, off to dyntick idle! |
| 294 | * "Timer": Timer fired to cause CPU to continue processing callbacks. | 295 | * "Timer": Timer fired to cause CPU to continue processing callbacks. |
diff --git a/kernel/panic.c b/kernel/panic.c index 8ed89a175d79..d2a5f4ecc6dd 100644 --- a/kernel/panic.c +++ b/kernel/panic.c | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | #define PANIC_TIMER_STEP 100 | 27 | #define PANIC_TIMER_STEP 100 |
| 28 | #define PANIC_BLINK_SPD 18 | 28 | #define PANIC_BLINK_SPD 18 |
| 29 | 29 | ||
| 30 | int panic_on_oops; | 30 | int panic_on_oops = CONFIG_PANIC_ON_OOPS_VALUE; |
| 31 | static unsigned long tainted_mask; | 31 | static unsigned long tainted_mask; |
| 32 | static int pause_on_oops; | 32 | static int pause_on_oops; |
| 33 | static int pause_on_oops_flag; | 33 | static int pause_on_oops_flag; |
| @@ -108,8 +108,6 @@ void panic(const char *fmt, ...) | |||
| 108 | */ | 108 | */ |
| 109 | crash_kexec(NULL); | 109 | crash_kexec(NULL); |
| 110 | 110 | ||
| 111 | kmsg_dump(KMSG_DUMP_PANIC); | ||
| 112 | |||
| 113 | /* | 111 | /* |
| 114 | * Note smp_send_stop is the usual smp shutdown function, which | 112 | * Note smp_send_stop is the usual smp shutdown function, which |
| 115 | * unfortunately means it may not be hardened to work in a panic | 113 | * unfortunately means it may not be hardened to work in a panic |
| @@ -117,6 +115,8 @@ void panic(const char *fmt, ...) | |||
| 117 | */ | 115 | */ |
| 118 | smp_send_stop(); | 116 | smp_send_stop(); |
| 119 | 117 | ||
| 118 | kmsg_dump(KMSG_DUMP_PANIC); | ||
| 119 | |||
| 120 | atomic_notifier_call_chain(&panic_notifier_list, 0, buf); | 120 | atomic_notifier_call_chain(&panic_notifier_list, 0, buf); |
| 121 | 121 | ||
| 122 | bust_spinlocks(0); | 122 | bust_spinlocks(0); |
diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 0da7b88d92d0..3b0f1337f75b 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c | |||
| @@ -1397,6 +1397,8 @@ static void rcu_adopt_orphan_cbs(struct rcu_state *rsp) | |||
| 1397 | rdp->qlen_lazy += rsp->qlen_lazy; | 1397 | rdp->qlen_lazy += rsp->qlen_lazy; |
| 1398 | rdp->qlen += rsp->qlen; | 1398 | rdp->qlen += rsp->qlen; |
| 1399 | rdp->n_cbs_adopted += rsp->qlen; | 1399 | rdp->n_cbs_adopted += rsp->qlen; |
| 1400 | if (rsp->qlen_lazy != rsp->qlen) | ||
| 1401 | rcu_idle_count_callbacks_posted(); | ||
| 1400 | rsp->qlen_lazy = 0; | 1402 | rsp->qlen_lazy = 0; |
| 1401 | rsp->qlen = 0; | 1403 | rsp->qlen = 0; |
| 1402 | 1404 | ||
diff --git a/kernel/rcutree.h b/kernel/rcutree.h index 7f5d138dedf5..ea056495783e 100644 --- a/kernel/rcutree.h +++ b/kernel/rcutree.h | |||
| @@ -84,6 +84,20 @@ struct rcu_dynticks { | |||
| 84 | /* Process level is worth LLONG_MAX/2. */ | 84 | /* Process level is worth LLONG_MAX/2. */ |
| 85 | int dynticks_nmi_nesting; /* Track NMI nesting level. */ | 85 | int dynticks_nmi_nesting; /* Track NMI nesting level. */ |
| 86 | atomic_t dynticks; /* Even value for idle, else odd. */ | 86 | atomic_t dynticks; /* Even value for idle, else odd. */ |
| 87 | #ifdef CONFIG_RCU_FAST_NO_HZ | ||
| 88 | int dyntick_drain; /* Prepare-for-idle state variable. */ | ||
| 89 | unsigned long dyntick_holdoff; | ||
| 90 | /* No retries for the jiffy of failure. */ | ||
| 91 | struct timer_list idle_gp_timer; | ||
| 92 | /* Wake up CPU sleeping with callbacks. */ | ||
| 93 | unsigned long idle_gp_timer_expires; | ||
| 94 | /* When to wake up CPU (for repost). */ | ||
| 95 | bool idle_first_pass; /* First pass of attempt to go idle? */ | ||
| 96 | unsigned long nonlazy_posted; | ||
| 97 | /* # times non-lazy CBs posted to CPU. */ | ||
| 98 | unsigned long nonlazy_posted_snap; | ||
| 99 | /* idle-period nonlazy_posted snapshot. */ | ||
| 100 | #endif /* #ifdef CONFIG_RCU_FAST_NO_HZ */ | ||
| 87 | }; | 101 | }; |
| 88 | 102 | ||
| 89 | /* RCU's kthread states for tracing. */ | 103 | /* RCU's kthread states for tracing. */ |
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index 2411000d9869..5271a020887e 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h | |||
| @@ -1886,8 +1886,9 @@ static void __cpuinit rcu_prepare_kthreads(int cpu) | |||
| 1886 | * Because we not have RCU_FAST_NO_HZ, just check whether this CPU needs | 1886 | * Because we not have RCU_FAST_NO_HZ, just check whether this CPU needs |
| 1887 | * any flavor of RCU. | 1887 | * any flavor of RCU. |
| 1888 | */ | 1888 | */ |
| 1889 | int rcu_needs_cpu(int cpu) | 1889 | int rcu_needs_cpu(int cpu, unsigned long *delta_jiffies) |
| 1890 | { | 1890 | { |
| 1891 | *delta_jiffies = ULONG_MAX; | ||
| 1891 | return rcu_cpu_has_callbacks(cpu); | 1892 | return rcu_cpu_has_callbacks(cpu); |
| 1892 | } | 1893 | } |
| 1893 | 1894 | ||
| @@ -1962,41 +1963,6 @@ static void rcu_idle_count_callbacks_posted(void) | |||
| 1962 | #define RCU_IDLE_GP_DELAY 6 /* Roughly one grace period. */ | 1963 | #define RCU_IDLE_GP_DELAY 6 /* Roughly one grace period. */ |
| 1963 | #define RCU_IDLE_LAZY_GP_DELAY (6 * HZ) /* Roughly six seconds. */ | 1964 | #define RCU_IDLE_LAZY_GP_DELAY (6 * HZ) /* Roughly six seconds. */ |
| 1964 | 1965 | ||
| 1965 | /* Loop counter for rcu_prepare_for_idle(). */ | ||
| 1966 | static DEFINE_PER_CPU(int, rcu_dyntick_drain); | ||
| 1967 | /* If rcu_dyntick_holdoff==jiffies, don't try to enter dyntick-idle mode. */ | ||
| 1968 | static DEFINE_PER_CPU(unsigned long, rcu_dyntick_holdoff); | ||
| 1969 | /* Timer to awaken the CPU if it enters dyntick-idle mode with callbacks. */ | ||
| 1970 | static DEFINE_PER_CPU(struct timer_list, rcu_idle_gp_timer); | ||
| 1971 | /* Scheduled expiry time for rcu_idle_gp_timer to allow reposting. */ | ||
| 1972 | static DEFINE_PER_CPU(unsigned long, rcu_idle_gp_timer_expires); | ||
| 1973 | /* Enable special processing on first attempt to enter dyntick-idle mode. */ | ||
| 1974 | static DEFINE_PER_CPU(bool, rcu_idle_first_pass); | ||
| 1975 | /* Running count of non-lazy callbacks posted, never decremented. */ | ||
| 1976 | static DEFINE_PER_CPU(unsigned long, rcu_nonlazy_posted); | ||
| 1977 | /* Snapshot of rcu_nonlazy_posted to detect meaningful exits from idle. */ | ||
| 1978 | static DEFINE_PER_CPU(unsigned long, rcu_nonlazy_posted_snap); | ||
| 1979 | |||
| 1980 | /* | ||
| 1981 | * Allow the CPU to enter dyntick-idle mode if either: (1) There are no | ||
| 1982 | * callbacks on this CPU, (2) this CPU has not yet attempted to enter | ||
| 1983 | * dyntick-idle mode, or (3) this CPU is in the process of attempting to | ||
| 1984 | * enter dyntick-idle mode. Otherwise, if we have recently tried and failed | ||
| 1985 | * to enter dyntick-idle mode, we refuse to try to enter it. After all, | ||
| 1986 | * it is better to incur scheduling-clock interrupts than to spin | ||
| 1987 | * continuously for the same time duration! | ||
| 1988 | */ | ||
| 1989 | int rcu_needs_cpu(int cpu) | ||
| 1990 | { | ||
| 1991 | /* Flag a new idle sojourn to the idle-entry state machine. */ | ||
| 1992 | per_cpu(rcu_idle_first_pass, cpu) = 1; | ||
