@@ -457,11 +457,12 @@ static int vas_deallocate_window(struct vas_window *vwin)
457
457
mutex_lock (& vas_pseries_mutex );
458
458
/*
459
459
* 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
462
462
* struct.
463
463
*/
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 )) {
465
466
rc = deallocate_free_window (win );
466
467
if (rc ) {
467
468
mutex_unlock (& vas_pseries_mutex );
@@ -578,12 +579,14 @@ static int __init get_vas_capabilities(u8 feat, enum vas_cop_feat_type type,
578
579
* by setting the remapping to new paste address if the window is
579
580
* active.
580
581
*/
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 )
582
584
{
583
585
long domain [PLPAR_HCALL9_BUFSIZE ] = {VAS_DEFAULT_DOMAIN_ID };
584
586
struct vas_cop_feat_caps * caps = & vcaps -> caps ;
585
587
struct pseries_vas_window * win = NULL , * tmp ;
586
588
int rc , mv_ents = 0 ;
589
+ int flag ;
587
590
588
591
/*
589
592
* Nothing to do if there are no closed windows.
@@ -602,8 +605,10 @@ static int reconfig_open_windows(struct vas_caps *vcaps, int creds)
602
605
* (dedicated). If 1 core is added, this LPAR can have 20 more
603
606
* credits. It means the kernel can reopen 20 windows. So move
604
607
* 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.
605
610
*/
606
- if (vcaps -> nr_close_wins > creds )
611
+ if (( vcaps -> nr_close_wins > creds ) && ! migrate )
607
612
mv_ents = vcaps -> nr_close_wins - creds ;
608
613
609
614
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)
613
618
mv_ents -- ;
614
619
}
615
620
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
+
616
630
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
+
617
645
/*
618
646
* Nothing to do on this window if it is not closed
619
- * with VAS_WIN_NO_CRED_CLOSE
647
+ * with this flag
620
648
*/
621
- if (!(win -> vas_win .status & VAS_WIN_NO_CRED_CLOSE ))
649
+ if (!(win -> vas_win .status & flag ))
622
650
continue ;
623
651
624
652
rc = allocate_setup_window (win , (u64 * )& domain [0 ],
@@ -634,7 +662,7 @@ static int reconfig_open_windows(struct vas_caps *vcaps, int creds)
634
662
/*
635
663
* Set window status to active
636
664
*/
637
- win -> vas_win .status &= ~VAS_WIN_NO_CRED_CLOSE ;
665
+ win -> vas_win .status &= ~flag ;
638
666
mutex_unlock (& win -> vas_win .task_ref .mmap_mutex );
639
667
win -> win_type = caps -> win_type ;
640
668
if (!-- vcaps -> nr_close_wins )
@@ -661,20 +689,32 @@ static int reconfig_open_windows(struct vas_caps *vcaps, int creds)
661
689
* the user space to fall back to SW compression and manage with the
662
690
* existing windows.
663
691
*/
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 )
665
694
{
666
695
struct pseries_vas_window * win , * tmp ;
667
696
struct vas_user_win_ref * task_ref ;
668
697
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 ;
670
704
671
705
list_for_each_entry_safe (win , tmp , & vcap -> list , win_list ) {
672
706
/*
673
707
* 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.
675
712
*/
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 ;
677
716
continue ;
717
+ }
678
718
679
719
task_ref = & win -> vas_win .task_ref ;
680
720
mutex_lock (& task_ref -> mmap_mutex );
@@ -683,7 +723,7 @@ static int reconfig_close_windows(struct vas_caps *vcap, int excess_creds)
683
723
* Number of available credits are reduced, So select
684
724
* and close windows.
685
725
*/
686
- win -> vas_win .status |= VAS_WIN_NO_CRED_CLOSE ;
726
+ win -> vas_win .status |= flag ;
687
727
688
728
mmap_write_lock (task_ref -> mm );
689
729
/*
@@ -706,12 +746,24 @@ static int reconfig_close_windows(struct vas_caps *vcap, int excess_creds)
706
746
* later when the process issued with close(FD).
707
747
*/
708
748
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 )
710
755
return rc ;
711
756
712
757
vcap -> nr_close_wins ++ ;
713
758
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 )
715
767
break ;
716
768
}
717
769
@@ -761,7 +813,8 @@ int vas_reconfig_capabilties(u8 type)
761
813
* target, reopen windows if they are closed due to
762
814
* the previous DLPAR (core removal).
763
815
*/
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);
765
818
} else {
766
819
/*
767
820
* # active windows is more than new LPAR available
@@ -771,7 +824,8 @@ int vas_reconfig_capabilties(u8 type)
771
824
nr_active_wins = vcaps -> nr_open_windows - vcaps -> nr_close_wins ;
772
825
if (nr_active_wins > new_nr_creds )
773
826
rc = reconfig_close_windows (vcaps ,
774
- nr_active_wins - new_nr_creds );
827
+ nr_active_wins - new_nr_creds ,
828
+ false);
775
829
}
776
830
777
831
out :
0 commit comments