Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 280630
b: refs/heads/master
c: 85ac7ca
h: refs/heads/master
v: v3
  • Loading branch information
Martin Schwidefsky committed Dec 27, 2011
1 parent 27fa39d commit c89ccc6
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 9 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3a3954ceae756ed2a5d53b45c67db6dde3c0c126
refs/heads/master: 85ac7ca5972d63d23aa5ea75c3834a33b951f89d
1 change: 1 addition & 0 deletions trunk/arch/s390/include/asm/sigp.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ enum {
ec_schedule = 0,
ec_call_function,
ec_call_function_single,
ec_stop_cpu,
};

/*
Expand Down
50 changes: 42 additions & 8 deletions trunk/arch/s390/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,22 +154,52 @@ void smp_switch_to_ipl_cpu(void (*func)(void *), void *data)
smp_switch_to_cpu(func, data, sp, stap(), __cpu_logical_map[0]);
}

static void smp_stop_cpu(void)
{
while (sigp(smp_processor_id(), sigp_stop) == sigp_busy)
cpu_relax();
}

void smp_send_stop(void)
{
int cpu, rc;
cpumask_t cpumask;
int cpu;
u64 end;

/* Disable all interrupts/machine checks */
__load_psw_mask(psw_kernel_bits | PSW_MASK_DAT);
trace_hardirqs_off();

/* stop all processors */
for_each_online_cpu(cpu) {
if (cpu == smp_processor_id())
continue;
do {
rc = sigp(cpu, sigp_stop);
} while (rc == sigp_busy);
cpumask_copy(&cpumask, cpu_online_mask);
cpumask_clear_cpu(smp_processor_id(), &cpumask);

if (oops_in_progress) {
/*
* Give the other cpus the opportunity to complete
* outstanding interrupts before stopping them.
*/
end = get_clock() + (1000000UL << 12);
for_each_cpu(cpu, &cpumask) {
set_bit(ec_stop_cpu, (unsigned long *)
&lowcore_ptr[cpu]->ext_call_fast);
while (sigp(cpu, sigp_emergency_signal) == sigp_busy &&
get_clock() < end)
cpu_relax();
}
while (get_clock() < end) {
for_each_cpu(cpu, &cpumask)
if (cpu_stopped(cpu))
cpumask_clear_cpu(cpu, &cpumask);
if (cpumask_empty(&cpumask))
break;
cpu_relax();
}
}

/* stop all processors */
for_each_cpu(cpu, &cpumask) {
while (sigp(cpu, sigp_stop) == sigp_busy)
cpu_relax();
while (!cpu_stopped(cpu))
cpu_relax();
}
Expand All @@ -194,6 +224,9 @@ static void do_ext_call_interrupt(unsigned int ext_int_code,
*/
bits = xchg(&S390_lowcore.ext_call_fast, 0);

if (test_bit(ec_stop_cpu, &bits))
smp_stop_cpu();

if (test_bit(ec_schedule, &bits))
scheduler_ipi();

Expand All @@ -202,6 +235,7 @@ static void do_ext_call_interrupt(unsigned int ext_int_code,

if (test_bit(ec_call_function_single, &bits))
generic_smp_call_function_single_interrupt();

}

/*
Expand Down

0 comments on commit c89ccc6

Please sign in to comment.