diff options
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r-- | mm/page_alloc.c | 132 |
1 files changed, 97 insertions, 35 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 533e2147d14f..3bac76ae4b30 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -205,7 +205,7 @@ static char * const zone_names[MAX_NR_ZONES] = { | |||
205 | }; | 205 | }; |
206 | 206 | ||
207 | int min_free_kbytes = 1024; | 207 | int min_free_kbytes = 1024; |
208 | int user_min_free_kbytes; | 208 | int user_min_free_kbytes = -1; |
209 | 209 | ||
210 | static unsigned long __meminitdata nr_kernel_pages; | 210 | static unsigned long __meminitdata nr_kernel_pages; |
211 | static unsigned long __meminitdata nr_all_pages; | 211 | static unsigned long __meminitdata nr_all_pages; |
@@ -295,7 +295,7 @@ static inline int bad_range(struct zone *zone, struct page *page) | |||
295 | } | 295 | } |
296 | #endif | 296 | #endif |
297 | 297 | ||
298 | static void bad_page(struct page *page) | 298 | static void bad_page(struct page *page, char *reason, unsigned long bad_flags) |
299 | { | 299 | { |
300 | static unsigned long resume; | 300 | static unsigned long resume; |
301 | static unsigned long nr_shown; | 301 | static unsigned long nr_shown; |
@@ -329,7 +329,7 @@ static void bad_page(struct page *page) | |||
329 | 329 | ||
330 | printk(KERN_ALERT "BUG: Bad page state in process %s pfn:%05lx\n", | 330 | printk(KERN_ALERT "BUG: Bad page state in process %s pfn:%05lx\n", |
331 | current->comm, page_to_pfn(page)); | 331 | current->comm, page_to_pfn(page)); |
332 | dump_page(page); | 332 | dump_page_badflags(page, reason, bad_flags); |
333 | 333 | ||
334 | print_modules(); | 334 | print_modules(); |
335 | dump_stack(); | 335 | dump_stack(); |
@@ -369,9 +369,11 @@ void prep_compound_page(struct page *page, unsigned long order) | |||
369 | __SetPageHead(page); | 369 | __SetPageHead(page); |
370 | for (i = 1; i < nr_pages; i++) { | 370 | for (i = 1; i < nr_pages; i++) { |
371 | struct page *p = page + i; | 371 | struct page *p = page + i; |
372 | __SetPageTail(p); | ||
373 | set_page_count(p, 0); | 372 | set_page_count(p, 0); |
374 | p->first_page = page; | 373 | p->first_page = page; |
374 | /* Make sure p->first_page is always valid for PageTail() */ | ||
375 | smp_wmb(); | ||
376 | __SetPageTail(p); | ||
375 | } | 377 | } |
376 | } | 378 | } |
377 | 379 | ||
@@ -383,7 +385,7 @@ static int destroy_compound_page(struct page *page, unsigned long order) | |||
383 | int bad = 0; | 385 | int bad = 0; |
384 | 386 | ||
385 | if (unlikely(compound_order(page) != order)) { | 387 | if (unlikely(compound_order(page) != order)) { |
386 | bad_page(page); | 388 | bad_page(page, "wrong compound order", 0); |
387 | bad++; | 389 | bad++; |
388 | } | 390 | } |
389 | 391 | ||
@@ -392,8 +394,11 @@ static int destroy_compound_page(struct page *page, unsigned long order) | |||
392 | for (i = 1; i < nr_pages; i++) { | 394 | for (i = 1; i < nr_pages; i++) { |
393 | struct page *p = page + i; | 395 | struct page *p = page + i; |
394 | 396 | ||
395 | if (unlikely(!PageTail(p) || (p->first_page != page))) { | 397 | if (unlikely(!PageTail(p))) { |
396 | bad_page(page); | 398 | bad_page(page, "PageTail not set", 0); |
399 | bad++; | ||
400 | } else if (unlikely(p->first_page != page)) { | ||
401 | bad_page(page, "first_page not consistent", 0); | ||
397 | bad++; | 402 | bad++; |
398 | } | 403 | } |
399 | __ClearPageTail(p); | 404 | __ClearPageTail(p); |
@@ -506,12 +511,12 @@ static inline int page_is_buddy(struct page *page, struct page *buddy, | |||
506 | return 0; | 511 | return 0; |
507 | 512 | ||
508 | if (page_is_guard(buddy) && page_order(buddy) == order) { | 513 | if (page_is_guard(buddy) && page_order(buddy) == order) { |
509 | VM_BUG_ON(page_count(buddy) != 0); | 514 | VM_BUG_ON_PAGE(page_count(buddy) != 0, buddy); |
510 | return 1; | 515 | return 1; |
511 | } | 516 | } |
512 | 517 | ||
513 | if (PageBuddy(buddy) && page_order(buddy) == order) { | 518 | if (PageBuddy(buddy) && page_order(buddy) == order) { |
514 | VM_BUG_ON(page_count(buddy) != 0); | 519 | VM_BUG_ON_PAGE(page_count(buddy) != 0, buddy); |
515 | return 1; | 520 | return 1; |
516 | } | 521 | } |
517 | return 0; | 522 | return 0; |
@@ -561,8 +566,8 @@ static inline void __free_one_page(struct page *page, | |||
561 | 566 | ||
562 | page_idx = page_to_pfn(page) & ((1 << MAX_ORDER) - 1); | 567 | page_idx = page_to_pfn(page) & ((1 << MAX_ORDER) - 1); |
563 | 568 | ||
564 | VM_BUG_ON(page_idx & ((1 << order) - 1)); | 569 | VM_BUG_ON_PAGE(page_idx & ((1 << order) - 1), page); |
565 | VM_BUG_ON(bad_range(zone, page)); | 570 | VM_BUG_ON_PAGE(bad_range(zone, page), page); |
566 | 571 | ||
567 | while (order < MAX_ORDER-1) { | 572 | while (order < MAX_ORDER-1) { |
568 | buddy_idx = __find_buddy_index(page_idx, order); | 573 | buddy_idx = __find_buddy_index(page_idx, order); |
@@ -618,12 +623,23 @@ out: | |||
618 | 623 | ||
619 | static inline int free_pages_check(struct page *page) | 624 | static inline int free_pages_check(struct page *page) |
620 | { | 625 | { |
621 | if (unlikely(page_mapcount(page) | | 626 | char *bad_reason = NULL; |
622 | (page->mapping != NULL) | | 627 | unsigned long bad_flags = 0; |
623 | (atomic_read(&page->_count) != 0) | | 628 | |
624 | (page->flags & PAGE_FLAGS_CHECK_AT_FREE) | | 629 | if (unlikely(page_mapcount(page))) |
625 | (mem_cgroup_bad_page_check(page)))) { | 630 | bad_reason = "nonzero mapcount"; |
626 | bad_page(page); | 631 | if (unlikely(page->mapping != NULL)) |
632 | bad_reason = "non-NULL mapping"; | ||
633 | if (unlikely(atomic_read(&page->_count) != 0)) | ||
634 | bad_reason = "nonzero _count"; | ||
635 | if (unlikely(page->flags & PAGE_FLAGS_CHECK_AT_FREE)) { | ||
636 | bad_reason = "PAGE_FLAGS_CHECK_AT_FREE flag(s) set"; | ||
637 | bad_flags = PAGE_FLAGS_CHECK_AT_FREE; | ||
638 | } | ||
639 | if (unlikely(mem_cgroup_bad_page_check(page))) | ||
640 | bad_reason = "cgroup check failed"; | ||
641 | if (unlikely(bad_reason)) { | ||
642 | bad_page(page, bad_reason, bad_flags); | ||
627 | return 1; | 643 | return 1; |
628 | } | 644 | } |
629 | page_cpupid_reset_last(page); | 645 | page_cpupid_reset_last(page); |
@@ -813,7 +829,7 @@ static inline void expand(struct zone *zone, struct page *page, | |||
813 | area--; | 829 | area--; |
814 | high--; | 830 | high--; |
815 | size >>= 1; | 831 | size >>= 1; |
816 | VM_BUG_ON(bad_range(zone, &page[size])); | 832 | VM_BUG_ON_PAGE(bad_range(zone, &page[size]), &page[size]); |
817 | 833 | ||
818 | #ifdef CONFIG_DEBUG_PAGEALLOC | 834 | #ifdef CONFIG_DEBUG_PAGEALLOC |
819 | if (high < debug_guardpage_minorder()) { | 835 | if (high < debug_guardpage_minorder()) { |
@@ -843,12 +859,23 @@ static inline void expand(struct zone *zone, struct page *page, | |||
843 | */ | 859 | */ |
844 | static inline int check_new_page(struct page *page) | 860 | static inline int check_new_page(struct page *page) |
845 | { | 861 | { |
846 | if (unlikely(page_mapcount(page) | | 862 | char *bad_reason = NULL; |
847 | (page->mapping != NULL) | | 863 | unsigned long bad_flags = 0; |
848 | (atomic_read(&page->_count) != 0) | | 864 | |
849 | (page->flags & PAGE_FLAGS_CHECK_AT_PREP) | | 865 | if (unlikely(page_mapcount(page))) |
850 | (mem_cgroup_bad_page_check(page)))) { | 866 | bad_reason = "nonzero mapcount"; |
851 | bad_page(page); | 867 | if (unlikely(page->mapping != NULL)) |
868 | bad_reason = "non-NULL mapping"; | ||
869 | if (unlikely(atomic_read(&page->_count) != 0)) | ||
870 | bad_reason = "nonzero _count"; | ||
871 | if (unlikely(page->flags & PAGE_FLAGS_CHECK_AT_PREP)) { | ||
872 | bad_reason = "PAGE_FLAGS_CHECK_AT_PREP flag set"; | ||
873 | bad_flags = PAGE_FLAGS_CHECK_AT_PREP; | ||
874 | } | ||
875 | if (unlikely(mem_cgroup_bad_page_check(page))) | ||
876 | bad_reason = "cgroup check failed"; | ||
877 | if (unlikely(bad_reason)) { | ||
878 | bad_page(page, bad_reason, bad_flags); | ||
852 | return 1; | 879 | return 1; |
853 | } | 880 | } |
854 | return 0; | 881 | return 0; |
@@ -955,7 +982,7 @@ int move_freepages(struct zone *zone, | |||
955 | 982 | ||
956 | for (page = start_page; page <= end_page;) { | 983 | for (page = start_page; page <= end_page;) { |
957 | /* Make sure we are not inadvertently changing nodes */ | 984 | /* Make sure we are not inadvertently changing nodes */ |
958 | VM_BUG_ON(page_to_nid(page) != zone_to_nid(zone)); | 985 | VM_BUG_ON_PAGE(page_to_nid(page) != zone_to_nid(zone), page); |
959 | 986 | ||
960 | if (!pfn_valid_within(page_to_pfn(page))) { | 987 | if (!pfn_valid_within(page_to_pfn(page))) { |
961 | page++; | 988 | page++; |
@@ -1211,6 +1238,15 @@ void drain_zone_pages(struct zone *zone, struct per_cpu_pages *pcp) | |||
1211 | } | 1238 | } |
1212 | local_irq_restore(flags); | 1239 | local_irq_restore(flags); |
1213 | } | 1240 | } |
1241 | static bool gfp_thisnode_allocation(gfp_t gfp_mask) | ||
1242 | { | ||
1243 | return (gfp_mask & GFP_THISNODE) == GFP_THISNODE; | ||
1244 | } | ||
1245 | #else | ||
1246 | static bool gfp_thisnode_allocation(gfp_t gfp_mask) | ||
1247 | { | ||
1248 | return false; | ||
1249 | } | ||
1214 | #endif | 1250 | #endif |
1215 | 1251 | ||
1216 | /* | 1252 | /* |
@@ -1404,8 +1440,8 @@ void split_page(struct page *page, unsigned int order) | |||
1404 | { | 1440 | { |
1405 | int i; | 1441 | int i; |
1406 | 1442 | ||
1407 | VM_BUG_ON(PageCompound(page)); | 1443 | VM_BUG_ON_PAGE(PageCompound(page), page); |
1408 | VM_BUG_ON(!page_count(page)); | 1444 | VM_BUG_ON_PAGE(!page_count(page), page); |
1409 | 1445 | ||
1410 | #ifdef CONFIG_KMEMCHECK | 1446 | #ifdef CONFIG_KMEMCHECK |
1411 | /* | 1447 | /* |
@@ -1547,12 +1583,18 @@ again: | |||
1547 | get_pageblock_migratetype(page)); | 1583 | get_pageblock_migratetype(page)); |
1548 | } | 1584 | } |
1549 | 1585 | ||
1550 | __mod_zone_page_state(zone, NR_ALLOC_BATCH, -(1 << order)); | 1586 | /* |
1587 | * NOTE: GFP_THISNODE allocations do not partake in the kswapd | ||
1588 | * aging protocol, so they can't be fair. | ||
1589 | */ | ||
1590 | if (!gfp_thisnode_allocation(gfp_flags)) | ||
1591 | __mod_zone_page_state(zone, NR_ALLOC_BATCH, -(1 << order)); | ||
1592 | |||
1551 | __count_zone_vm_events(PGALLOC, zone, 1 << order); | 1593 | __count_zone_vm_events(PGALLOC, zone, 1 << order); |
1552 | zone_statistics(preferred_zone, zone, gfp_flags); | 1594 | zone_statistics(preferred_zone, zone, gfp_flags); |
1553 | local_irq_restore(flags); | 1595 | local_irq_restore(flags); |
1554 | 1596 | ||
1555 | VM_BUG_ON(bad_range(zone, page)); | 1597 | VM_BUG_ON_PAGE(bad_range(zone, page), page); |
1556 | if (prep_new_page(page, order, gfp_flags)) | 1598 | if (prep_new_page(page, order, gfp_flags)) |
1557 | goto again; | 1599 | goto again; |
1558 | return page; | 1600 | return page; |
@@ -1919,8 +1961,12 @@ zonelist_scan: | |||
1919 | * ultimately fall back to remote zones that do not | 1961 | * ultimately fall back to remote zones that do not |
1920 | * partake in the fairness round-robin cycle of this | 1962 | * partake in the fairness round-robin cycle of this |
1921 | * zonelist. | 1963 | * zonelist. |
1964 | * | ||
1965 | * NOTE: GFP_THISNODE allocations do not partake in | ||
1966 | * the kswapd aging protocol, so they can't be fair. | ||
1922 | */ | 1967 | */ |
1923 | if (alloc_flags & ALLOC_WMARK_LOW) { | 1968 | if ((alloc_flags & ALLOC_WMARK_LOW) && |
1969 | !gfp_thisnode_allocation(gfp_mask)) { | ||
1924 | if (zone_page_state(zone, NR_ALLOC_BATCH) <= 0) | 1970 | if (zone_page_state(zone, NR_ALLOC_BATCH) <= 0) |
1925 | continue; | 1971 | continue; |
1926 | if (!zone_local(preferred_zone, zone)) | 1972 | if (!zone_local(preferred_zone, zone)) |
@@ -2476,8 +2522,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, | |||
2476 | * allowed per node queues are empty and that nodes are | 2522 | * allowed per node queues are empty and that nodes are |
2477 | * over allocated. | 2523 | * over allocated. |
2478 | */ | 2524 | */ |
2479 | if (IS_ENABLED(CONFIG_NUMA) && | 2525 | if (gfp_thisnode_allocation(gfp_mask)) |
2480 | (gfp_mask & GFP_THISNODE) == GFP_THISNODE) | ||
2481 | goto nopage; | 2526 | goto nopage; |
2482 | 2527 | ||
2483 | restart: | 2528 | restart: |
@@ -5729,7 +5774,12 @@ module_init(init_per_zone_wmark_min) | |||
5729 | int min_free_kbytes_sysctl_handler(ctl_table *table, int write, | 5774 | int min_free_kbytes_sysctl_handler(ctl_table *table, int write, |
5730 | void __user *buffer, size_t *length, loff_t *ppos) | 5775 | void __user *buffer, size_t *length, loff_t *ppos) |
5731 | { | 5776 | { |
5732 | proc_dointvec(table, write, buffer, length, ppos); | 5777 | int rc; |
5778 | |||
5779 | rc = proc_dointvec_minmax(table, write, buffer, length, ppos); | ||
5780 | if (rc) | ||
5781 | return rc; | ||
5782 | |||
5733 | if (write) { | 5783 | if (write) { |
5734 | user_min_free_kbytes = min_free_kbytes; | 5784 | user_min_free_kbytes = min_free_kbytes; |
5735 | setup_per_zone_wmarks(); | 5785 | setup_per_zone_wmarks(); |
@@ -5996,7 +6046,7 @@ void set_pageblock_flags_group(struct page *page, unsigned long flags, | |||
5996 | pfn = page_to_pfn(page); | 6046 | pfn = page_to_pfn(page); |
5997 | bitmap = get_pageblock_bitmap(zone, pfn); | 6047 | bitmap = get_pageblock_bitmap(zone, pfn); |
5998 | bitidx = pfn_to_bitidx(zone, pfn); | 6048 | bitidx = pfn_to_bitidx(zone, pfn); |
5999 | VM_BUG_ON(!zone_spans_pfn(zone, pfn)); | 6049 | VM_BUG_ON_PAGE(!zone_spans_pfn(zone, pfn), page); |
6000 | 6050 | ||
6001 | for (; start_bitidx <= end_bitidx; start_bitidx++, value <<= 1) | 6051 | for (; start_bitidx <= end_bitidx; start_bitidx++, value <<= 1) |
6002 | if (flags & value) | 6052 | if (flags & value) |
@@ -6494,12 +6544,24 @@ static void dump_page_flags(unsigned long flags) | |||
6494 | printk(")\n"); | 6544 | printk(")\n"); |
6495 | } | 6545 | } |
6496 | 6546 | ||
6497 | void dump_page(struct page *page) | 6547 | void dump_page_badflags(struct page *page, char *reason, unsigned long badflags) |
6498 | { | 6548 | { |
6499 | printk(KERN_ALERT | 6549 | printk(KERN_ALERT |
6500 | "page:%p count:%d mapcount:%d mapping:%p index:%#lx\n", | 6550 | "page:%p count:%d mapcount:%d mapping:%p index:%#lx\n", |
6501 | page, atomic_read(&page->_count), page_mapcount(page), | 6551 | page, atomic_read(&page->_count), page_mapcount(page), |
6502 | page->mapping, page->index); | 6552 | page->mapping, page->index); |
6503 | dump_page_flags(page->flags); | 6553 | dump_page_flags(page->flags); |
6554 | if (reason) | ||
6555 | pr_alert("page dumped because: %s\n", reason); | ||
6556 | if (page->flags & badflags) { | ||
6557 | pr_alert("bad because of flags:\n"); | ||
6558 | dump_page_flags(page->flags & badflags); | ||
6559 | } | ||
6504 | mem_cgroup_print_bad_page(page); | 6560 | mem_cgroup_print_bad_page(page); |
6505 | } | 6561 | } |
6562 | |||
6563 | void dump_page(struct page *page, char *reason) | ||
6564 | { | ||
6565 | dump_page_badflags(page, reason, 0); | ||
6566 | } | ||
6567 | EXPORT_SYMBOL_GPL(dump_page); | ||