Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Tyrel Datwyler and committed by
Michael Ellerman
c03e7374 52fd4750

+17 -20
+1 -1
arch/powerpc/include/asm/rtas.h
··· 328 328 extern int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data); 329 329 extern int rtas_online_cpus_mask(cpumask_var_t cpus); 330 330 extern int rtas_offline_cpus_mask(cpumask_var_t cpus); 331 - extern int rtas_ibm_suspend_me(u64 handle, int *vasi_return); 331 + extern int rtas_ibm_suspend_me(u64 handle); 332 332 333 333 struct rtc_time; 334 334 extern unsigned long rtas_get_boot_time(void);
+13 -13
arch/powerpc/kernel/rtas.c
··· 897 897 } 898 898 EXPORT_SYMBOL(rtas_offline_cpus_mask); 899 899 900 - int rtas_ibm_suspend_me(u64 handle, int *vasi_return) 900 + int rtas_ibm_suspend_me(u64 handle) 901 901 { 902 902 long state; 903 903 long rc; ··· 919 919 printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned %ld\n",rc); 920 920 return rc; 921 921 } else if (state == H_VASI_ENABLED) { 922 - *vasi_return = RTAS_NOT_SUSPENDABLE; 923 - return 0; 922 + return -EAGAIN; 924 923 } else if (state != H_VASI_SUSPENDING) { 925 924 printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned state %ld\n", 926 925 state); 927 - *vasi_return = -1; 928 - return 0; 926 + return -EIO; 929 927 } 930 928 931 929 if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY)) ··· 970 972 return atomic_read(&data.error); 971 973 } 972 974 #else /* CONFIG_PPC_PSERIES */ 973 - int rtas_ibm_suspend_me(u64 handle, int *vasi_return) 975 + int rtas_ibm_suspend_me(u64 handle) 974 976 { 975 977 return -ENOSYS; 976 978 } ··· 1020 1022 unsigned long flags; 1021 1023 char *buff_copy, *errbuf = NULL; 1022 1024 int nargs, nret, token; 1023 - int rc; 1024 1025 1025 1026 if (!capable(CAP_SYS_ADMIN)) 1026 1027 return -EPERM; ··· 1051 1054 if (token == ibm_suspend_me_token) { 1052 1055 1053 1056 /* 1054 - * rtas_ibm_suspend_me assumes args are in cpu endian, or at least the 1055 - * hcall within it requires it. 1057 + * rtas_ibm_suspend_me assumes the streamid handle is in cpu 1058 + * endian, or at least the hcall within it requires it. 1056 1059 */ 1057 - int vasi_rc = 0; 1060 + int rc = 0; 1058 1061 u64 handle = ((u64)be32_to_cpu(args.args[0]) << 32) 1059 1062 | be32_to_cpu(args.args[1]); 1060 - rc = rtas_ibm_suspend_me(handle, &vasi_rc); 1061 - args.rets[0] = cpu_to_be32(vasi_rc); 1062 - if (rc) 1063 + rc = rtas_ibm_suspend_me(handle); 1064 + if (rc == -EAGAIN) 1065 + args.rets[0] = cpu_to_be32(RTAS_NOT_SUSPENDABLE); 1066 + else if (rc == -EIO) 1067 + args.rets[0] = cpu_to_be32(-1); 1068 + else if (rc) 1063 1069 return rc; 1064 1070 goto copy_return; 1065 1071 }
+3 -6
arch/powerpc/platforms/pseries/mobility.c
··· 318 318 { 319 319 u64 streamid; 320 320 int rc; 321 - int vasi_rc = 0; 322 321 323 322 rc = kstrtou64(buf, 0, &streamid); 324 323 if (rc) 325 324 return rc; 326 325 327 326 do { 328 - rc = rtas_ibm_suspend_me(streamid, &vasi_rc); 329 - if (!rc && vasi_rc == RTAS_NOT_SUSPENDABLE) 327 + rc = rtas_ibm_suspend_me(streamid); 328 + if (rc == -EAGAIN) 330 329 ssleep(1); 331 - } while (!rc && vasi_rc == RTAS_NOT_SUSPENDABLE); 330 + } while (rc == -EAGAIN); 332 331 333 332 if (rc) 334 333 return rc; 335 - if (vasi_rc) 336 - return vasi_rc; 337 334 338 335 post_mobility_fixup(); 339 336 return count;