Skip to content

Commit 716d7a2

Browse files
hmynenimpe
authored andcommitted
powerpc/pseries/vas: Modify reconfig open/close functions for migration
VAS is a hardware engine stays on the chip. So when the partition migrates, all VAS windows on the source system have to be closed and reopen them on the destination after migration. The kernel has to consider both DLPAR CPU and migration events to take action on VAS windows. So using VAS_WIN_NO_CRED_CLOSE and VAS_WIN_MIGRATE_CLOSE status bits and windows will be reopened after migration only after both status bits are cleared. This patch make changes to the current reconfig_open/close_windows functions to support migration: - Set VAS_WIN_MIGRATE_CLOSE to the window status when closes and reopen windows with the same status during resume. - Continue to close all windows even if deallocate HCALL failed (should not happen) since no way to stop migration with the current LPM implementation. - If the DLPAR CPU event happens while migration is in progress, set VAS_WIN_NO_CRED_CLOSE to the window status. Close window happens with the first event (migration or DLPAR) and Reopen window happens only with the last event (migration or DLPAR). Signed-off-by: Haren Myneni <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 278fe1c commit 716d7a2

File tree

2 files changed

+73
-17
lines changed
  • arch/powerpc

2 files changed

+73
-17
lines changed

arch/powerpc/include/asm/vas.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
/* vas mmap() */
3737
/* Window is closed in the hypervisor due to lost credit */
3838
#define VAS_WIN_NO_CRED_CLOSE 0x00000001
39+
/* Window is closed due to migration */
40+
#define VAS_WIN_MIGRATE_CLOSE 0x00000002
3941

4042
/*
4143
* Get/Set bit fields

arch/powerpc/platforms/pseries/vas.c

Lines changed: 71 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -457,11 +457,12 @@ static int vas_deallocate_window(struct vas_window *vwin)
457457
mutex_lock(&vas_pseries_mutex);
458458
/*
459459
* VAS window is already closed in the hypervisor when
460-
* lost the credit. So just remove the entry from
461-
* the list, remove task references and free vas_window
460+
* lost the credit or with migration. So just remove the entry
461+
* from the list, remove task references and free vas_window
462462
* struct.
463463
*/
464-
if (win->vas_win.status & VAS_WIN_NO_CRED_CLOSE) {
464+
if (!(win->vas_win.status & VAS_WIN_NO_CRED_CLOSE) &&
465+
!(win->vas_win.status & VAS_WIN_MIGRATE_CLOSE)) {
465466
rc = deallocate_free_window(win);
466467
if (rc) {
467468
mutex_unlock(&vas_pseries_mutex);
@@ -578,12 +579,14 @@ static int __init get_vas_capabilities(u8 feat, enum vas_cop_feat_type type,
578579
* by setting the remapping to new paste address if the window is
579580
* active.
580581
*/
581-
static int reconfig_open_windows(struct vas_caps *vcaps, int creds)
582+
static int reconfig_open_windows(struct vas_caps *vcaps, int creds,
583+
bool migrate)
582584
{
583585
long domain[PLPAR_HCALL9_BUFSIZE] = {VAS_DEFAULT_DOMAIN_ID};
584586
struct vas_cop_feat_caps *caps = &vcaps->caps;
585587
struct pseries_vas_window *win = NULL, *tmp;
586588
int rc, mv_ents = 0;
589+
int flag;
587590

588591
/*
589592
* Nothing to do if there are no closed windows.
@@ -602,8 +605,10 @@ static int reconfig_open_windows(struct vas_caps *vcaps, int creds)
602605
* (dedicated). If 1 core is added, this LPAR can have 20 more
603606
* credits. It means the kernel can reopen 20 windows. So move
604607
* 20 entries in the VAS windows lost and reopen next 20 windows.
608+
* For partition migration, reopen all windows that are closed
609+
* during resume.
605610
*/
606-
if (vcaps->nr_close_wins > creds)
611+
if ((vcaps->nr_close_wins > creds) && !migrate)
607612
mv_ents = vcaps->nr_close_wins - creds;
608613

609614
list_for_each_entry_safe(win, tmp, &vcaps->list, win_list) {
@@ -613,12 +618,35 @@ static int reconfig_open_windows(struct vas_caps *vcaps, int creds)
613618
mv_ents--;
614619
}
615620

621+
/*
622+
* Open windows if they are closed only with migration or
623+
* DLPAR (lost credit) before.
624+
*/
625+
if (migrate)
626+
flag = VAS_WIN_MIGRATE_CLOSE;
627+
else
628+
flag = VAS_WIN_NO_CRED_CLOSE;
629+
616630
list_for_each_entry_safe_from(win, tmp, &vcaps->list, win_list) {
631+
/*
632+
* This window is closed with DLPAR and migration events.
633+
* So reopen the window with the last event.
634+
* The user space is not suspended with the current
635+
* migration notifier. So the user space can issue DLPAR
636+
* CPU hotplug while migration in progress. In this case
637+
* this window will be opened with the last event.
638+
*/
639+
if ((win->vas_win.status & VAS_WIN_NO_CRED_CLOSE) &&
640+
(win->vas_win.status & VAS_WIN_MIGRATE_CLOSE)) {
641+
win->vas_win.status &= ~flag;
642+
continue;
643+
}
644+
617645
/*
618646
* Nothing to do on this window if it is not closed
619-
* with VAS_WIN_NO_CRED_CLOSE
647+
* with this flag
620648
*/
621-
if (!(win->vas_win.status & VAS_WIN_NO_CRED_CLOSE))
649+
if (!(win->vas_win.status & flag))
622650
continue;
623651

624652
rc = allocate_setup_window(win, (u64 *)&domain[0],
@@ -634,7 +662,7 @@ static int reconfig_open_windows(struct vas_caps *vcaps, int creds)
634662
/*
635663
* Set window status to active
636664
*/
637-
win->vas_win.status &= ~VAS_WIN_NO_CRED_CLOSE;
665+
win->vas_win.status &= ~flag;
638666
mutex_unlock(&win->vas_win.task_ref.mmap_mutex);
639667
win->win_type = caps->win_type;
640668
if (!--vcaps->nr_close_wins)
@@ -661,20 +689,32 @@ static int reconfig_open_windows(struct vas_caps *vcaps, int creds)
661689
* the user space to fall back to SW compression and manage with the
662690
* existing windows.
663691
*/
664-
static int reconfig_close_windows(struct vas_caps *vcap, int excess_creds)
692+
static int reconfig_close_windows(struct vas_caps *vcap, int excess_creds,
693+
bool migrate)
665694
{
666695
struct pseries_vas_window *win, *tmp;
667696
struct vas_user_win_ref *task_ref;
668697
struct vm_area_struct *vma;
669-
int rc = 0;
698+
int rc = 0, flag;
699+
700+
if (migrate)
701+
flag = VAS_WIN_MIGRATE_CLOSE;
702+
else
703+
flag = VAS_WIN_NO_CRED_CLOSE;
670704

671705
list_for_each_entry_safe(win, tmp, &vcap->list, win_list) {
672706
/*
673707
* This window is already closed due to lost credit
674-
* before. Go for next window.
708+
* or for migration before. Go for next window.
709+
* For migration, nothing to do since this window
710+
* closed for DLPAR and will be reopened even on
711+
* the destination system with other DLPAR operation.
675712
*/
676-
if (win->vas_win.status & VAS_WIN_NO_CRED_CLOSE)
713+
if ((win->vas_win.status & VAS_WIN_MIGRATE_CLOSE) ||
714+
(win->vas_win.status & VAS_WIN_NO_CRED_CLOSE)) {
715+
win->vas_win.status |= flag;
677716
continue;
717+
}
678718

679719
task_ref = &win->vas_win.task_ref;
680720
mutex_lock(&task_ref->mmap_mutex);
@@ -683,7 +723,7 @@ static int reconfig_close_windows(struct vas_caps *vcap, int excess_creds)
683723
* Number of available credits are reduced, So select
684724
* and close windows.
685725
*/
686-
win->vas_win.status |= VAS_WIN_NO_CRED_CLOSE;
726+
win->vas_win.status |= flag;
687727

688728
mmap_write_lock(task_ref->mm);
689729
/*
@@ -706,12 +746,24 @@ static int reconfig_close_windows(struct vas_caps *vcap, int excess_creds)
706746
* later when the process issued with close(FD).
707747
*/
708748
rc = deallocate_free_window(win);
709-
if (rc)
749+
/*
750+
* This failure is from the hypervisor.
751+
* No way to stop migration for these failures.
752+
* So ignore error and continue closing other windows.
753+
*/
754+
if (rc && !migrate)
710755
return rc;
711756

712757
vcap->nr_close_wins++;
713758

714-
if (!--excess_creds)
759+
/*
760+
* For migration, do not depend on lpar_creds in case if
761+
* mismatch with the hypervisor value (should not happen).
762+
* So close all active windows in the list and will be
763+
* reopened windows based on the new lpar_creds on the
764+
* destination system during resume.
765+
*/
766+
if (!migrate && !--excess_creds)
715767
break;
716768
}
717769

@@ -761,7 +813,8 @@ int vas_reconfig_capabilties(u8 type)
761813
* target, reopen windows if they are closed due to
762814
* the previous DLPAR (core removal).
763815
*/
764-
rc = reconfig_open_windows(vcaps, new_nr_creds - old_nr_creds);
816+
rc = reconfig_open_windows(vcaps, new_nr_creds - old_nr_creds,
817+
false);
765818
} else {
766819
/*
767820
* # active windows is more than new LPAR available
@@ -771,7 +824,8 @@ int vas_reconfig_capabilties(u8 type)
771824
nr_active_wins = vcaps->nr_open_windows - vcaps->nr_close_wins;
772825
if (nr_active_wins > new_nr_creds)
773826
rc = reconfig_close_windows(vcaps,
774-
nr_active_wins - new_nr_creds);
827+
nr_active_wins - new_nr_creds,
828+
false);
775829
}
776830

777831
out:

0 commit comments

Comments
 (0)