summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/irq/chip.c9
-rw-r--r--kernel/irq/irqdesc.c1
-rw-r--r--kernel/kexec.c12
-rw-r--r--kernel/panic.c4
-rw-r--r--kernel/power/suspend.c37
-rw-r--r--kernel/printk.c12
-rw-r--r--kernel/sched/core.c2
-rw-r--r--kernel/trace/trace.c11
-rw-r--r--kernel/trace/trace_events.c8
-rw-r--r--kernel/trace/trace_export.c1
-rw-r--r--kernel/trace/trace_sched_switch.c10
11 files changed, 96 insertions, 11 deletions
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 6080f6bc8c3..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);
@@ -518,6 +522,7 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
out_unlock:
raw_spin_unlock(&desc->lock);
}
+EXPORT_SYMBOL(handle_edge_irq);
#ifdef CONFIG_IRQ_EDGE_EOI_HANDLER
/**
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index d86e254b95e..192a302d6cf 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -112,6 +112,7 @@ struct irq_desc *irq_to_desc(unsigned int irq)
{
return radix_tree_lookup(&irq_desc_tree, irq);
}
+EXPORT_SYMBOL(irq_to_desc);
static void delete_irq_desc(unsigned int irq)
{
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/panic.c b/kernel/panic.c
index b47ca87a6aa..c4093d317bd 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -107,6 +107,8 @@ void panic(const char *fmt, ...)
dump_stack();
#endif
+ atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
+
/*
* If we have crashed and we have a crash kernel loaded let it handle
* everything else.
@@ -123,8 +125,6 @@ void panic(const char *fmt, ...)
*/
smp_send_stop();
- atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
-
bust_spinlocks(0);
if (!panic_blink)
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 45ac7560d7b..cce10a33c8f 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
@@ -931,6 +936,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 */
@@ -952,6 +961,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/sched/core.c b/kernel/sched/core.c
index d5c92579d61..9d35dfeda3e 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -6382,6 +6382,8 @@ static int __sdt_alloc(const struct cpumask *cpu_map)
if (!sg)
return -ENOMEM;
+ sg->next = sg;
+
*per_cpu_ptr(sdd->sg, j) = sg;
sgp = kzalloc_node(sizeof(struct sched_group_power),
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 079a93ae8a9..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"
@@ -294,6 +295,9 @@ static int __ftrace_set_clr_event(const char *match, const char *sub,
if (!call->name || !call->class || !call->class->reg)
continue;
+ if (call->flags & TRACE_EVENT_FL_IGNORE_ENABLE)
+ continue;
+
if (match &&
strcmp(match, call->name) != 0 &&
strcmp(match, call->class->system) != 0)
@@ -1164,7 +1168,7 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
return -1;
}
- if (call->class->reg)
+ if (call->class->reg && !(call->flags & TRACE_EVENT_FL_IGNORE_ENABLE))
trace_create_file("enable", 0644, call->dir, call,
enable);
@@ -1709,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_export.c b/kernel/trace/trace_export.c
index 3dd15e8bc85..e039906b037 100644
--- a/kernel/trace/trace_export.c
+++ b/kernel/trace/trace_export.c
@@ -180,6 +180,7 @@ struct ftrace_event_call __used event_##call = { \
.event.type = etype, \
.class = &event_class_ftrace_##call, \
.print_fmt = print, \
+ .flags = TRACE_EVENT_FL_IGNORE_ENABLE, \
}; \
struct ftrace_event_call __used \
__attribute__((section("_ftrace_events"))) *__event_##call = &event_##call;
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);
}