@@ -385,11 +385,15 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags,
385
385
* same fault IRQ is not freed by the OS before.
386
386
*/
387
387
mutex_lock (& vas_pseries_mutex );
388
- if (migration_in_progress )
388
+ if (migration_in_progress ) {
389
389
rc = - EBUSY ;
390
- else
390
+ } else {
391
391
rc = allocate_setup_window (txwin , (u64 * )& domain [0 ],
392
392
cop_feat_caps -> win_type );
393
+ if (!rc )
394
+ caps -> nr_open_wins_progress ++ ;
395
+ }
396
+
393
397
mutex_unlock (& vas_pseries_mutex );
394
398
if (rc )
395
399
goto out ;
@@ -404,18 +408,29 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags,
404
408
goto out_free ;
405
409
406
410
txwin -> win_type = cop_feat_caps -> win_type ;
407
- mutex_lock ( & vas_pseries_mutex );
411
+
408
412
/*
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
+ *
409
422
* Possible to lose the acquired credit with DLPAR core
410
423
* removal after the window is opened. So if there are any
411
424
* closed windows (means with lost credits), do not give new
412
425
* window to user space. New windows will be opened only
413
426
* after the existing windows are reopened when credits are
414
427
* available.
415
428
*/
416
- if (!caps -> nr_close_wins ) {
429
+ mutex_lock (& vas_pseries_mutex );
430
+ if (!caps -> nr_close_wins && !migration_in_progress ) {
417
431
list_add (& txwin -> win_list , & caps -> list );
418
432
caps -> nr_open_windows ++ ;
433
+ caps -> nr_open_wins_progress -- ;
419
434
mutex_unlock (& vas_pseries_mutex );
420
435
vas_user_win_add_mm_context (& txwin -> vas_win .task_ref );
421
436
return & txwin -> vas_win ;
@@ -433,6 +448,12 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags,
433
448
*/
434
449
free_irq_setup (txwin );
435
450
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 );
436
457
out :
437
458
atomic_dec (& cop_feat_caps -> nr_used_credits );
438
459
kfree (txwin );
@@ -937,14 +958,14 @@ int vas_migration_handler(int action)
937
958
struct vas_caps * vcaps ;
938
959
int i , rc = 0 ;
939
960
961
+ pr_info ("VAS migration event %d\n" , action );
962
+
940
963
/*
941
964
* NX-GZIP is not enabled. Nothing to do for migration.
942
965
*/
943
966
if (!copypaste_feat )
944
967
return rc ;
945
968
946
- mutex_lock (& vas_pseries_mutex );
947
-
948
969
if (action == VAS_SUSPEND )
949
970
migration_in_progress = true;
950
971
else
@@ -990,12 +1011,27 @@ int vas_migration_handler(int action)
990
1011
991
1012
switch (action ) {
992
1013
case VAS_SUSPEND :
1014
+ mutex_lock (& vas_pseries_mutex );
993
1015
rc = reconfig_close_windows (vcaps , vcaps -> nr_open_windows ,
994
1016
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 );
995
1029
break ;
996
1030
case VAS_RESUME :
1031
+ mutex_lock (& vas_pseries_mutex );
997
1032
atomic_set (& caps -> nr_total_credits , new_nr_creds );
998
1033
rc = reconfig_open_windows (vcaps , new_nr_creds , true);
1034
+ mutex_unlock (& vas_pseries_mutex );
999
1035
break ;
1000
1036
default :
1001
1037
/* should not happen */
@@ -1011,8 +1047,9 @@ int vas_migration_handler(int action)
1011
1047
goto out ;
1012
1048
}
1013
1049
1050
+ pr_info ("VAS migration event (%d) successful\n" , action );
1051
+
1014
1052
out :
1015
- mutex_unlock (& vas_pseries_mutex );
1016
1053
return rc ;
1017
1054
}
1018
1055
0 commit comments