aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMahesh Salgaonkar <mahesh@linux.vnet.ibm.com>2016-10-27 18:14:40 +0530
committerStewart Smith <stewart@linux.vnet.ibm.com>2016-11-02 17:31:52 +1100
commitf1cde7dcd3485ec7c1bb2ee385049ef200859a5b (patch)
tree4ff3b6255cc4602ce5106d67efaab512c11bca23
parent322317b06939befbe87397e8d26f4dfca975f763 (diff)
downloadskiboot-f1cde7dcd3485ec7c1bb2ee385049ef200859a5b.zip
skiboot-f1cde7dcd3485ec7c1bb2ee385049ef200859a5b.tar.gz
skiboot-f1cde7dcd3485ec7c1bb2ee385049ef200859a5b.tar.bz2
opal/fast-reboot: Send special reset sequence to operational CPUs only.
In the fast reboot path opal sends multiple special sequence to all the CPUs using xscom operations. On freshly booted system where all CPUs are in good condition, the fast reboot works fine. But fast reboot fails when any of the COREs are GARDed by Service processor. This is because xscom operations fails/timeout on the CPUs/COREs that are GARDed. Fix this issue by skipping GARDed CPUs during fast reboot path. The GARDed CPUs are presented as 'bad' to OPAL and OPAL marks that cpu->state as 'cpu_state_unavailable'. This patch checks the cpu state to skip GARDed CPUs during fast reboot. Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
-rw-r--r--core/fast-reboot.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/core/fast-reboot.c b/core/fast-reboot.c
index 12ebf5b..e9a18bc 100644
--- a/core/fast-reboot.c
+++ b/core/fast-reboot.c
@@ -235,8 +235,12 @@ static bool fast_reset_p8(void)
prlog(PR_DEBUG, "RESET: Resetting from cpu: 0x%x (core 0x%x)\n",
this_cpu()->pir, pir_to_core_id(this_cpu()->pir));
- /* Assert special wakup on all cores */
+ /* Assert special wakup on all cores. Only on operational cores. */
for_each_cpu(cpu) {
+ /* GARDed CPUs are marked unavailable. Skip them. */
+ if (cpu->state == cpu_state_unavailable)
+ continue;
+
if (cpu->primary == cpu)
if (set_special_wakeup(cpu) != OPAL_SUCCESS)
return false;
@@ -246,6 +250,10 @@ static bool fast_reset_p8(void)
/* Put everybody in stop except myself */
for_each_cpu(cpu) {
+ /* GARDed CPUs are marked unavailable. Skip them. */
+ if (cpu->state == cpu_state_unavailable)
+ continue;
+
if (cpu != this_cpu())
set_direct_ctl(cpu, P8_DIRECT_CTL_STOP);
@@ -263,6 +271,10 @@ static bool fast_reset_p8(void)
/* Put everybody in pre-nap except myself */
for_each_cpu(cpu) {
+ /* GARDed CPUs are marked unavailable. Skip them. */
+ if (cpu->state == cpu_state_unavailable)
+ continue;
+
if (cpu != this_cpu())
set_direct_ctl(cpu, P8_DIRECT_CTL_PRENAP);
}
@@ -271,6 +283,10 @@ static bool fast_reset_p8(void)
/* Reset everybody except my own core threads */
for_each_cpu(cpu) {
+ /* GARDed CPUs are marked unavailable. Skip them. */
+ if (cpu->state == cpu_state_unavailable)
+ continue;
+
if (cpu != this_cpu())
set_direct_ctl(cpu, P8_DIRECT_CTL_SRESET);
}
@@ -500,6 +516,10 @@ void __noreturn fast_reboot_entry(void)
if (cpu == this_cpu())
continue;
+ /* GARDed CPUs are marked unavailable. Skip them. */
+ if (cpu->state == cpu_state_unavailable)
+ continue;
+
/* XXX Add a callin timeout ? */
while (cpu->state != cpu_state_present) {
smt_very_low();
@@ -519,6 +539,10 @@ void __noreturn fast_reboot_entry(void)
if (cpu == this_cpu())
continue;
+ /* GARDed CPUs are marked unavailable. Skip them. */
+ if (cpu->state == cpu_state_unavailable)
+ continue;
+
/* XXX Add a callin timeout ? */
while (cpu->state == cpu_state_present) {
smt_very_low();
@@ -529,6 +553,10 @@ void __noreturn fast_reboot_entry(void)
prlog(PR_DEBUG, "RESET: Releasing special wakeups...\n");
for_each_cpu(cpu) {
+ /* GARDed CPUs are marked unavailable. Skip them. */
+ if (cpu->state == cpu_state_unavailable)
+ continue;
+
if (cpu->primary == cpu)
clr_special_wakeup(cpu);
}