Commit 82b23cb9 authored by Linus Torvalds's avatar Linus Torvalds

Merge branches 'perf-urgent-for-linus', 'smp-urgent-for-linus' and...

Merge branches 'perf-urgent-for-linus', 'smp-urgent-for-linus' and 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf, cpu hotplug and timer fixes from Ingo Molnar:
 "perf:
   - A single tooling fix for a user-triggerable segfault.

  CPU hotplug:
   - Fix a CPU hotplug corner case regression, introduced by the recent
     hotplug rework

  timers:
   - Fix a boot hang in the ARM based Tango SoC clocksource driver"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  perf intel-pt: Fix segfault tracing transactions

* 'smp-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  cpu/hotplug: Fix rollback during error-out in __cpu_disable()

* 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  clocksource/drivers/tango-xtal: Fix boot hang due to incorrect test
...@@ -42,7 +42,7 @@ static void __init tango_clocksource_init(struct device_node *np) ...@@ -42,7 +42,7 @@ static void __init tango_clocksource_init(struct device_node *np)
ret = clocksource_mmio_init(xtal_in_cnt, "tango-xtal", xtal_freq, 350, ret = clocksource_mmio_init(xtal_in_cnt, "tango-xtal", xtal_freq, 350,
32, clocksource_mmio_readl_up); 32, clocksource_mmio_readl_up);
if (!ret) { if (ret) {
pr_err("%s: registration failed\n", np->full_name); pr_err("%s: registration failed\n", np->full_name);
return; return;
} }
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
* @target: The target state * @target: The target state
* @thread: Pointer to the hotplug thread * @thread: Pointer to the hotplug thread
* @should_run: Thread should execute * @should_run: Thread should execute
* @rollback: Perform a rollback
* @cb_stat: The state for a single callback (install/uninstall) * @cb_stat: The state for a single callback (install/uninstall)
* @cb: Single callback function (install/uninstall) * @cb: Single callback function (install/uninstall)
* @result: Result of the operation * @result: Result of the operation
...@@ -47,6 +48,7 @@ struct cpuhp_cpu_state { ...@@ -47,6 +48,7 @@ struct cpuhp_cpu_state {
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
struct task_struct *thread; struct task_struct *thread;
bool should_run; bool should_run;
bool rollback;
enum cpuhp_state cb_state; enum cpuhp_state cb_state;
int (*cb)(unsigned int cpu); int (*cb)(unsigned int cpu);
int result; int result;
...@@ -301,6 +303,11 @@ static int cpu_notify(unsigned long val, unsigned int cpu) ...@@ -301,6 +303,11 @@ static int cpu_notify(unsigned long val, unsigned int cpu)
return __cpu_notify(val, cpu, -1, NULL); return __cpu_notify(val, cpu, -1, NULL);
} }
static void cpu_notify_nofail(unsigned long val, unsigned int cpu)
{
BUG_ON(cpu_notify(val, cpu));
}
/* Notifier wrappers for transitioning to state machine */ /* Notifier wrappers for transitioning to state machine */
static int notify_prepare(unsigned int cpu) static int notify_prepare(unsigned int cpu)
{ {
...@@ -477,6 +484,16 @@ static void cpuhp_thread_fun(unsigned int cpu) ...@@ -477,6 +484,16 @@ static void cpuhp_thread_fun(unsigned int cpu)
} else { } else {
ret = cpuhp_invoke_callback(cpu, st->cb_state, st->cb); ret = cpuhp_invoke_callback(cpu, st->cb_state, st->cb);
} }
} else if (st->rollback) {
BUG_ON(st->state < CPUHP_AP_ONLINE_IDLE);
undo_cpu_down(cpu, st, cpuhp_ap_states);
/*
* This is a momentary workaround to keep the notifier users
* happy. Will go away once we got rid of the notifiers.
*/
cpu_notify_nofail(CPU_DOWN_FAILED, cpu);
st->rollback = false;
} else { } else {
/* Cannot happen .... */ /* Cannot happen .... */
BUG_ON(st->state < CPUHP_AP_ONLINE_IDLE); BUG_ON(st->state < CPUHP_AP_ONLINE_IDLE);
...@@ -636,11 +653,6 @@ static inline void check_for_tasks(int dead_cpu) ...@@ -636,11 +653,6 @@ static inline void check_for_tasks(int dead_cpu)
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
} }
static void cpu_notify_nofail(unsigned long val, unsigned int cpu)
{
BUG_ON(cpu_notify(val, cpu));
}
static int notify_down_prepare(unsigned int cpu) static int notify_down_prepare(unsigned int cpu)
{ {
int err, nr_calls = 0; int err, nr_calls = 0;
...@@ -721,9 +733,10 @@ static int takedown_cpu(unsigned int cpu) ...@@ -721,9 +733,10 @@ static int takedown_cpu(unsigned int cpu)
*/ */
err = stop_machine(take_cpu_down, NULL, cpumask_of(cpu)); err = stop_machine(take_cpu_down, NULL, cpumask_of(cpu));
if (err) { if (err) {
/* CPU didn't die: tell everyone. Can't complain. */ /* CPU refused to die */
cpu_notify_nofail(CPU_DOWN_FAILED, cpu);
irq_unlock_sparse(); irq_unlock_sparse();
/* Unpark the hotplug thread so we can rollback there */
kthread_unpark(per_cpu_ptr(&cpuhp_state, cpu)->thread);
return err; return err;
} }
BUG_ON(cpu_online(cpu)); BUG_ON(cpu_online(cpu));
...@@ -832,6 +845,11 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen, ...@@ -832,6 +845,11 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen,
* to do the further cleanups. * to do the further cleanups.
*/ */
ret = cpuhp_down_callbacks(cpu, st, cpuhp_bp_states, target); ret = cpuhp_down_callbacks(cpu, st, cpuhp_bp_states, target);
if (ret && st->state > CPUHP_TEARDOWN_CPU && st->state < prev_state) {
st->target = prev_state;
st->rollback = true;
cpuhp_kick_ap_work(cpu);
}
hasdied = prev_state != st->state && st->state == CPUHP_OFFLINE; hasdied = prev_state != st->state && st->state == CPUHP_OFFLINE;
out: out:
...@@ -1249,6 +1267,7 @@ static struct cpuhp_step cpuhp_ap_states[] = { ...@@ -1249,6 +1267,7 @@ static struct cpuhp_step cpuhp_ap_states[] = {
.name = "notify:online", .name = "notify:online",
.startup = notify_online, .startup = notify_online,
.teardown = notify_down_prepare, .teardown = notify_down_prepare,
.skip_onerr = true,
}, },
#endif #endif
/* /*
......
...@@ -1130,7 +1130,7 @@ static int intel_pt_synth_transaction_sample(struct intel_pt_queue *ptq) ...@@ -1130,7 +1130,7 @@ static int intel_pt_synth_transaction_sample(struct intel_pt_queue *ptq)
pr_err("Intel Processor Trace: failed to deliver transaction event, error %d\n", pr_err("Intel Processor Trace: failed to deliver transaction event, error %d\n",
ret); ret);
if (pt->synth_opts.callchain) if (pt->synth_opts.last_branch)
intel_pt_reset_last_branch_rb(ptq); intel_pt_reset_last_branch_rb(ptq);
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment