aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/mm')
-rw-r--r--arch/x86/mm/init_64.c13
-rw-r--r--arch/x86/mm/ioremap.c4
-rw-r--r--arch/x86/mm/numa_64.c8
-rw-r--r--arch/x86/mm/pageattr.c84
-rw-r--r--arch/x86/mm/pgtable_32.c18
5 files changed, 70 insertions, 57 deletions
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index bb652f5a93fb..a02a14f0f324 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -172,8 +172,9 @@ set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot)
172} 172}
173 173
174/* 174/*
175 * The head.S code sets up the kernel high mapping from: 175 * The head.S code sets up the kernel high mapping:
176 * __START_KERNEL_map to __START_KERNEL_map + KERNEL_TEXT_SIZE 176 *
177 * from __START_KERNEL_map to __START_KERNEL_map + size (== _end-_text)
177 * 178 *
178 * phys_addr holds the negative offset to the kernel, which is added 179 * phys_addr holds the negative offset to the kernel, which is added
179 * to the compile time generated pmds. This results in invalid pmds up 180 * to the compile time generated pmds. This results in invalid pmds up
@@ -515,14 +516,6 @@ void __init mem_init(void)
515 516
516 /* clear_bss() already clear the empty_zero_page */ 517 /* clear_bss() already clear the empty_zero_page */
517 518
518 /* temporary debugging - double check it's true: */
519 {
520 int i;
521
522 for (i = 0; i < 1024; i++)
523 WARN_ON_ONCE(empty_zero_page[i]);
524 }
525
526 reservedpages = 0; 519 reservedpages = 0;
527 520
528 /* this will put all low memory onto the freelists */ 521 /* this will put all low memory onto the freelists */
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 882328efc3db..8fe576baa148 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -134,8 +134,6 @@ static void __iomem *__ioremap(unsigned long phys_addr, unsigned long size,
134 return NULL; 134 return NULL;
135 } 135 }
136 136
137 WARN_ON_ONCE(page_is_ram(pfn));
138
139 switch (mode) { 137 switch (mode) {
140 case IOR_MODE_UNCACHED: 138 case IOR_MODE_UNCACHED:
141 default: 139 default:
@@ -162,7 +160,7 @@ static void __iomem *__ioremap(unsigned long phys_addr, unsigned long size,
162 area->phys_addr = phys_addr; 160 area->phys_addr = phys_addr;
163 vaddr = (unsigned long) area->addr; 161 vaddr = (unsigned long) area->addr;
164 if (ioremap_page_range(vaddr, vaddr + size, phys_addr, prot)) { 162 if (ioremap_page_range(vaddr, vaddr + size, phys_addr, prot)) {
165 remove_vm_area((void *)(vaddr & PAGE_MASK)); 163 free_vm_area(area);
166 return NULL; 164 return NULL;
167 } 165 }
168 166
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index 59898fb0a4aa..8ccfee10f5b5 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -622,13 +622,17 @@ void __init init_cpu_to_node(void)
622 int i; 622 int i;
623 623
624 for (i = 0; i < NR_CPUS; i++) { 624 for (i = 0; i < NR_CPUS; i++) {
625 int node;
625 u16 apicid = x86_cpu_to_apicid_init[i]; 626 u16 apicid = x86_cpu_to_apicid_init[i];
626 627
627 if (apicid == BAD_APICID) 628 if (apicid == BAD_APICID)
628 continue; 629 continue;
629 if (apicid_to_node[apicid] == NUMA_NO_NODE) 630 node = apicid_to_node[apicid];
631 if (node == NUMA_NO_NODE)
630 continue; 632 continue;
631 numa_set_node(i, apicid_to_node[apicid]); 633 if (!node_online(node))
634 continue;
635 numa_set_node(i, node);
632 } 636 }
633} 637}
634 638
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 464d8fc21ce6..14e48b5a94ba 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -44,6 +44,12 @@ static inline unsigned long highmap_end_pfn(void)
44 44
45#endif 45#endif
46 46
47#ifdef CONFIG_DEBUG_PAGEALLOC
48# define debug_pagealloc 1
49#else
50# define debug_pagealloc 0
51#endif
52
47static inline int 53static inline int
48within(unsigned long addr, unsigned long start, unsigned long end) 54within(unsigned long addr, unsigned long start, unsigned long end)
49{ 55{
@@ -355,45 +361,48 @@ out_unlock:
355 361
356static LIST_HEAD(page_pool); 362static LIST_HEAD(page_pool);
357static unsigned long pool_size, pool_pages, pool_low; 363static unsigned long pool_size, pool_pages, pool_low;
358static unsigned long pool_used, pool_failed, pool_refill; 364static unsigned long pool_used, pool_failed;
359 365
360static void cpa_fill_pool(void) 366static void cpa_fill_pool(struct page **ret)
361{ 367{
362 struct page *p;
363 gfp_t gfp = GFP_KERNEL; 368 gfp_t gfp = GFP_KERNEL;
369 unsigned long flags;
370 struct page *p;
364 371
365 /* Do not allocate from interrupt context */
366 if (in_irq() || irqs_disabled())
367 return;
368 /* 372 /*
369 * Check unlocked. I does not matter when we have one more 373 * Avoid recursion (on debug-pagealloc) and also signal
370 * page in the pool. The bit lock avoids recursive pool 374 * our priority to get to these pagetables:
371 * allocations:
372 */ 375 */
373 if (pool_pages >= pool_size || test_and_set_bit_lock(0, &pool_refill)) 376 if (current->flags & PF_MEMALLOC)
374 return; 377 return;
378 current->flags |= PF_MEMALLOC;
375 379
376#ifdef CONFIG_DEBUG_PAGEALLOC
377 /* 380 /*
378 * We could do: 381 * Allocate atomically from atomic contexts:
379 * gfp = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
380 * but this fails on !PREEMPT kernels
381 */ 382 */
382 gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN; 383 if (in_atomic() || irqs_disabled() || debug_pagealloc)
383#endif 384 gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN;
384 385
385 while (pool_pages < pool_size) { 386 while (pool_pages < pool_size || (ret && !*ret)) {
386 p = alloc_pages(gfp, 0); 387 p = alloc_pages(gfp, 0);
387 if (!p) { 388 if (!p) {
388 pool_failed++; 389 pool_failed++;
389 break; 390 break;
390 } 391 }
391 spin_lock_irq(&pgd_lock); 392 /*
393 * If the call site needs a page right now, provide it:
394 */
395 if (ret && !*ret) {
396 *ret = p;
397 continue;
398 }
399 spin_lock_irqsave(&pgd_lock, flags);
392 list_add(&p->lru, &page_pool); 400 list_add(&p->lru, &page_pool);
393 pool_pages++; 401 pool_pages++;
394 spin_unlock_irq(&pgd_lock); 402 spin_unlock_irqrestore(&pgd_lock, flags);
395 } 403 }
396 clear_bit_unlock(0, &pool_refill); 404
405 current->flags &= ~PF_MEMALLOC;
397} 406}
398 407
399#define SHIFT_MB (20 - PAGE_SHIFT) 408#define SHIFT_MB (20 - PAGE_SHIFT)
@@ -414,11 +423,15 @@ void __init cpa_init(void)
414 * GiB. Shift MiB to Gib and multiply the result by 423 * GiB. Shift MiB to Gib and multiply the result by
415 * POOL_PAGES_PER_GB: 424 * POOL_PAGES_PER_GB:
416 */ 425 */
417 gb = ((si.totalram >> SHIFT_MB) + ROUND_MB_GB) >> SHIFT_MB_GB; 426 if (debug_pagealloc) {
418 pool_size = POOL_PAGES_PER_GB * gb; 427 gb = ((si.totalram >> SHIFT_MB) + ROUND_MB_GB) >> SHIFT_MB_GB;
428 pool_size = POOL_PAGES_PER_GB * gb;
429 } else {
430 pool_size = 1;
431 }
419 pool_low = pool_size; 432 pool_low = pool_size;
420 433
421 cpa_fill_pool(); 434 cpa_fill_pool(NULL);
422 printk(KERN_DEBUG 435 printk(KERN_DEBUG
423 "CPA: page pool initialized %lu of %lu pages preallocated\n", 436 "CPA: page pool initialized %lu of %lu pages preallocated\n",
424 pool_pages, pool_size); 437 pool_pages, pool_size);
@@ -440,16 +453,20 @@ static int split_large_page(pte_t *kpte, unsigned long address)
440 spin_lock_irqsave(&pgd_lock, flags); 453 spin_lock_irqsave(&pgd_lock, flags);
441 if (list_empty(&page_pool)) { 454 if (list_empty(&page_pool)) {
442 spin_unlock_irqrestore(&pgd_lock, flags); 455 spin_unlock_irqrestore(&pgd_lock, flags);
443 return -ENOMEM; 456 base = NULL;
457 cpa_fill_pool(&base);
458 if (!base)
459 return -ENOMEM;
460 spin_lock_irqsave(&pgd_lock, flags);
461 } else {
462 base = list_first_entry(&page_pool, struct page, lru);
463 list_del(&base->lru);
464 pool_pages--;
465
466 if (pool_pages < pool_low)
467 pool_low = pool_pages;
444 } 468 }
445 469
446 base = list_first_entry(&page_pool, struct page, lru);
447 list_del(&base->lru);
448 pool_pages--;
449
450 if (pool_pages < pool_low)
451 pool_low = pool_pages;
452
453 /* 470 /*
454 * Check for races, another CPU might have split this page 471 * Check for races, another CPU might have split this page
455 * up for us already: 472 * up for us already:
@@ -734,7 +751,8 @@ static int change_page_attr_set_clr(unsigned long addr, int numpages,
734 cpa_flush_all(cache); 751 cpa_flush_all(cache);
735 752
736out: 753out:
737 cpa_fill_pool(); 754 cpa_fill_pool(NULL);
755
738 return ret; 756 return ret;
739} 757}
740 758
@@ -897,7 +915,7 @@ void kernel_map_pages(struct page *page, int numpages, int enable)
897 * Try to refill the page pool here. We can do this only after 915 * Try to refill the page pool here. We can do this only after
898 * the tlb flush. 916 * the tlb flush.
899 */ 917 */
900 cpa_fill_pool(); 918 cpa_fill_pool(NULL);
901} 919}
902 920
903#ifdef CONFIG_HIBERNATION 921#ifdef CONFIG_HIBERNATION
diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c
index 73aba7125203..2f9e9afcb9f4 100644
--- a/arch/x86/mm/pgtable_32.c
+++ b/arch/x86/mm/pgtable_32.c
@@ -342,12 +342,16 @@ static void pgd_mop_up_pmds(struct mm_struct *mm, pgd_t *pgdp)
342 342
343pgd_t *pgd_alloc(struct mm_struct *mm) 343pgd_t *pgd_alloc(struct mm_struct *mm)
344{ 344{
345 pgd_t *pgd = quicklist_alloc(0, GFP_KERNEL, pgd_ctor); 345 pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
346 346
347 mm->pgd = pgd; /* so that alloc_pd can use it */ 347 /* so that alloc_pd can use it */
348 mm->pgd = pgd;
349 if (pgd)
350 pgd_ctor(pgd);
348 351
349 if (pgd && !pgd_prepopulate_pmd(mm, pgd)) { 352 if (pgd && !pgd_prepopulate_pmd(mm, pgd)) {
350 quicklist_free(0, pgd_dtor, pgd); 353 pgd_dtor(pgd);
354 free_page((unsigned long)pgd);
351 pgd = NULL; 355 pgd = NULL;
352 } 356 }
353 357
@@ -357,12 +361,8 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
357void pgd_free(struct mm_struct *mm, pgd_t *pgd) 361void pgd_free(struct mm_struct *mm, pgd_t *pgd)
358{ 362{
359 pgd_mop_up_pmds(mm, pgd); 363 pgd_mop_up_pmds(mm, pgd);
360 quicklist_free(0, pgd_dtor, pgd); 364 pgd_dtor(pgd);
361} 365 free_page((unsigned long)pgd);
362
363void check_pgt_cache(void)
364{
365 quicklist_trim(0, pgd_dtor, 25, 16);
366} 366}
367 367
368void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte) 368void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte)