diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/irq/chip.c | 8 | ||||
-rw-r--r-- | kernel/kexec.c | 12 | ||||
-rw-r--r-- | kernel/power/suspend.c | 37 | ||||
-rw-r--r-- | kernel/printk.c | 12 | ||||
-rw-r--r-- | kernel/trace/trace.c | 11 | ||||
-rw-r--r-- | kernel/trace/trace_events.c | 3 | ||||
-rw-r--r-- | kernel/trace/trace_sched_switch.c | 10 |
7 files changed, 85 insertions, 8 deletions
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 3914c1e03cf..468bcbc5db4 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -266,7 +266,7 @@ void handle_nested_irq(unsigned int irq) { struct irq_desc *desc = irq_to_desc(irq); struct irqaction *action; - irqreturn_t action_ret; + irqreturn_t action_ret = IRQ_NONE; might_sleep(); @@ -281,7 +281,11 @@ void handle_nested_irq(unsigned int irq) irqd_set(&desc->irq_data, IRQD_IRQ_INPROGRESS); raw_spin_unlock_irq(&desc->lock); - action_ret = action->thread_fn(action->irq, action->dev_id); + do { + action_ret |= action->thread_fn(action->irq, action->dev_id); + action = action->next; + } while (action); + if (!noirqdebug) note_interrupt(irq, desc, action_ret); diff --git a/kernel/kexec.c b/kernel/kexec.c index 4e2e472f6ae..799064323aa 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -48,6 +48,8 @@ u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4]; size_t vmcoreinfo_size; size_t vmcoreinfo_max_size = sizeof(vmcoreinfo_data); +ATOMIC_NOTIFIER_HEAD(crash_percpu_notifier_list); + /* Location of the reserved area for the crash kernel */ struct resource crashk_res = { .name = "Crash kernel", @@ -1080,6 +1082,7 @@ asmlinkage long compat_sys_kexec_load(unsigned long entry, void crash_kexec(struct pt_regs *regs) { + struct pt_regs fixed_regs; /* Take the kexec_mutex here to prevent sys_kexec_load * running on one cpu from replacing the crash kernel * we are using after a panic on a different cpu. @@ -1090,13 +1093,20 @@ void crash_kexec(struct pt_regs *regs) */ if (mutex_trylock(&kexec_mutex)) { if (kexec_crash_image) { - struct pt_regs fixed_regs; crash_setup_regs(&fixed_regs, regs); crash_save_vmcoreinfo(); machine_crash_shutdown(&fixed_regs); machine_kexec(kexec_crash_image); } +#ifdef CONFIG_CRASH_SWRESET + else { + crash_setup_regs(&fixed_regs, regs); + crash_save_vmcoreinfo(); + machine_crash_shutdown(&fixed_regs); + machine_crash_swreset(); + } +#endif mutex_unlock(&kexec_mutex); } } diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 396d262b8fd..e53c663a5e9 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -23,6 +23,7 @@ #include <linux/slab.h> #include <linux/export.h> #include <linux/suspend.h> +#include <linux/kthread.h> #include <linux/syscore_ops.h> #include <trace/events/power.h> @@ -35,6 +36,10 @@ const char *const pm_states[PM_SUSPEND_MAX] = { static const struct platform_suspend_ops *suspend_ops; +static struct completion second_cpu_complete = {1, + __WAIT_QUEUE_HEAD_INITIALIZER((second_cpu_complete).wait) +}; + /** * suspend_set_ops - Set the global suspend method table. * @ops: Suspend operations to use. @@ -157,9 +162,10 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) if (suspend_test(TEST_PLATFORM)) goto Platform_wake; + error = disable_nonboot_cpus(); if (error || suspend_test(TEST_CPUS)) - goto Enable_cpus; + goto Platform_wake; arch_suspend_disable_irqs(); BUG_ON(!irqs_disabled()); @@ -177,9 +183,6 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) arch_suspend_enable_irqs(); BUG_ON(irqs_disabled()); - Enable_cpus: - enable_nonboot_cpus(); - Platform_wake: if (suspend_ops->wake) suspend_ops->wake(); @@ -257,6 +260,18 @@ static void suspend_finish(void) pm_restore_console(); } +static int plug_secondary_cpus(void *data) +{ + if (!(suspend_test(TEST_FREEZER) || + suspend_test(TEST_DEVICES) || + suspend_test(TEST_PLATFORM))) + enable_nonboot_cpus(); + + complete(&second_cpu_complete); + + return 0; +} + /** * enter_state - Do common work needed to enter system sleep state. * @state: System sleep state to enter. @@ -268,6 +283,7 @@ static void suspend_finish(void) static int enter_state(suspend_state_t state) { int error; + struct task_struct *cpu_task; if (!valid_state(state)) return -ENODEV; @@ -275,6 +291,14 @@ static int enter_state(suspend_state_t state) if (!mutex_trylock(&pm_mutex)) return -EBUSY; + /* + * Assure that previous started thread is completed before + * attempting to suspend again. + */ + error = wait_for_completion_timeout(&second_cpu_complete, + msecs_to_jiffies(500)); + WARN_ON(error == 0); + printk(KERN_INFO "PM: Syncing filesystems ... "); sys_sync(); printk("done.\n"); @@ -296,6 +320,11 @@ static int enter_state(suspend_state_t state) pr_debug("PM: Finishing wakeup.\n"); suspend_finish(); Unlock: + + cpu_task = kthread_run(plug_secondary_cpus, + NULL, "cpu-plug"); + BUG_ON(IS_ERR(cpu_task)); + mutex_unlock(&pm_mutex); return error; } diff --git a/kernel/printk.c b/kernel/printk.c index b663c2c95d3..c538c187618 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -41,6 +41,7 @@ #include <linux/cpu.h> #include <linux/notifier.h> #include <linux/rculist.h> +#include <trace/stm.h> #include <asm/uaccess.h> @@ -56,6 +57,10 @@ void asmlinkage __attribute__((weak)) early_printk(const char *fmt, ...) #define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) +#ifdef CONFIG_PRINTK_LL +extern void printascii(char *); +#endif + /* printk's without a loglevel use this.. */ #define DEFAULT_MESSAGE_LOGLEVEL CONFIG_DEFAULT_MESSAGE_LOGLEVEL @@ -884,6 +889,10 @@ asmlinkage int vprintk(const char *fmt, va_list args) printed_len += vscnprintf(printk_buf + printed_len, sizeof(printk_buf) - printed_len, fmt, args); +#ifdef CONFIG_PRINTK_LL + printascii(printk_buf); +#endif + p = printk_buf; /* Read log level and handle special printk prefix */ @@ -905,6 +914,9 @@ asmlinkage int vprintk(const char *fmt, va_list args) } } + /* Send printk buffer to MIPI STM trace hardware too if enable */ + stm_dup_printk(printk_buf, printed_len); + /* * Copy the output into log_buf. If the caller didn't provide * the appropriate log prefix, we insert them here diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 2a22255c101..dba8f56afc2 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -38,6 +38,7 @@ #include <linux/poll.h> #include <linux/nmi.h> #include <linux/fs.h> +#include <trace/stm.h> #include "trace.h" #include "trace_output.h" @@ -965,7 +966,7 @@ void tracing_reset_current_online_cpus(void) tracing_reset_online_cpus(&global_trace); } -#define SAVED_CMDLINES 128 +#define SAVED_CMDLINES 2048 #define NO_CMDLINE_MAP UINT_MAX static unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; static unsigned map_cmdline_to_pid[SAVED_CMDLINES]; @@ -1293,6 +1294,8 @@ trace_function(struct trace_array *tr, if (!filter_check_discard(call, entry, buffer, event)) ring_buffer_unlock_commit(buffer, event); + + stm_ftrace(ip, parent_ip); } void @@ -1387,6 +1390,8 @@ static void __ftrace_trace_stack(struct ring_buffer *buffer, if (!filter_check_discard(call, entry, buffer, event)) ring_buffer_unlock_commit(buffer, event); + stm_stack_trace(trace.entries); + out: /* Again, don't let gcc optimize things here */ barrier(); @@ -1557,6 +1562,8 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args) ftrace_trace_stack(buffer, flags, 6, pc); } + stm_trace_bprintk_buf(ip, fmt, trace_buf, sizeof(u32) * len); + out_unlock: arch_spin_unlock(&trace_buf_lock); local_irq_restore(flags); @@ -1633,6 +1640,8 @@ int trace_array_vprintk(struct trace_array *tr, ftrace_trace_stack(buffer, irq_flags, 6, pc); } + stm_trace_printk_buf(ip, trace_buf, len); + out_unlock: arch_spin_unlock(&trace_buf_lock); raw_local_irq_restore(irq_flags); diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 29111da1d10..7dd750a3443 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -19,6 +19,7 @@ #include <linux/delay.h> #include <asm/setup.h> +#include <trace/stm.h> #include "trace_output.h" @@ -1712,6 +1713,8 @@ function_test_events_call(unsigned long ip, unsigned long parent_ip) trace_nowake_buffer_unlock_commit(buffer, event, flags, pc); + stm_ftrace(ip, parent_ip); + out: atomic_dec(&per_cpu(ftrace_test_event_disable, cpu)); preempt_enable_notrace(); diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index 7e62c0a1845..a136fd86533 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c @@ -11,6 +11,7 @@ #include <linux/uaccess.h> #include <linux/ftrace.h> #include <trace/events/sched.h> +#include <trace/stm.h> #include "trace.h" @@ -47,6 +48,10 @@ tracing_sched_switch_trace(struct trace_array *tr, if (!filter_check_discard(call, entry, buffer, event)) trace_buffer_unlock_commit(buffer, event, flags, pc); + + stm_sched_switch(entry->prev_pid, entry->prev_prio, entry->prev_state, + entry->next_pid, entry->next_prio, entry->next_state, + entry->next_cpu); } static void @@ -103,6 +108,11 @@ tracing_sched_wakeup_trace(struct trace_array *tr, if (!filter_check_discard(call, entry, buffer, event)) ring_buffer_unlock_commit(buffer, event); + + stm_sched_wakeup(entry->prev_pid, entry->prev_prio, entry->prev_state, + entry->next_pid, entry->next_prio, entry->next_state, + entry->next_cpu); + ftrace_trace_stack(tr->buffer, flags, 6, pc); ftrace_trace_userstack(tr->buffer, flags, pc); } |