Skip to content

Commit

Permalink
powerpc/pseries/vas: Add VAS migration handler
Browse files Browse the repository at this point in the history
Since the VAS windows belong to the VAS hardware resource, the
hypervisor expects the partition to close them on source partition
and reopen them after the partition migrated on the destination
machine.

This handler is called before pseries_suspend() to close these
windows and again invoked after migration. All active windows
for both default and QoS types will be closed and mark them
inactive and reopened after migration with this handler.
During the migration, the user space receives paste instruction
failure if it issues copy/paste on these inactive windows.

The current migration implementation does not freeze the user
space and applications can continue to open VAS windows while
migration is in progress. So when the migration_in_progress flag
is set, VAS open window API returns -EBUSY.

Signed-off-by: Haren Myneni <haren@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/05e45ff4f8babd2490ccb7ae923884f4aa21a7e5.camel@linux.ibm.com
  • Loading branch information
hmyneni authored and mpe committed Mar 7, 2022
1 parent 716d7a2 commit 37e6764
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 1 deletion.
5 changes: 5 additions & 0 deletions arch/powerpc/platforms/pseries/mobility.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <asm/machdep.h>
#include <asm/rtas.h>
#include "pseries.h"
#include "vas.h" /* vas_migration_handler() */
#include "../../kernel/cacheinfo.h"

static struct kobject *mobility_kobj;
Expand Down Expand Up @@ -669,12 +670,16 @@ static int pseries_migrate_partition(u64 handle)
if (ret)
return ret;

vas_migration_handler(VAS_SUSPEND);

ret = pseries_suspend(handle);
if (ret == 0)
post_mobility_fixup();
else
pseries_cancel_migration(handle, ret);

vas_migration_handler(VAS_RESUME);

return ret;
}

Expand Down
98 changes: 97 additions & 1 deletion arch/powerpc/platforms/pseries/vas.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ static struct hv_vas_cop_feat_caps hv_cop_caps;

static struct vas_caps vascaps[VAS_MAX_FEAT_TYPE];
static DEFINE_MUTEX(vas_pseries_mutex);
static bool migration_in_progress;

static long hcall_return_busy_check(long rc)
{
Expand Down Expand Up @@ -356,7 +357,10 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags,
* same fault IRQ is not freed by the OS before.
*/
mutex_lock(&vas_pseries_mutex);
rc = allocate_setup_window(txwin, (u64 *)&domain[0],
if (migration_in_progress)
rc = -EBUSY;
else
rc = allocate_setup_window(txwin, (u64 *)&domain[0],
cop_feat_caps->win_type);
mutex_unlock(&vas_pseries_mutex);
if (rc)
Expand Down Expand Up @@ -869,6 +873,98 @@ static struct notifier_block pseries_vas_nb = {
.notifier_call = pseries_vas_notifier,
};

/*
* For LPM, all windows have to be closed on the source partition
* before migration and reopen them on the destination partition
* after migration. So closing windows during suspend and
* reopen them during resume.
*/
int vas_migration_handler(int action)
{
struct vas_cop_feat_caps *caps;
int old_nr_creds, new_nr_creds = 0;
struct vas_caps *vcaps;
int i, rc = 0;

/*
* NX-GZIP is not enabled. Nothing to do for migration.
*/
if (!copypaste_feat)
return rc;

mutex_lock(&vas_pseries_mutex);

if (action == VAS_SUSPEND)
migration_in_progress = true;
else
migration_in_progress = false;

for (i = 0; i < VAS_MAX_FEAT_TYPE; i++) {
vcaps = &vascaps[i];
caps = &vcaps->caps;
old_nr_creds = atomic_read(&caps->nr_total_credits);

rc = h_query_vas_capabilities(H_QUERY_VAS_CAPABILITIES,
vcaps->feat,
(u64)virt_to_phys(&hv_cop_caps));
if (!rc) {
new_nr_creds = be16_to_cpu(hv_cop_caps.target_lpar_creds);
/*
* Should not happen. But incase print messages, close
* all windows in the list during suspend and reopen
* windows based on new lpar_creds on the destination
* system.
*/
if (old_nr_creds != new_nr_creds) {
pr_err("Target credits mismatch with the hypervisor\n");
pr_err("state(%d): lpar creds: %d HV lpar creds: %d\n",
action, old_nr_creds, new_nr_creds);
pr_err("Used creds: %d, Active creds: %d\n",
atomic_read(&caps->nr_used_credits),
vcaps->nr_open_windows - vcaps->nr_close_wins);
}
} else {
pr_err("state(%d): Get VAS capabilities failed with %d\n",
action, rc);
/*
* We can not stop migration with the current lpm
* implementation. So continue closing all windows in
* the list (during suspend) and return without
* opening windows (during resume) if VAS capabilities
* HCALL failed.
*/
if (action == VAS_RESUME)
goto out;
}

switch (action) {
case VAS_SUSPEND:
rc = reconfig_close_windows(vcaps, vcaps->nr_open_windows,
true);
break;
case VAS_RESUME:
atomic_set(&caps->nr_total_credits, new_nr_creds);
rc = reconfig_open_windows(vcaps, new_nr_creds, true);
break;
default:
/* should not happen */
pr_err("Invalid migration action %d\n", action);
rc = -EINVAL;
goto out;
}

/*
* Ignore errors during suspend and return for resume.
*/
if (rc && (action == VAS_RESUME))
goto out;
}

out:
mutex_unlock(&vas_pseries_mutex);
return rc;
}

static int __init pseries_vas_init(void)
{
struct hv_vas_all_caps *hv_caps;
Expand Down
14 changes: 14 additions & 0 deletions arch/powerpc/platforms/pseries/vas.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@
#define VAS_GZIP_QOS_CAPABILITIES 0x56516F73477A6970
#define VAS_GZIP_DEFAULT_CAPABILITIES 0x56446566477A6970

enum vas_migrate_action {
VAS_SUSPEND,
VAS_RESUME,
};

/*
* Co-processor feature - GZIP QoS windows or GZIP default windows
*/
Expand Down Expand Up @@ -132,4 +137,13 @@ struct pseries_vas_window {
int sysfs_add_vas_caps(struct vas_cop_feat_caps *caps);
int vas_reconfig_capabilties(u8 type);
int __init sysfs_pseries_vas_init(struct vas_all_caps *vas_caps);

#ifdef CONFIG_PPC_VAS
int vas_migration_handler(int action);
#else
static inline int vas_migration_handler(int action)
{
return 0;
}
#endif
#endif /* _VAS_H */

0 comments on commit 37e6764

Please sign in to comment.