@@ -2362,7 +2362,6 @@ static int migrate_vma_collect_pmd(pmd_t *pmdp,
2362
2362
* can't be dropped from it).
2363
2363
*/
2364
2364
get_page (page );
2365
- migrate -> cpages ++ ;
2366
2365
2367
2366
/*
2368
2367
* Optimize for the common case where page is only mapped once
@@ -2372,7 +2371,7 @@ static int migrate_vma_collect_pmd(pmd_t *pmdp,
2372
2371
if (trylock_page (page )) {
2373
2372
pte_t swp_pte ;
2374
2373
2375
- mpfn |= MIGRATE_PFN_LOCKED ;
2374
+ migrate -> cpages ++ ;
2376
2375
ptep_get_and_clear (mm , addr , ptep );
2377
2376
2378
2377
/* Setup special migration page table entry */
@@ -2406,6 +2405,9 @@ static int migrate_vma_collect_pmd(pmd_t *pmdp,
2406
2405
2407
2406
if (pte_present (pte ))
2408
2407
unmapped ++ ;
2408
+ } else {
2409
+ put_page (page );
2410
+ mpfn = 0 ;
2409
2411
}
2410
2412
2411
2413
next :
@@ -2510,15 +2512,17 @@ static bool migrate_vma_check_page(struct page *page)
2510
2512
}
2511
2513
2512
2514
/*
2513
- * migrate_vma_prepare () - lock pages and isolate them from the lru
2515
+ * migrate_vma_unmap () - replace page mapping with special migration pte entry
2514
2516
* @migrate: migrate struct containing all migration information
2515
2517
*
2516
- * This locks pages that have been collected by migrate_vma_collect(). Once each
2517
- * page is locked it is isolated from the lru (for non-device pages). Finally,
2518
- * the ref taken by migrate_vma_collect() is dropped, as locked pages cannot be
2519
- * migrated by concurrent kernel threads.
2518
+ * Isolate pages from the LRU and replace mappings (CPU page table pte) with a
2519
+ * special migration pte entry and check if it has been pinned. Pinned pages are
2520
+ * restored because we cannot migrate them.
2521
+ *
2522
+ * This is the last step before we call the device driver callback to allocate
2523
+ * destination memory and copy contents of original page over to new page.
2520
2524
*/
2521
- static void migrate_vma_prepare (struct migrate_vma * migrate )
2525
+ static void migrate_vma_unmap (struct migrate_vma * migrate )
2522
2526
{
2523
2527
const unsigned long npages = migrate -> npages ;
2524
2528
const unsigned long start = migrate -> start ;
@@ -2527,32 +2531,12 @@ static void migrate_vma_prepare(struct migrate_vma *migrate)
2527
2531
2528
2532
lru_add_drain ();
2529
2533
2530
- for (i = 0 ; ( i < npages ) && migrate -> cpages ; i ++ ) {
2534
+ for (i = 0 ; i < npages ; i ++ ) {
2531
2535
struct page * page = migrate_pfn_to_page (migrate -> src [i ]);
2532
- bool remap = true;
2533
2536
2534
2537
if (!page )
2535
2538
continue ;
2536
2539
2537
- if (!(migrate -> src [i ] & MIGRATE_PFN_LOCKED )) {
2538
- /*
2539
- * Because we are migrating several pages there can be
2540
- * a deadlock between 2 concurrent migration where each
2541
- * are waiting on each other page lock.
2542
- *
2543
- * Make migrate_vma() a best effort thing and backoff
2544
- * for any page we can not lock right away.
2545
- */
2546
- if (!trylock_page (page )) {
2547
- migrate -> src [i ] = 0 ;
2548
- migrate -> cpages -- ;
2549
- put_page (page );
2550
- continue ;
2551
- }
2552
- remap = false;
2553
- migrate -> src [i ] |= MIGRATE_PFN_LOCKED ;
2554
- }
2555
-
2556
2540
/* ZONE_DEVICE pages are not on LRU */
2557
2541
if (!is_zone_device_page (page )) {
2558
2542
if (!PageLRU (page ) && allow_drain ) {
@@ -2562,97 +2546,30 @@ static void migrate_vma_prepare(struct migrate_vma *migrate)
2562
2546
}
2563
2547
2564
2548
if (isolate_lru_page (page )) {
2565
- if (remap ) {
2566
- migrate -> src [i ] &= ~MIGRATE_PFN_MIGRATE ;
2567
- migrate -> cpages -- ;
2568
- restore ++ ;
2569
- } else {
2570
- migrate -> src [i ] = 0 ;
2571
- unlock_page (page );
2572
- migrate -> cpages -- ;
2573
- put_page (page );
2574
- }
2549
+ migrate -> src [i ] &= ~MIGRATE_PFN_MIGRATE ;
2550
+ migrate -> cpages -- ;
2551
+ restore ++ ;
2575
2552
continue ;
2576
2553
}
2577
2554
2578
2555
/* Drop the reference we took in collect */
2579
2556
put_page (page );
2580
2557
}
2581
2558
2582
- if (!migrate_vma_check_page (page )) {
2583
- if (remap ) {
2584
- migrate -> src [i ] &= ~MIGRATE_PFN_MIGRATE ;
2585
- migrate -> cpages -- ;
2586
- restore ++ ;
2587
-
2588
- if (!is_zone_device_page (page )) {
2589
- get_page (page );
2590
- putback_lru_page (page );
2591
- }
2592
- } else {
2593
- migrate -> src [i ] = 0 ;
2594
- unlock_page (page );
2595
- migrate -> cpages -- ;
2559
+ if (page_mapped (page ))
2560
+ try_to_migrate (page , 0 );
2596
2561
2597
- if (! is_zone_device_page (page ))
2598
- putback_lru_page ( page );
2599
- else
2600
- put_page (page );
2562
+ if (page_mapped ( page ) || ! migrate_vma_check_page (page )) {
2563
+ if (! is_zone_device_page ( page )) {
2564
+ get_page ( page );
2565
+ putback_lru_page (page );
2601
2566
}
2602
- }
2603
- }
2604
-
2605
- for (i = 0 , addr = start ; i < npages && restore ; i ++ , addr += PAGE_SIZE ) {
2606
- struct page * page = migrate_pfn_to_page (migrate -> src [i ]);
2607
-
2608
- if (!page || (migrate -> src [i ] & MIGRATE_PFN_MIGRATE ))
2609
- continue ;
2610
2567
2611
- remove_migration_pte (page , migrate -> vma , addr , page );
2612
-
2613
- migrate -> src [i ] = 0 ;
2614
- unlock_page (page );
2615
- put_page (page );
2616
- restore -- ;
2617
- }
2618
- }
2619
-
2620
- /*
2621
- * migrate_vma_unmap() - replace page mapping with special migration pte entry
2622
- * @migrate: migrate struct containing all migration information
2623
- *
2624
- * Replace page mapping (CPU page table pte) with a special migration pte entry
2625
- * and check again if it has been pinned. Pinned pages are restored because we
2626
- * cannot migrate them.
2627
- *
2628
- * This is the last step before we call the device driver callback to allocate
2629
- * destination memory and copy contents of original page over to new page.
2630
- */
2631
- static void migrate_vma_unmap (struct migrate_vma * migrate )
2632
- {
2633
- const unsigned long npages = migrate -> npages ;
2634
- const unsigned long start = migrate -> start ;
2635
- unsigned long addr , i , restore = 0 ;
2636
-
2637
- for (i = 0 ; i < npages ; i ++ ) {
2638
- struct page * page = migrate_pfn_to_page (migrate -> src [i ]);
2639
-
2640
- if (!page || !(migrate -> src [i ] & MIGRATE_PFN_MIGRATE ))
2568
+ migrate -> src [i ] &= ~MIGRATE_PFN_MIGRATE ;
2569
+ migrate -> cpages -- ;
2570
+ restore ++ ;
2641
2571
continue ;
2642
-
2643
- if (page_mapped (page )) {
2644
- try_to_migrate (page , 0 );
2645
- if (page_mapped (page ))
2646
- goto restore ;
2647
2572
}
2648
-
2649
- if (migrate_vma_check_page (page ))
2650
- continue ;
2651
-
2652
- restore :
2653
- migrate -> src [i ] &= ~MIGRATE_PFN_MIGRATE ;
2654
- migrate -> cpages -- ;
2655
- restore ++ ;
2656
2573
}
2657
2574
2658
2575
for (addr = start , i = 0 ; i < npages && restore ; addr += PAGE_SIZE , i ++ ) {
@@ -2665,12 +2582,8 @@ static void migrate_vma_unmap(struct migrate_vma *migrate)
2665
2582
2666
2583
migrate -> src [i ] = 0 ;
2667
2584
unlock_page (page );
2585
+ put_page (page );
2668
2586
restore -- ;
2669
-
2670
- if (is_zone_device_page (page ))
2671
- put_page (page );
2672
- else
2673
- putback_lru_page (page );
2674
2587
}
2675
2588
}
2676
2589
@@ -2693,8 +2606,8 @@ static void migrate_vma_unmap(struct migrate_vma *migrate)
2693
2606
* it for all those entries (ie with MIGRATE_PFN_VALID and MIGRATE_PFN_MIGRATE
2694
2607
* flag set). Once these are allocated and copied, the caller must update each
2695
2608
* corresponding entry in the dst array with the pfn value of the destination
2696
- * page and with the MIGRATE_PFN_VALID and MIGRATE_PFN_LOCKED flags set
2697
- * (destination pages must have their struct pages locked, via lock_page() ).
2609
+ * page and with MIGRATE_PFN_VALID. Destination pages must be locked via
2610
+ * lock_page().
2698
2611
*
2699
2612
* Note that the caller does not have to migrate all the pages that are marked
2700
2613
* with MIGRATE_PFN_MIGRATE flag in src array unless this is a migration from
@@ -2763,8 +2676,6 @@ int migrate_vma_setup(struct migrate_vma *args)
2763
2676
2764
2677
migrate_vma_collect (args );
2765
2678
2766
- if (args -> cpages )
2767
- migrate_vma_prepare (args );
2768
2679
if (args -> cpages )
2769
2680
migrate_vma_unmap (args );
2770
2681
0 commit comments