powerpc/pseries: Simplify check for suspendability during suspend/migration
authorTyrel Datwyler <tyreld@linux.vnet.ibm.com>
Fri, 27 Mar 2015 19:47:25 +0000 (12:47 -0700)
committerMichael Ellerman <mpe@ellerman.id.au>
Sat, 28 Mar 2015 01:20:39 +0000 (12:20 +1100)
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>
arch/powerpc/include/asm/rtas.h
arch/powerpc/kernel/rtas.c
arch/powerpc/platforms/pseries/mobility.c

index c3c99eb35448988cf053e3bf5e774c68f30b48f3..398106f126179aaa1a30be6b7ee51afcfa04b495 100644 (file)
@@ -328,7 +328,7 @@ extern int rtas_suspend_cpu(struct rtas_suspend_me_data *data);
 extern int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data);
 extern int rtas_online_cpus_mask(cpumask_var_t cpus);
 extern int rtas_offline_cpus_mask(cpumask_var_t cpus);
-extern int rtas_ibm_suspend_me(u64 handle, int *vasi_return);
+extern int rtas_ibm_suspend_me(u64 handle);
 
 struct rtc_time;
 extern unsigned long rtas_get_boot_time(void);
index 21c45a2d07062d4e43f7dc28065b938207434944..b9a7b8981ef7ba604b06369d37313caf92fa4328 100644 (file)
@@ -897,7 +897,7 @@ int rtas_offline_cpus_mask(cpumask_var_t cpus)
 }
 EXPORT_SYMBOL(rtas_offline_cpus_mask);
 
-int rtas_ibm_suspend_me(u64 handle, int *vasi_return)
+int rtas_ibm_suspend_me(u64 handle)
 {
        long state;
        long rc;
@@ -919,13 +919,11 @@ int rtas_ibm_suspend_me(u64 handle, int *vasi_return)
                printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned %ld\n",rc);
                return rc;
        } else if (state == H_VASI_ENABLED) {
-               *vasi_return = RTAS_NOT_SUSPENDABLE;
-               return 0;
+               return -EAGAIN;
        } else if (state != H_VASI_SUSPENDING) {
                printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned state %ld\n",
                       state);
-               *vasi_return = -1;
-               return 0;
+               return -EIO;
        }
 
        if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY))
@@ -972,7 +970,7 @@ out:
        return atomic_read(&data.error);
 }
 #else /* CONFIG_PPC_PSERIES */
-int rtas_ibm_suspend_me(u64 handle, int *vasi_return)
+int rtas_ibm_suspend_me(u64 handle)
 {
        return -ENOSYS;
 }
@@ -1022,7 +1020,6 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
        unsigned long flags;
        char *buff_copy, *errbuf = NULL;
        int nargs, nret, token;
-       int rc;
 
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
@@ -1054,15 +1051,18 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
        if (token == ibm_suspend_me_token) {
 
                /*
-                * rtas_ibm_suspend_me assumes args are in cpu endian, or at least the
-                * hcall within it requires it.
+                * rtas_ibm_suspend_me assumes the streamid handle is in cpu
+                * endian, or at least the hcall within it requires it.
                 */
-               int vasi_rc = 0;
+               int rc = 0;
                u64 handle = ((u64)be32_to_cpu(args.args[0]) << 32)
                              | be32_to_cpu(args.args[1]);
-               rc = rtas_ibm_suspend_me(handle, &vasi_rc);
-               args.rets[0] = cpu_to_be32(vasi_rc);
-               if (rc)
+               rc = rtas_ibm_suspend_me(handle);
+               if (rc == -EAGAIN)
+                       args.rets[0] = cpu_to_be32(RTAS_NOT_SUSPENDABLE);
+               else if (rc == -EIO)
+                       args.rets[0] = cpu_to_be32(-1);
+               else if (rc)
                        return rc;
                goto copy_return;
        }
index 03a428e87b14bb088f91d38d96d69db9327c5663..38db1b9f2ac3020a96a02274ddc957c340f2dd11 100644 (file)
@@ -318,22 +318,19 @@ static ssize_t migrate_store(struct class *class, struct class_attribute *attr,
 {
        u64 streamid;
        int rc;
-       int vasi_rc = 0;
 
        rc = kstrtou64(buf, 0, &streamid);
        if (rc)
                return rc;
 
        do {
-               rc = rtas_ibm_suspend_me(streamid, &vasi_rc);
-               if (!rc && vasi_rc == RTAS_NOT_SUSPENDABLE)
+               rc = rtas_ibm_suspend_me(streamid);
+               if (rc == -EAGAIN)
                        ssleep(1);
-       } while (!rc && vasi_rc == RTAS_NOT_SUSPENDABLE);
+       } while (rc == -EAGAIN);
 
        if (rc)
                return rc;
-       if (vasi_rc)
-               return vasi_rc;
 
        post_mobility_fixup();
        return count;