Skip to content

Commit

Permalink
[S390] Force PSW restart on online CPU
Browse files Browse the repository at this point in the history
PSW restart can be triggered on offline CPUs. If this happens, currently
the PSW restart code fails, because functions like smp_processor_id()
do not work on offline CPUs. This patch fixes this as follows:

If PSW restart is triggered on an offline CPU, the PSW restart (sigp restart)
is done a second time on another CPU that is online and the old CPU is
stopped afterwards.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
  • Loading branch information
Michael Holzheu authored and Martin Schwidefsky committed Oct 30, 2011
1 parent d3bf379 commit 1943f53
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 0 deletions.
5 changes: 5 additions & 0 deletions arch/s390/include/asm/smp.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ extern struct save_area *zfcpdump_save_areas[NR_CPUS + 1];
extern void smp_switch_to_ipl_cpu(void (*func)(void *), void *);
extern void smp_switch_to_cpu(void (*)(void *), void *, unsigned long sp,
int from, int to);
extern void smp_restart_with_online_cpu(void);
extern void smp_restart_cpu(void);

/*
Expand Down Expand Up @@ -64,6 +65,10 @@ static inline void smp_switch_to_ipl_cpu(void (*func)(void *), void *data)
func(data);
}

static inline void smp_restart_with_online_cpu(void)
{
}

#define smp_vcpu_scheduled (1)

#endif /* CONFIG_SMP */
Expand Down
1 change: 1 addition & 0 deletions arch/s390/kernel/ipl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1738,6 +1738,7 @@ static struct kobj_attribute on_restart_attr =

void do_restart(void)
{
smp_restart_with_online_cpu();
smp_send_stop();
on_restart_trigger.action->fn(&on_restart_trigger);
stop_run(&on_restart_trigger);
Expand Down
23 changes: 23 additions & 0 deletions arch/s390/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,29 @@ static inline int cpu_stopped(int cpu)
return raw_cpu_stopped(cpu_logical_map(cpu));
}

/*
* Ensure that PSW restart is done on an online CPU
*/
void smp_restart_with_online_cpu(void)
{
int cpu;

for_each_online_cpu(cpu) {
if (stap() == __cpu_logical_map[cpu]) {
/* We are online: Enable DAT again and return */
__load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK);
return;
}
}
/* We are not online: Do PSW restart on an online CPU */
while (sigp(cpu, sigp_restart) == sigp_busy)
cpu_relax();
/* And stop ourself */
while (raw_sigp(stap(), sigp_stop) == sigp_busy)
cpu_relax();
for (;;);
}

void smp_switch_to_ipl_cpu(void (*func)(void *), void *data)
{
struct _lowcore *lc, *current_lc;
Expand Down

0 comments on commit 1943f53

Please sign in to comment.