aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorTyrel Datwyler <tyreld@linux.vnet.ibm.com>2015-03-27 15:47:25 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2015-03-27 21:20:39 -0400
commitc03e73740d24fbe990291cd9ac2d6ae0d95b975f (patch)
tree685d741c017c657f419c85788bc4e217beac9a60 /arch/powerpc
parent52fd475042dc145284d05f86ceac66ef5ed6665c (diff)
powerpc/pseries: Simplify check for suspendability during suspend/migration
During suspend/migration operation we must wait for the VASI state reported by the hypervisor to become Suspending prior to making the ibm,suspend-me RTAS call. Calling routines to rtas_ibm_supend_me() pass a vasi_state variable that exposes the VASI state to the caller. This is unnecessary as the caller only really cares about the following three conditions; if there is an error we should bailout, success indicating we have suspended and woken back up so proceed to device tree update, or we are not suspendable yet so try calling rtas_ibm_suspend_me again shortly. This patch removes the extraneous vasi_state variable and simply uses the return code to communicate how to proceed. We either succeed, fail, or get -EAGAIN in which case we sleep for a second before trying to call rtas_ibm_suspend_me again. The behaviour of ppc_rtas() remains the same, but migrate_store() now returns the propogated error code on failure. Previously -1 was returned from migrate_store() in the failure case which equates to -EPERM and was clearly wrong. Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com> Cc: Nathan Fontenont <nfont@linux.vnet.ibm.com> Cc: Cyril Bur <cyrilbur@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/include/asm/rtas.h2
-rw-r--r--arch/powerpc/kernel/rtas.c26
-rw-r--r--arch/powerpc/platforms/pseries/mobility.c9
3 files changed, 17 insertions, 20 deletions
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index c3c99eb35448..398106f12617 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -328,7 +328,7 @@ extern int rtas_suspend_cpu(struct rtas_suspend_me_data *data);
328extern int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data); 328extern int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data);
329extern int rtas_online_cpus_mask(cpumask_var_t cpus); 329extern int rtas_online_cpus_mask(cpumask_var_t cpus);
330extern int rtas_offline_cpus_mask(cpumask_var_t cpus); 330extern int rtas_offline_cpus_mask(cpumask_var_t cpus);
331extern int rtas_ibm_suspend_me(u64 handle, int *vasi_return); 331extern int rtas_ibm_suspend_me(u64 handle);
332 332
333struct rtc_time; 333struct rtc_time;
334extern unsigned long rtas_get_boot_time(void); 334extern unsigned long rtas_get_boot_time(void);
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 21c45a2d0706..b9a7b8981ef7 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -897,7 +897,7 @@ int rtas_offline_cpus_mask(cpumask_var_t cpus)
897} 897}
898EXPORT_SYMBOL(rtas_offline_cpus_mask); 898EXPORT_SYMBOL(rtas_offline_cpus_mask);
899 899
900int rtas_ibm_suspend_me(u64 handle, int *vasi_return) 900int rtas_ibm_suspend_me(u64 handle)
901{ 901{
902 long state; 902 long state;
903 long rc; 903 long rc;
@@ -919,13 +919,11 @@ int rtas_ibm_suspend_me(u64 handle, int *vasi_return)
919 printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned %ld\n",rc); 919 printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned %ld\n",rc);
920 return rc; 920 return rc;
921 } else if (state == H_VASI_ENABLED) { 921 } else if (state == H_VASI_ENABLED) {
922 *vasi_return = RTAS_NOT_SUSPENDABLE; 922 return -EAGAIN;
923 return 0;
924 } else if (state != H_VASI_SUSPENDING) { 923 } else if (state != H_VASI_SUSPENDING) {
925 printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned state %ld\n", 924 printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned state %ld\n",
926 state); 925 state);
927 *vasi_return = -1; 926 return -EIO;
928 return 0;
929 } 927 }
930 928
931 if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY)) 929 if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY))
@@ -972,7 +970,7 @@ out:
972 return atomic_read(&data.error); 970 return atomic_read(&data.error);
973} 971}
974#else /* CONFIG_PPC_PSERIES */ 972#else /* CONFIG_PPC_PSERIES */
975int rtas_ibm_suspend_me(u64 handle, int *vasi_return) 973int rtas_ibm_suspend_me(u64 handle)
976{ 974{
977 return -ENOSYS; 975 return -ENOSYS;
978} 976}
@@ -1022,7 +1020,6 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
1022 unsigned long flags; 1020 unsigned long flags;
1023 char *buff_copy, *errbuf = NULL; 1021 char *buff_copy, *errbuf = NULL;
1024 int nargs, nret, token; 1022 int nargs, nret, token;
1025 int rc;
1026 1023
1027 if (!capable(CAP_SYS_ADMIN)) 1024 if (!capable(CAP_SYS_ADMIN))
1028 return -EPERM; 1025 return -EPERM;
@@ -1054,15 +1051,18 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
1054 if (token == ibm_suspend_me_token) { 1051 if (token == ibm_suspend_me_token) {
1055 1052
1056 /* 1053 /*
1057 * rtas_ibm_suspend_me assumes args are in cpu endian, or at least the 1054 * rtas_ibm_suspend_me assumes the streamid handle is in cpu
1058 * hcall within it requires it. 1055 * endian, or at least the hcall within it requires it.
1059 */ 1056 */
1060 int vasi_rc = 0; 1057 int rc = 0;
1061 u64 handle = ((u64)be32_to_cpu(args.args[0]) << 32) 1058 u64 handle = ((u64)be32_to_cpu(args.args[0]) << 32)
1062 | be32_to_cpu(args.args[1]); 1059 | be32_to_cpu(args.args[1]);
1063 rc = rtas_ibm_suspend_me(handle, &vasi_rc); 1060 rc = rtas_ibm_suspend_me(handle);
1064 args.rets[0] = cpu_to_be32(vasi_rc); 1061 if (rc == -EAGAIN)
1065 if (rc) 1062 args.rets[0] = cpu_to_be32(RTAS_NOT_SUSPENDABLE);
1063 else if (rc == -EIO)
1064 args.rets[0] = cpu_to_be32(-1);
1065 else if (rc)
1066 return rc; 1066 return rc;
1067 goto copy_return; 1067 goto copy_return;
1068 } 1068 }
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index 03a428e87b14..38db1b9f2ac3 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -318,22 +318,19 @@ static ssize_t migrate_store(struct class *class, struct class_attribute *attr,
318{ 318{
319 u64 streamid; 319 u64 streamid;
320 int rc; 320 int rc;
321 int vasi_rc = 0;
322 321
323 rc = kstrtou64(buf, 0, &streamid); 322 rc = kstrtou64(buf, 0, &streamid);
324 if (rc) 323 if (rc)
325 return rc; 324 return rc;
326 325
327 do { 326 do {
328 rc = rtas_ibm_suspend_me(streamid, &vasi_rc); 327 rc = rtas_ibm_suspend_me(streamid);
329 if (!rc && vasi_rc == RTAS_NOT_SUSPENDABLE) 328 if (rc == -EAGAIN)
330 ssleep(1); 329 ssleep(1);
331 } while (!rc && vasi_rc == RTAS_NOT_SUSPENDABLE); 330 } while (rc == -EAGAIN);
332 331
333 if (rc) 332 if (rc)
334 return rc; 333 return rc;
335 if (vasi_rc)
336 return vasi_rc;
337 334
338 post_mobility_fixup(); 335 post_mobility_fixup();
339 return count; 336 return count;