[kvm-unit-tests PATCH v2 4/7] s390x: smp: Rework cpu start and active tracking

Janosch Frank
2020-01-16T12:05:36Z

sigp is not synchronous on all hypervisors, so we need to wait until
the cpu runs until we return from the setup/start function.

As there was a lot of duplicate code a common function for cpu
restarts has been intropduced.

Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
---
lib/s390x/smp.c | 45 ++++++++++++++++++++++++---------------------
1 file changed, 24 insertions(+), 21 deletions(-)

diff --git a/lib/s390x/smp.c b/lib/s390x/smp.c
index f57f420..f984a34 100644
--- a/lib/s390x/smp.c
+++ b/lib/s390x/smp.c
@@ -104,35 +104,41 @@ int smp_cpu_stop_store_status(uint16_t addr)
return rc;
}

+static int smp_cpu_restart_nolock(uint16_t addr, struct psw *psw)
+{
+ int rc;
+ struct cpu *cpu = smp_cpu_from_addr(addr);
+
+ if (!cpu)
+ return -1;
+ if (psw) {
+ cpu->lowcore->restart_new_psw.mask = psw->mask;
+ cpu->lowcore->restart_new_psw.addr = psw->addr;
+ }
+ rc = sigp(addr, SIGP_RESTART, 0, NULL);
+ if (rc)
+ return rc;
+ while (!smp_cpu_running(addr)) { mb(); }
+ cpu->active = true;
+ return 0;
+}
+
int smp_cpu_restart(uint16_t addr)
{
- int rc = -1;
- struct cpu *cpu;
+ int rc;

spin_lock(&lock);
- cpu = smp_cpu_from_addr(addr);
- if (cpu) {
- rc = sigp(addr, SIGP_RESTART, 0, NULL);
- cpu->active = true;
- }
+ rc = smp_cpu_restart_nolock(addr, NULL);
spin_unlock(&lock);
return rc;
}

int smp_cpu_start(uint16_t addr, struct psw psw)
{
- int rc = -1;
- struct cpu *cpu;
- struct lowcore *lc;
+ int rc;

spin_lock(&lock);
- cpu = smp_cpu_from_addr(addr);
- if (cpu) {
- lc = cpu->lowcore;
- lc->restart_new_psw.mask = psw.mask;
- lc->restart_new_psw.addr = psw.addr;
- rc = sigp(addr, SIGP_RESTART, 0, NULL);
- }
+ rc = smp_cpu_restart_nolock(addr, &psw);
spin_unlock(&lock);
return rc;
}
@@ -192,10 +198,7 @@ int smp_cpu_setup(uint16_t addr, struct psw psw)
lc->sw_int_crs[0] = 0x0000000000040000UL;

/* Start processing */
- rc = sigp_retry(cpu->addr, SIGP_RESTART, 0, NULL);
- if (!rc)
- cpu->active = true;
-
+ smp_cpu_restart_nolock(addr, NULL);
out:
spin_unlock(&lock);
return rc;
--
2.20.1