diff options
Diffstat (limited to 'arch/ia64/mm')
| -rw-r--r-- | arch/ia64/mm/contig.c | 3 | ||||
| -rw-r--r-- | arch/ia64/mm/discontig.c | 3 | ||||
| -rw-r--r-- | arch/ia64/mm/init.c | 74 |
3 files changed, 51 insertions, 29 deletions
diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c index 6daf15ac8940..91a055f5731f 100644 --- a/arch/ia64/mm/contig.c +++ b/arch/ia64/mm/contig.c | |||
| @@ -61,7 +61,8 @@ show_mem (void) | |||
| 61 | printk("%d reserved pages\n", reserved); | 61 | printk("%d reserved pages\n", reserved); |
| 62 | printk("%d pages shared\n", shared); | 62 | printk("%d pages shared\n", shared); |
| 63 | printk("%d pages swap cached\n", cached); | 63 | printk("%d pages swap cached\n", cached); |
| 64 | printk("%ld pages in page table cache\n", pgtable_cache_size); | 64 | printk("%ld pages in page table cache\n", |
| 65 | pgtable_quicklist_total_size()); | ||
| 65 | } | 66 | } |
| 66 | 67 | ||
| 67 | /* physical address where the bootmem map is located */ | 68 | /* physical address where the bootmem map is located */ |
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index 3456a9b6971e..c00710929390 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c | |||
| @@ -582,7 +582,8 @@ void show_mem(void) | |||
| 582 | printk("%d reserved pages\n", total_reserved); | 582 | printk("%d reserved pages\n", total_reserved); |
| 583 | printk("%d pages shared\n", total_shared); | 583 | printk("%d pages shared\n", total_shared); |
| 584 | printk("%d pages swap cached\n", total_cached); | 584 | printk("%d pages swap cached\n", total_cached); |
| 585 | printk("Total of %ld pages in page table cache\n", pgtable_cache_size); | 585 | printk("Total of %ld pages in page table cache\n", |
| 586 | pgtable_quicklist_total_size()); | ||
| 586 | printk("%d free buffer pages\n", nr_free_buffer_pages()); | 587 | printk("%d free buffer pages\n", nr_free_buffer_pages()); |
| 587 | } | 588 | } |
| 588 | 589 | ||
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 65cf839573ea..4892be53e227 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c | |||
| @@ -39,6 +39,9 @@ | |||
| 39 | 39 | ||
| 40 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); | 40 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); |
| 41 | 41 | ||
| 42 | DEFINE_PER_CPU(unsigned long *, __pgtable_quicklist); | ||
| 43 | DEFINE_PER_CPU(long, __pgtable_quicklist_size); | ||
| 44 | |||
| 42 | extern void ia64_tlb_init (void); | 45 | extern void ia64_tlb_init (void); |
| 43 | 46 | ||
| 44 | unsigned long MAX_DMA_ADDRESS = PAGE_OFFSET + 0x100000000UL; | 47 | unsigned long MAX_DMA_ADDRESS = PAGE_OFFSET + 0x100000000UL; |
| @@ -50,27 +53,53 @@ struct page *vmem_map; | |||
| 50 | EXPORT_SYMBOL(vmem_map); | 53 | EXPORT_SYMBOL(vmem_map); |
| 51 | #endif | 54 | #endif |
| 52 | 55 | ||
| 53 | static int pgt_cache_water[2] = { 25, 50 }; | 56 | struct page *zero_page_memmap_ptr; /* map entry for zero page */ |
| 54 | |||
| 55 | struct page *zero_page_memmap_ptr; /* map entry for zero page */ | ||
| 56 | EXPORT_SYMBOL(zero_page_memmap_ptr); | 57 | EXPORT_SYMBOL(zero_page_memmap_ptr); |
| 57 | 58 | ||
| 59 | #define MIN_PGT_PAGES 25UL | ||
| 60 | #define MAX_PGT_FREES_PER_PASS 16 | ||
| 61 | #define PGT_FRACTION_OF_NODE_MEM 16 | ||
| 62 | |||
| 63 | static inline long | ||
| 64 | max_pgt_pages(void) | ||
| 65 | { | ||
| 66 | u64 node_free_pages, max_pgt_pages; | ||
| 67 | |||
| 68 | #ifndef CONFIG_NUMA | ||
| 69 | node_free_pages = nr_free_pages(); | ||
| 70 | #else | ||
| 71 | node_free_pages = nr_free_pages_pgdat(NODE_DATA(numa_node_id())); | ||
| 72 | #endif | ||
| 73 | max_pgt_pages = node_free_pages / PGT_FRACTION_OF_NODE_MEM; | ||
| 74 | max_pgt_pages = max(max_pgt_pages, MIN_PGT_PAGES); | ||
| 75 | return max_pgt_pages; | ||
| 76 | } | ||
| 77 | |||
| 78 | static inline long | ||
| 79 | min_pages_to_free(void) | ||
| 80 | { | ||
| 81 | long pages_to_free; | ||
| 82 | |||
| 83 | pages_to_free = pgtable_quicklist_size - max_pgt_pages(); | ||
| 84 | pages_to_free = min(pages_to_free, MAX_PGT_FREES_PER_PASS); | ||
| 85 | return pages_to_free; | ||
| 86 | } | ||
| 87 | |||
| 58 | void | 88 | void |
| 59 | check_pgt_cache (void) | 89 | check_pgt_cache(void) |
| 60 | { | 90 | { |
| 61 | int low, high; | 91 | long pages_to_free; |
| 62 | 92 | ||
| 63 | low = pgt_cache_water[0]; | 93 | if (unlikely(pgtable_quicklist_size <= MIN_PGT_PAGES)) |
| 64 | high = pgt_cache_water[1]; | 94 | return; |
| 65 | 95 | ||
| 66 | preempt_disable(); | 96 | preempt_disable(); |
| 67 | if (pgtable_cache_size > (u64) high) { | 97 | while (unlikely((pages_to_free = min_pages_to_free()) > 0)) { |
| 68 | do { | 98 | while (pages_to_free--) { |
| 69 | if (pgd_quicklist) | 99 | free_page((unsigned long)pgtable_quicklist_alloc()); |
| 70 | free_page((unsigned long)pgd_alloc_one_fast(NULL)); | 100 | } |
| 71 | if (pmd_quicklist) | 101 | preempt_enable(); |
| 72 | free_page((unsigned long)pmd_alloc_one_fast(NULL, 0)); | 102 | preempt_disable(); |
| 73 | } while (pgtable_cache_size > (u64) low); | ||
| 74 | } | 103 | } |
| 75 | preempt_enable(); | 104 | preempt_enable(); |
| 76 | } | 105 | } |
| @@ -523,11 +552,14 @@ void | |||
| 523 | mem_init (void) | 552 | mem_init (void) |
| 524 | { | 553 | { |
| 525 | long reserved_pages, codesize, datasize, initsize; | 554 | long reserved_pages, codesize, datasize, initsize; |
| 526 | unsigned long num_pgt_pages; | ||
| 527 | pg_data_t *pgdat; | 555 | pg_data_t *pgdat; |
| 528 | int i; | 556 | int i; |
| 529 | static struct kcore_list kcore_mem, kcore_vmem, kcore_kernel; | 557 | static struct kcore_list kcore_mem, kcore_vmem, kcore_kernel; |
| 530 | 558 | ||
| 559 | BUG_ON(PTRS_PER_PGD * sizeof(pgd_t) != PAGE_SIZE); | ||
| 560 | BUG_ON(PTRS_PER_PMD * sizeof(pmd_t) != PAGE_SIZE); | ||
| 561 | BUG_ON(PTRS_PER_PTE * sizeof(pte_t) != PAGE_SIZE); | ||
| 562 | |||
| 531 | #ifdef CONFIG_PCI | 563 | #ifdef CONFIG_PCI |
| 532 | /* | 564 | /* |
| 533 | * This needs to be called _after_ the command line has been parsed but _before_ | 565 | * This needs to be called _after_ the command line has been parsed but _before_ |
| @@ -564,18 +596,6 @@ mem_init (void) | |||
| 564 | num_physpages << (PAGE_SHIFT - 10), codesize >> 10, | 596 | num_physpages << (PAGE_SHIFT - 10), codesize >> 10, |
| 565 | reserved_pages << (PAGE_SHIFT - 10), datasize >> 10, initsize >> 10); | 597 | reserved_pages << (PAGE_SHIFT - 10), datasize >> 10, initsize >> 10); |
| 566 | 598 | ||
| 567 | /* | ||
| 568 | * Allow for enough (cached) page table pages so that we can map the entire memory | ||
| 569 | * at least once. Each task also needs a couple of page tables pages, so add in a | ||
| 570 | * fudge factor for that (don't use "threads-max" here; that would be wrong!). | ||
| 571 | * Don't allow the cache to be more than 10% of total memory, though. | ||
| 572 | */ | ||
| 573 | # define NUM_TASKS 500 /* typical number of tasks */ | ||
| 574 | num_pgt_pages = nr_free_pages() / PTRS_PER_PGD + NUM_TASKS; | ||
| 575 | if (num_pgt_pages > nr_free_pages() / 10) | ||
| 576 | num_pgt_pages = nr_free_pages() / 10; | ||
| 577 | if (num_pgt_pages > (u64) pgt_cache_water[1]) | ||
| 578 | pgt_cache_water[1] = num_pgt_pages; | ||
| 579 | 599 | ||
| 580 | /* | 600 | /* |
| 581 | * For fsyscall entrpoints with no light-weight handler, use the ordinary | 601 | * For fsyscall entrpoints with no light-weight handler, use the ordinary |
