diff options
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r-- | mm/page_alloc.c | 54 |
1 files changed, 29 insertions, 25 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 6cbde310abed..07efbc3a8656 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -1090,10 +1090,10 @@ static void free_pcppages_bulk(struct zone *zone, int count, | |||
1090 | { | 1090 | { |
1091 | int migratetype = 0; | 1091 | int migratetype = 0; |
1092 | int batch_free = 0; | 1092 | int batch_free = 0; |
1093 | unsigned long nr_scanned, flags; | 1093 | unsigned long nr_scanned; |
1094 | bool isolated_pageblocks; | 1094 | bool isolated_pageblocks; |
1095 | 1095 | ||
1096 | spin_lock_irqsave(&zone->lock, flags); | 1096 | spin_lock(&zone->lock); |
1097 | isolated_pageblocks = has_isolate_pageblock(zone); | 1097 | isolated_pageblocks = has_isolate_pageblock(zone); |
1098 | nr_scanned = node_page_state(zone->zone_pgdat, NR_PAGES_SCANNED); | 1098 | nr_scanned = node_page_state(zone->zone_pgdat, NR_PAGES_SCANNED); |
1099 | if (nr_scanned) | 1099 | if (nr_scanned) |
@@ -1142,7 +1142,7 @@ static void free_pcppages_bulk(struct zone *zone, int count, | |||
1142 | trace_mm_page_pcpu_drain(page, 0, mt); | 1142 | trace_mm_page_pcpu_drain(page, 0, mt); |
1143 | } while (--count && --batch_free && !list_empty(list)); | 1143 | } while (--count && --batch_free && !list_empty(list)); |
1144 | } | 1144 | } |
1145 | spin_unlock_irqrestore(&zone->lock, flags); | 1145 | spin_unlock(&zone->lock); |
1146 | } | 1146 | } |
1147 | 1147 | ||
1148 | static void free_one_page(struct zone *zone, | 1148 | static void free_one_page(struct zone *zone, |
@@ -1150,9 +1150,8 @@ static void free_one_page(struct zone *zone, | |||
1150 | unsigned int order, | 1150 | unsigned int order, |
1151 | int migratetype) | 1151 | int migratetype) |
1152 | { | 1152 | { |
1153 | unsigned long nr_scanned, flags; | 1153 | unsigned long nr_scanned; |
1154 | spin_lock_irqsave(&zone->lock, flags); | 1154 | spin_lock(&zone->lock); |
1155 | __count_vm_events(PGFREE, 1 << order); | ||
1156 | nr_scanned = node_page_state(zone->zone_pgdat, NR_PAGES_SCANNED); | 1155 | nr_scanned = node_page_state(zone->zone_pgdat, NR_PAGES_SCANNED); |
1157 | if (nr_scanned) | 1156 | if (nr_scanned) |
1158 | __mod_node_page_state(zone->zone_pgdat, NR_PAGES_SCANNED, -nr_scanned); | 1157 | __mod_node_page_state(zone->zone_pgdat, NR_PAGES_SCANNED, -nr_scanned); |
@@ -1162,7 +1161,7 @@ static void free_one_page(struct zone *zone, | |||
1162 | migratetype = get_pfnblock_migratetype(page, pfn); | 1161 | migratetype = get_pfnblock_migratetype(page, pfn); |
1163 | } | 1162 | } |
1164 | __free_one_page(page, pfn, zone, order, migratetype); | 1163 | __free_one_page(page, pfn, zone, order, migratetype); |
1165 | spin_unlock_irqrestore(&zone->lock, flags); | 1164 | spin_unlock(&zone->lock); |
1166 | } | 1165 | } |
1167 | 1166 | ||
1168 | static void __meminit __init_single_page(struct page *page, unsigned long pfn, | 1167 | static void __meminit __init_single_page(struct page *page, unsigned long pfn, |
@@ -1240,6 +1239,7 @@ void __meminit reserve_bootmem_region(phys_addr_t start, phys_addr_t end) | |||
1240 | 1239 | ||
1241 | static void __free_pages_ok(struct page *page, unsigned int order) | 1240 | static void __free_pages_ok(struct page *page, unsigned int order) |
1242 | { | 1241 | { |
1242 | unsigned long flags; | ||
1243 | int migratetype; | 1243 | int migratetype; |
1244 | unsigned long pfn = page_to_pfn(page); | 1244 | unsigned long pfn = page_to_pfn(page); |
1245 | 1245 | ||
@@ -1247,7 +1247,10 @@ static void __free_pages_ok(struct page *page, unsigned int order) | |||
1247 | return; | 1247 | return; |
1248 | 1248 | ||
1249 | migratetype = get_pfnblock_migratetype(page, pfn); | 1249 | migratetype = get_pfnblock_migratetype(page, pfn); |
1250 | local_irq_save(flags); | ||
1251 | __count_vm_events(PGFREE, 1 << order); | ||
1250 | free_one_page(page_zone(page), page, pfn, order, migratetype); | 1252 | free_one_page(page_zone(page), page, pfn, order, migratetype); |
1253 | local_irq_restore(flags); | ||
1251 | } | 1254 | } |
1252 | 1255 | ||
1253 | static void __init __free_pages_boot_core(struct page *page, unsigned int order) | 1256 | static void __init __free_pages_boot_core(struct page *page, unsigned int order) |
@@ -2219,9 +2222,8 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order, | |||
2219 | int migratetype, bool cold) | 2222 | int migratetype, bool cold) |
2220 | { | 2223 | { |
2221 | int i, alloced = 0; | 2224 | int i, alloced = 0; |
2222 | unsigned long flags; | ||
2223 | 2225 | ||
2224 | spin_lock_irqsave(&zone->lock, flags); | 2226 | spin_lock(&zone->lock); |
2225 | for (i = 0; i < count; ++i) { | 2227 | for (i = 0; i < count; ++i) { |
2226 | struct page *page = __rmqueue(zone, order, migratetype); | 2228 | struct page *page = __rmqueue(zone, order, migratetype); |
2227 | if (unlikely(page == NULL)) | 2229 | if (unlikely(page == NULL)) |
@@ -2257,7 +2259,7 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order, | |||
2257 | * pages added to the pcp list. | 2259 | * pages added to the pcp list. |
2258 | */ | 2260 | */ |
2259 | __mod_zone_page_state(zone, NR_FREE_PAGES, -(i << order)); | 2261 | __mod_zone_page_state(zone, NR_FREE_PAGES, -(i << order)); |
2260 | spin_unlock_irqrestore(&zone->lock, flags); | 2262 | spin_unlock(&zone->lock); |
2261 | return alloced; | 2263 | return alloced; |
2262 | } | 2264 | } |
2263 | 2265 | ||
@@ -2373,6 +2375,13 @@ void drain_all_pages(struct zone *zone) | |||
2373 | */ | 2375 | */ |
2374 | static cpumask_t cpus_with_pcps; | 2376 | static cpumask_t cpus_with_pcps; |
2375 | 2377 | ||
2378 | /* | ||
2379 | * Make sure nobody triggers this path before mm_percpu_wq is fully | ||
2380 | * initialized. | ||
2381 | */ | ||
2382 | if (WARN_ON_ONCE(!mm_percpu_wq)) | ||
2383 | return; | ||
2384 | |||
2376 | /* Workqueues cannot recurse */ | 2385 | /* Workqueues cannot recurse */ |
2377 | if (current->flags & PF_WQ_WORKER) | 2386 | if (current->flags & PF_WQ_WORKER) |
2378 | return; | 2387 | return; |
@@ -2422,7 +2431,7 @@ void drain_all_pages(struct zone *zone) | |||
2422 | for_each_cpu(cpu, &cpus_with_pcps) { | 2431 | for_each_cpu(cpu, &cpus_with_pcps) { |
2423 | struct work_struct *work = per_cpu_ptr(&pcpu_drain, cpu); | 2432 | struct work_struct *work = per_cpu_ptr(&pcpu_drain, cpu); |
2424 | INIT_WORK(work, drain_local_pages_wq); | 2433 | INIT_WORK(work, drain_local_pages_wq); |
2425 | schedule_work_on(cpu, work); | 2434 | queue_work_on(cpu, mm_percpu_wq, work); |
2426 | } | 2435 | } |
2427 | for_each_cpu(cpu, &cpus_with_pcps) | 2436 | for_each_cpu(cpu, &cpus_with_pcps) |
2428 | flush_work(per_cpu_ptr(&pcpu_drain, cpu)); | 2437 | flush_work(per_cpu_ptr(&pcpu_drain, cpu)); |
@@ -2478,20 +2487,17 @@ void free_hot_cold_page(struct page *page, bool cold) | |||
2478 | { | 2487 | { |
2479 | struct zone *zone = page_zone(page); | 2488 | struct zone *zone = page_zone(page); |
2480 | struct per_cpu_pages *pcp; | 2489 | struct per_cpu_pages *pcp; |
2490 | unsigned long flags; | ||
2481 | unsigned long pfn = page_to_pfn(page); | 2491 | unsigned long pfn = page_to_pfn(page); |
2482 | int migratetype; | 2492 | int migratetype; |
2483 | 2493 | ||
2484 | if (in_interrupt()) { | ||
2485 | __free_pages_ok(page, 0); | ||
2486 | return; | ||
2487 | } | ||
2488 | |||
2489 | if (!free_pcp_prepare(page)) | 2494 | if (!free_pcp_prepare(page)) |
2490 | return; | 2495 | return; |
2491 | 2496 | ||
2492 | migratetype = get_pfnblock_migratetype(page, pfn); | 2497 | migratetype = get_pfnblock_migratetype(page, pfn); |
2493 | set_pcppage_migratetype(page, migratetype); | 2498 | set_pcppage_migratetype(page, migratetype); |
2494 | preempt_disable(); | 2499 | local_irq_save(flags); |
2500 | __count_vm_event(PGFREE); | ||
2495 | 2501 | ||
2496 | /* | 2502 | /* |
2497 | * We only track unmovable, reclaimable and movable on pcp lists. | 2503 | * We only track unmovable, reclaimable and movable on pcp lists. |
@@ -2508,7 +2514,6 @@ void free_hot_cold_page(struct page *page, bool cold) | |||
2508 | migratetype = MIGRATE_MOVABLE; | 2514 | migratetype = MIGRATE_MOVABLE; |
2509 | } | 2515 | } |
2510 | 2516 | ||
2511 | __count_vm_event(PGFREE); | ||
2512 | pcp = &this_cpu_ptr(zone->pageset)->pcp; | 2517 | pcp = &this_cpu_ptr(zone->pageset)->pcp; |
2513 | if (!cold) | 2518 | if (!cold) |
2514 | list_add(&page->lru, &pcp->lists[migratetype]); | 2519 | list_add(&page->lru, &pcp->lists[migratetype]); |
@@ -2522,7 +2527,7 @@ void free_hot_cold_page(struct page *page, bool cold) | |||
2522 | } | 2527 | } |
2523 | 2528 | ||
2524 | out: | 2529 | out: |
2525 | preempt_enable(); | 2530 | local_irq_restore(flags); |
2526 | } | 2531 | } |
2527 | 2532 | ||
2528 | /* | 2533 | /* |
@@ -2647,8 +2652,6 @@ static struct page *__rmqueue_pcplist(struct zone *zone, int migratetype, | |||
2647 | { | 2652 | { |
2648 | struct page *page; | 2653 | struct page *page; |
2649 | 2654 | ||
2650 | VM_BUG_ON(in_interrupt()); | ||
2651 | |||
2652 | do { | 2655 | do { |
2653 | if (list_empty(list)) { | 2656 | if (list_empty(list)) { |
2654 | pcp->count += rmqueue_bulk(zone, 0, | 2657 | pcp->count += rmqueue_bulk(zone, 0, |
@@ -2679,8 +2682,9 @@ static struct page *rmqueue_pcplist(struct zone *preferred_zone, | |||
2679 | struct list_head *list; | 2682 | struct list_head *list; |
2680 | bool cold = ((gfp_flags & __GFP_COLD) != 0); | 2683 | bool cold = ((gfp_flags & __GFP_COLD) != 0); |
2681 | struct page *page; | 2684 | struct page *page; |
2685 | unsigned long flags; | ||
2682 | 2686 | ||
2683 | preempt_disable(); | 2687 | local_irq_save(flags); |
2684 | pcp = &this_cpu_ptr(zone->pageset)->pcp; | 2688 | pcp = &this_cpu_ptr(zone->pageset)->pcp; |
2685 | list = &pcp->lists[migratetype]; | 2689 | list = &pcp->lists[migratetype]; |
2686 | page = __rmqueue_pcplist(zone, migratetype, cold, pcp, list); | 2690 | page = __rmqueue_pcplist(zone, migratetype, cold, pcp, list); |
@@ -2688,7 +2692,7 @@ static struct page *rmqueue_pcplist(struct zone *preferred_zone, | |||
2688 | __count_zid_vm_events(PGALLOC, page_zonenum(page), 1 << order); | 2692 | __count_zid_vm_events(PGALLOC, page_zonenum(page), 1 << order); |
2689 | zone_statistics(preferred_zone, zone); | 2693 | zone_statistics(preferred_zone, zone); |
2690 | } | 2694 | } |
2691 | preempt_enable(); | 2695 | local_irq_restore(flags); |
2692 | return page; | 2696 | return page; |
2693 | } | 2697 | } |
2694 | 2698 | ||
@@ -2704,7 +2708,7 @@ struct page *rmqueue(struct zone *preferred_zone, | |||
2704 | unsigned long flags; | 2708 | unsigned long flags; |
2705 | struct page *page; | 2709 | struct page *page; |
2706 | 2710 | ||
2707 | if (likely(order == 0) && !in_interrupt()) { | 2711 | if (likely(order == 0)) { |
2708 | page = rmqueue_pcplist(preferred_zone, zone, order, | 2712 | page = rmqueue_pcplist(preferred_zone, zone, order, |
2709 | gfp_flags, migratetype); | 2713 | gfp_flags, migratetype); |
2710 | goto out; | 2714 | goto out; |
@@ -4519,13 +4523,13 @@ void show_free_areas(unsigned int filter, nodemask_t *nodemask) | |||
4519 | K(node_page_state(pgdat, NR_FILE_MAPPED)), | 4523 | K(node_page_state(pgdat, NR_FILE_MAPPED)), |
4520 | K(node_page_state(pgdat, NR_FILE_DIRTY)), | 4524 | K(node_page_state(pgdat, NR_FILE_DIRTY)), |
4521 | K(node_page_state(pgdat, NR_WRITEBACK)), | 4525 | K(node_page_state(pgdat, NR_WRITEBACK)), |
4526 | K(node_page_state(pgdat, NR_SHMEM)), | ||
4522 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 4527 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
4523 | K(node_page_state(pgdat, NR_SHMEM_THPS) * HPAGE_PMD_NR), | 4528 | K(node_page_state(pgdat, NR_SHMEM_THPS) * HPAGE_PMD_NR), |
4524 | K(node_page_state(pgdat, NR_SHMEM_PMDMAPPED) | 4529 | K(node_page_state(pgdat, NR_SHMEM_PMDMAPPED) |
4525 | * HPAGE_PMD_NR), | 4530 | * HPAGE_PMD_NR), |
4526 | K(node_page_state(pgdat, NR_ANON_THPS) * HPAGE_PMD_NR), | 4531 | K(node_page_state(pgdat, NR_ANON_THPS) * HPAGE_PMD_NR), |
4527 | #endif | 4532 | #endif |
4528 | K(node_page_state(pgdat, NR_SHMEM)), | ||
4529 | K(node_page_state(pgdat, NR_WRITEBACK_TEMP)), | 4533 | K(node_page_state(pgdat, NR_WRITEBACK_TEMP)), |
4530 | K(node_page_state(pgdat, NR_UNSTABLE_NFS)), | 4534 | K(node_page_state(pgdat, NR_UNSTABLE_NFS)), |
4531 | node_page_state(pgdat, NR_PAGES_SCANNED), | 4535 | node_page_state(pgdat, NR_PAGES_SCANNED), |