@@ -385,11 +385,15 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags,
385385 * same fault IRQ is not freed by the OS before.
386386 */
387387 mutex_lock (& vas_pseries_mutex );
388- if (migration_in_progress )
388+ if (migration_in_progress ) {
389389 rc = - EBUSY ;
390- else
390+ } else {
391391 rc = allocate_setup_window (txwin , (u64 * )& domain [0 ],
392392 cop_feat_caps -> win_type );
393+ if (!rc )
394+ caps -> nr_open_wins_progress ++ ;
395+ }
396+
393397 mutex_unlock (& vas_pseries_mutex );
394398 if (rc )
395399 goto out ;
@@ -404,18 +408,29 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags,
404408 goto out_free ;
405409
406410 txwin -> win_type = cop_feat_caps -> win_type ;
407- mutex_lock ( & vas_pseries_mutex );
411+
408412 /*
413+ * The migration SUSPEND thread sets migration_in_progress and
414+ * closes all open windows from the list. But the window is
415+ * added to the list after open and modify HCALLs. So possible
416+ * that migration_in_progress is set before modify HCALL which
417+ * may cause some windows are still open when the hypervisor
418+ * initiates the migration.
419+ * So checks the migration_in_progress flag again and close all
420+ * open windows.
421+ *
409422 * Possible to lose the acquired credit with DLPAR core
410423 * removal after the window is opened. So if there are any
411424 * closed windows (means with lost credits), do not give new
412425 * window to user space. New windows will be opened only
413426 * after the existing windows are reopened when credits are
414427 * available.
415428 */
416- if (!caps -> nr_close_wins ) {
429+ mutex_lock (& vas_pseries_mutex );
430+ if (!caps -> nr_close_wins && !migration_in_progress ) {
417431 list_add (& txwin -> win_list , & caps -> list );
418432 caps -> nr_open_windows ++ ;
433+ caps -> nr_open_wins_progress -- ;
419434 mutex_unlock (& vas_pseries_mutex );
420435 vas_user_win_add_mm_context (& txwin -> vas_win .task_ref );
421436 return & txwin -> vas_win ;
@@ -433,6 +448,12 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags,
433448 */
434449 free_irq_setup (txwin );
435450 h_deallocate_vas_window (txwin -> vas_win .winid );
451+ /*
452+ * Hold mutex and reduce nr_open_wins_progress counter.
453+ */
454+ mutex_lock (& vas_pseries_mutex );
455+ caps -> nr_open_wins_progress -- ;
456+ mutex_unlock (& vas_pseries_mutex );
436457out :
437458 atomic_dec (& cop_feat_caps -> nr_used_credits );
438459 kfree (txwin );
@@ -937,14 +958,14 @@ int vas_migration_handler(int action)
937958 struct vas_caps * vcaps ;
938959 int i , rc = 0 ;
939960
961+ pr_info ("VAS migration event %d\n" , action );
962+
940963 /*
941964 * NX-GZIP is not enabled. Nothing to do for migration.
942965 */
943966 if (!copypaste_feat )
944967 return rc ;
945968
946- mutex_lock (& vas_pseries_mutex );
947-
948969 if (action == VAS_SUSPEND )
949970 migration_in_progress = true;
950971 else
@@ -990,12 +1011,27 @@ int vas_migration_handler(int action)
9901011
9911012 switch (action ) {
9921013 case VAS_SUSPEND :
1014+ mutex_lock (& vas_pseries_mutex );
9931015 rc = reconfig_close_windows (vcaps , vcaps -> nr_open_windows ,
9941016 true);
1017+ /*
1018+ * Windows are included in the list after successful
1019+ * open. So wait for closing these in-progress open
1020+ * windows in vas_allocate_window() which will be
1021+ * done if the migration_in_progress is set.
1022+ */
1023+ while (vcaps -> nr_open_wins_progress ) {
1024+ mutex_unlock (& vas_pseries_mutex );
1025+ msleep (10 );
1026+ mutex_lock (& vas_pseries_mutex );
1027+ }
1028+ mutex_unlock (& vas_pseries_mutex );
9951029 break ;
9961030 case VAS_RESUME :
1031+ mutex_lock (& vas_pseries_mutex );
9971032 atomic_set (& caps -> nr_total_credits , new_nr_creds );
9981033 rc = reconfig_open_windows (vcaps , new_nr_creds , true);
1034+ mutex_unlock (& vas_pseries_mutex );
9991035 break ;
10001036 default :
10011037 /* should not happen */
@@ -1011,8 +1047,9 @@ int vas_migration_handler(int action)
10111047 goto out ;
10121048 }
10131049
1050+ pr_info ("VAS migration event (%d) successful\n" , action );
1051+
10141052out :
1015- mutex_unlock (& vas_pseries_mutex );
10161053 return rc ;
10171054}
10181055
0 commit comments