Commit c5e3acd6 authored by Heiko Carstens's avatar Heiko Carstens Committed by Martin Schwidefsky

s390/smp: avoid concurrent write to sigp status field

When a sigp instruction is issued it may store a status. This status is
currently stored in a per cpu field of the target cpu.
If multiple cpus issue a sigp instruction with the same target cpu
and a status is stored the result is not necessarily as expected.

Currently this is not an issue:
- on cpu hotplug no sigps, except "restart" and "sense" are sent to the
  target cpu.
- on external call we don't look at the status if it is stored
- on sense running the condition code "status stored" is sufficient to
  tell if a cpu is running or not
Signed-off-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent fbf3c542
...@@ -66,7 +66,6 @@ struct pcpu { ...@@ -66,7 +66,6 @@ struct pcpu {
unsigned long panic_stack; /* panic stack for the cpu */ unsigned long panic_stack; /* panic stack for the cpu */
unsigned long ec_mask; /* bit mask for ec_xxx functions */ unsigned long ec_mask; /* bit mask for ec_xxx functions */
int state; /* physical cpu state */ int state; /* physical cpu state */
u32 status; /* last status received via sigp */
u16 address; /* physical cpu address */ u16 address; /* physical cpu address */
}; };
...@@ -99,7 +98,7 @@ static inline int __pcpu_sigp_relax(u16 addr, u8 order, u32 parm, u32 *status) ...@@ -99,7 +98,7 @@ static inline int __pcpu_sigp_relax(u16 addr, u8 order, u32 parm, u32 *status)
int cc; int cc;
while (1) { while (1) {
cc = __pcpu_sigp(addr, order, parm, status); cc = __pcpu_sigp(addr, order, parm, NULL);
if (cc != SIGP_CC_BUSY) if (cc != SIGP_CC_BUSY)
return cc; return cc;
cpu_relax(); cpu_relax();
...@@ -111,7 +110,7 @@ static int pcpu_sigp_retry(struct pcpu *pcpu, u8 order, u32 parm) ...@@ -111,7 +110,7 @@ static int pcpu_sigp_retry(struct pcpu *pcpu, u8 order, u32 parm)
int cc, retry; int cc, retry;
for (retry = 0; ; retry++) { for (retry = 0; ; retry++) {
cc = __pcpu_sigp(pcpu->address, order, parm, &pcpu->status); cc = __pcpu_sigp(pcpu->address, order, parm, NULL);
if (cc != SIGP_CC_BUSY) if (cc != SIGP_CC_BUSY)
break; break;
if (retry >= 3) if (retry >= 3)
...@@ -122,16 +121,18 @@ static int pcpu_sigp_retry(struct pcpu *pcpu, u8 order, u32 parm) ...@@ -122,16 +121,18 @@ static int pcpu_sigp_retry(struct pcpu *pcpu, u8 order, u32 parm)
static inline int pcpu_stopped(struct pcpu *pcpu) static inline int pcpu_stopped(struct pcpu *pcpu)
{ {
u32 status;
if (__pcpu_sigp(pcpu->address, SIGP_SENSE, if (__pcpu_sigp(pcpu->address, SIGP_SENSE,
0, &pcpu->status) != SIGP_CC_STATUS_STORED) 0, &status) != SIGP_CC_STATUS_STORED)
return 0; return 0;
return !!(pcpu->status & (SIGP_STATUS_CHECK_STOP|SIGP_STATUS_STOPPED)); return !!(status & (SIGP_STATUS_CHECK_STOP|SIGP_STATUS_STOPPED));
} }
static inline int pcpu_running(struct pcpu *pcpu) static inline int pcpu_running(struct pcpu *pcpu)
{ {
if (__pcpu_sigp(pcpu->address, SIGP_SENSE_RUNNING, if (__pcpu_sigp(pcpu->address, SIGP_SENSE_RUNNING,
0, &pcpu->status) != SIGP_CC_STATUS_STORED) 0, NULL) != SIGP_CC_STATUS_STORED)
return 1; return 1;
/* Status stored condition code is equivalent to cpu not running. */ /* Status stored condition code is equivalent to cpu not running. */
return 0; return 0;
......
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