core kernel fixes
Subsystems (6)
Ingo Molnar
maintainerLinus,
Please pull the latest core-urgent-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git core-urgent-for-linus
HEAD: 4a1e001d2bb75c47a9cdbbfb66ae51daff1ddcba Merge branch 'rcu/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu into core/urgent
Most of the diffstat comes from the RCU slow boot regression fixes, but there's also a debuggability improvements/fixes.
Thanks,
Ingo
------------------>
Christian Borntraeger (1):
spinlock: Indicate that a lockup is only suspected
Kyle McMartin (1):
panic: Make panic_on_oops configurable
Paul E. McKenney (4):
rcu: RCU_FAST_NO_HZ detection of callback adoption
rcu: Update RCU_FAST_NO_HZ tracing for lazy callbacks
rcu: Move RCU_FAST_NO_HZ per-CPU variables to rcu_dynticks structure
rcu: Precompute RCU_FAST_NO_HZ timer offsets
Seiji Aguchi (1):
kdump: Execute kmsg_dump(KMSG_DUMP_PANIC) after smp_send_stop()
Stephen Boyd (1):
memblock: Document memblock_is_region_{memory,reserved}()
include/linux/rcutiny.h | 6 +- include/linux/rcutree.h | 2 +- include/trace/events/rcu.h | 1 + kernel/panic.c | 6 +- kernel/rcutree.c | 2 + kernel/rcutree.h | 14 ++++ kernel/rcutree_plugin.h | 165 ++++++++++++++++++++++++--------------------- kernel/time/tick-sched.c | 7 +- lib/Kconfig.debug | 20 ++++++ lib/spinlock_debug.c | 2 +- mm/memblock.c | 20 ++++++ 11 files changed, 160 insertions(+), 85 deletions(-)
include/linux/rcutiny.h +4 -2
@@ -87,8 +87,9 @@ static inline void kfree_call_rcu(struct rcu_head *head,#ifdef CONFIG_TINY_RCU -static inline int rcu_needs_cpu (int cpu) +static inline int rcu_needs_cpu (int cpu,unsigned long *delta_jiffies) { + *delta_jiffies =ULONG_MAX ;return 0 ; }
@@ -96,8 +97,9 @@ static inline int rcu_needs_cpu(int cpu)int rcu_preempt_needs_cpu (void ); -static inline int rcu_needs_cpu (int cpu) +static inline int rcu_needs_cpu (int cpu,unsigned long *delta_jiffies) { + *delta_jiffies =ULONG_MAX ;return rcu_preempt_needs_cpu (); }
include/linux/rcutree.h +1 -1
@@ -32,7 +32,7 @@extern void rcu_init (void );extern void rcu_note_context_switch (int cpu); -extern int rcu_needs_cpu (int cpu); +extern int rcu_needs_cpu (int cpu,unsigned long *delta_jiffies);extern void rcu_cpu_stall_reset (void );/*
include/trace/events/rcu.h +1 -0
@@ -289,6 +289,7 @@ TRACE_EVENT(rcu_dyntick,* "In holdoff": Nothing to do, holding off after unsuccessful attempt. * "Begin holdoff": Attempt failed, don't retry until next jiffy. * "Dyntick with callbacks": Entering dyntick-idle despite callbacks. +* "Dyntick with lazy callbacks": Entering dyntick-idle w/lazy callbacks. * "More callbacks": Still more callbacks, try again to clear them out. * "Callbacks drained": All callbacks processed, off to dyntick idle! * "Timer": Timer fired to cause CPU to continue processing callbacks.
kernel/panic.c +3 -3
@@ -27,7 +27,7 @@#define PANIC_TIMER_STEP 100#define PANIC_BLINK_SPD 18 -int panic_on_oops; +int panic_on_oops =CONFIG_PANIC_ON_OOPS_VALUE ;static unsigned long tainted_mask;static int pause_on_oops;static int pause_on_oops_flag;
@@ -108,8 +108,6 @@ void panic(const char *fmt, ...)*/ crash_kexec (NULL ); -kmsg_dump (KMSG_DUMP_PANIC ); -/* * Note smp_send_stop is the usual smp shutdown function, which * unfortunately means it may not be hardened to work in a panic
@@ -117,6 +115,8 @@ void panic(const char *fmt, ...)*/ smp_send_stop (); +kmsg_dump (KMSG_DUMP_PANIC ); +atomic_notifier_call_chain (&panic_notifier_list,0 , buf);bust_spinlocks (0 );
kernel/rcutree.c +2 -0
@@ -1397,6 +1397,8 @@ static void rcu_adopt_orphan_cbs(struct rcu_state *rsp) rdp->qlen_lazy += rsp->qlen_lazy; rdp->qlen += rsp->qlen; rdp->n_cbs_adopted += rsp->qlen; +if (rsp->qlen_lazy != rsp->qlen) +rcu_idle_count_callbacks_posted (); rsp->qlen_lazy =0 ; rsp->qlen =0 ;
kernel/rcutree.h +14 -0
@@ -84,6 +84,20 @@ struct rcu_dynticks {/* Process level is worth LLONG_MAX/2. */ int dynticks_nmi_nesting;/* Track NMI nesting level. */ atomic_t dynticks;/* Even value for idle, else odd. */ +#ifdef CONFIG_RCU_FAST_NO_HZ +int dyntick_drain;/* Prepare-for-idle state variable. */ +unsigned long dyntick_holdoff; +/* No retries for the jiffy of failure. */ +struct timer_list idle_gp_timer; +/* Wake up CPU sleeping with callbacks. */ +unsigned long idle_gp_timer_expires; +/* When to wake up CPU (for repost). */ +bool idle_first_pass;/* First pass of attempt to go idle? */ +unsigned long nonlazy_posted; +/* # times non-lazy CBs posted to CPU. */ +unsigned long nonlazy_posted_snap; +/* idle-period nonlazy_posted snapshot. */ +#endif /* #ifdef CONFIG_RCU_FAST_NO_HZ */ };/* RCU's kthread states for tracing. */
kernel/rcutree_plugin.h +88 -77
260 lines not on this page · raw message
kernel/time/tick-sched.c +6 -1
@@ -274,6 +274,7 @@ EXPORT_SYMBOL_GPL(get_cpu_iowait_time_us);static void tick_nohz_stop_sched_tick (struct tick_sched *ts) {unsigned long seq, last_jiffies, next_jiffies, delta_jiffies; +unsigned long rcu_delta_jiffies;ktime_t last_update, expires, now;struct clock_event_device *dev =__get_cpu_var (tick_cpu_device).evtdev;u64 time_delta;
@@ -322,7 +323,7 @@ static void tick_nohz_stop_sched_tick(struct tick_sched *ts) time_delta =timekeeping_max_deferment (); }while (read_seqretry (&xtime_lock, seq)); -if (rcu_needs_cpu (cpu) ||printk_needs_cpu (cpu) || +if (rcu_needs_cpu (cpu, &rcu_delta_jiffies) ||printk_needs_cpu (cpu) ||arch_needs_cpu (cpu)) { next_jiffies = last_jiffies +1 ; delta_jiffies =1 ;
@@ -330,6 +331,10 @@ static void tick_nohz_stop_sched_tick(struct tick_sched *ts)/* Get the next timer wheel timer */ next_jiffies =get_next_timer_interrupt (last_jiffies); delta_jiffies = next_jiffies - last_jiffies; +if (rcu_delta_jiffies < delta_jiffies) { + next_jiffies = last_jiffies + rcu_delta_jiffies; + delta_jiffies = rcu_delta_jiffies; + } }/* * Do not stop the tick, if we are only one off
lib/Kconfig.debug +20 -0
@@ -241,6 +241,26 @@ config BOOTPARAM_SOFTLOCKUP_PANIC_VALUE default 0 if !BOOTPARAM_SOFTLOCKUP_PANIC default 1 if BOOTPARAM_SOFTLOCKUP_PANIC +config PANIC_ON_OOPS + bool "Panic on Oops" if EXPERT + default n + help + Say Y here to enable the kernel to panic when it oopses. This + has the same effect as setting oops=panic on the kernel command + line. + + This feature is useful to ensure that the kernel does not do + anything erroneous after an oops which could result in data + corruption or other issues. + + Say N if unsure. + +config PANIC_ON_OOPS_VALUE + int + range 0 1 + default 0 if !PANIC_ON_OOPS + default 1 if PANIC_ON_OOPS + config DETECT_HUNG_TASK bool "Detect Hung Tasks" depends on DEBUG_KERNEL
lib/spinlock_debug.c +1 -1
@@ -118,7 +118,7 @@ static void __spin_lock_debug(raw_spinlock_t *lock)/* lockup suspected: */ if (print_once) { print_once =0 ; -spin_dump (lock,"lockup" ); +spin_dump (lock,"lockup suspected" );#ifdef CONFIG_SMP trigger_all_cpu_backtrace ();#endif
mm/memblock.c +20 -0
@@ -867,6 +867,16 @@ int __init_memblock memblock_is_memory(phys_addr_t addr)return memblock_search (&memblock.memory, addr) !=-1 ; } +/** +* memblock_is_region_memory - check if a region is a subset of memory +* @base: base of region to check +* @size: size of region to check +* +* Check if the region [@base, @base+@size) is a subset of a memory block. +* +* RETURNS: +* 0 if false, non-zero if true +*/ int __init_memblock memblock_is_region_memory(phys_addr_t base, phys_addr_t size) {int idx =memblock_search (&memblock.memory, base);
@@ -879,6 +889,16 @@ int __init_memblock memblock_is_region_memory(phys_addr_t base, phys_addr_t size memblock.memory.regions[idx].size) >= end; } +/** +* memblock_is_region_reserved - check if a region intersects reserved memory +* @base: base of region to check +* @size: size of region to check +* +* Check if the region [@base, @base+@size) intersects a reserved memory block. +* +* RETURNS: +* 0 if false, non-zero if true +*/ int __init_memblock memblock_is_region_reserved(phys_addr_t base, phys_addr_t size) {memblock_cap_size (base, &size);