diff options
Diffstat (limited to 'arch/tile/mm/init.c')
-rw-r--r-- | arch/tile/mm/init.c | 99 |
1 files changed, 51 insertions, 48 deletions
diff --git a/arch/tile/mm/init.c b/arch/tile/mm/init.c index 125ac53b60fc..d89c9eacd162 100644 --- a/arch/tile/mm/init.c +++ b/arch/tile/mm/init.c | |||
@@ -67,7 +67,9 @@ | |||
67 | 67 | ||
68 | #define clear_pgd(pmdptr) (*(pmdptr) = hv_pte(0)) | 68 | #define clear_pgd(pmdptr) (*(pmdptr) = hv_pte(0)) |
69 | 69 | ||
70 | #ifndef __tilegx__ | ||
70 | unsigned long VMALLOC_RESERVE = CONFIG_VMALLOC_RESERVE; | 71 | unsigned long VMALLOC_RESERVE = CONFIG_VMALLOC_RESERVE; |
72 | #endif | ||
71 | 73 | ||
72 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); | 74 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); |
73 | 75 | ||
@@ -282,9 +284,9 @@ static pgprot_t __init init_pgprot(ulong address) | |||
282 | /* | 284 | /* |
283 | * Everything else that isn't data or bss is heap, so mark it | 285 | * Everything else that isn't data or bss is heap, so mark it |
284 | * with the initial heap home (hash-for-home, or this cpu). This | 286 | * with the initial heap home (hash-for-home, or this cpu). This |
285 | * includes any addresses after the loaded image; any address before | 287 | * includes any addresses after the loaded image and any address before |
286 | * _einittext (since we already captured the case of text before | 288 | * _einitdata, since we already captured the case of text before |
287 | * _sinittext); and any init-data pages. | 289 | * _sinittext, and __pa(einittext) is approximately __pa(sinitdata). |
288 | * | 290 | * |
289 | * All the LOWMEM pages that we mark this way will get their | 291 | * All the LOWMEM pages that we mark this way will get their |
290 | * struct page homecache properly marked later, in set_page_homes(). | 292 | * struct page homecache properly marked later, in set_page_homes(). |
@@ -292,9 +294,7 @@ static pgprot_t __init init_pgprot(ulong address) | |||
292 | * homes, but with a zero free_time we don't have to actually | 294 | * homes, but with a zero free_time we don't have to actually |
293 | * do a flush action the first time we use them, either. | 295 | * do a flush action the first time we use them, either. |
294 | */ | 296 | */ |
295 | if (address >= (ulong) _end || address < (ulong) _sdata || | 297 | if (address >= (ulong) _end || address < (ulong) _einitdata) |
296 | (address >= (ulong) _sinitdata && | ||
297 | address < (ulong) _einitdata)) | ||
298 | return construct_pgprot(PAGE_KERNEL, initial_heap_home()); | 298 | return construct_pgprot(PAGE_KERNEL, initial_heap_home()); |
299 | 299 | ||
300 | #if CHIP_HAS_CBOX_HOME_MAP() | 300 | #if CHIP_HAS_CBOX_HOME_MAP() |
@@ -304,35 +304,38 @@ static pgprot_t __init init_pgprot(ulong address) | |||
304 | #endif | 304 | #endif |
305 | 305 | ||
306 | /* | 306 | /* |
307 | * Make the w1data homed like heap to start with, to avoid | ||
308 | * making it part of the page-striped data area when we're just | ||
309 | * going to convert it to read-only soon anyway. | ||
310 | */ | ||
311 | if (address >= (ulong)__w1data_begin && address < (ulong)__w1data_end) | ||
312 | return construct_pgprot(PAGE_KERNEL, initial_heap_home()); | ||
313 | |||
314 | /* | ||
307 | * Otherwise we just hand out consecutive cpus. To avoid | 315 | * Otherwise we just hand out consecutive cpus. To avoid |
308 | * requiring this function to hold state, we just walk forward from | 316 | * requiring this function to hold state, we just walk forward from |
309 | * _sdata by PAGE_SIZE, skipping the readonly and init data, to reach | 317 | * _sdata by PAGE_SIZE, skipping the readonly and init data, to reach |
310 | * the requested address, while walking cpu home around kdata_mask. | 318 | * the requested address, while walking cpu home around kdata_mask. |
311 | * This is typically no more than a dozen or so iterations. | 319 | * This is typically no more than a dozen or so iterations. |
312 | */ | 320 | */ |
313 | BUG_ON(_einitdata != __bss_start); | 321 | page = (((ulong)__w1data_end) + PAGE_SIZE - 1) & PAGE_MASK; |
314 | for (page = (ulong)_sdata, cpu = NR_CPUS; ; ) { | 322 | BUG_ON(address < page || address >= (ulong)_end); |
315 | cpu = cpumask_next(cpu, &kdata_mask); | 323 | cpu = cpumask_first(&kdata_mask); |
316 | if (cpu == NR_CPUS) | 324 | for (; page < address; page += PAGE_SIZE) { |
317 | cpu = cpumask_first(&kdata_mask); | 325 | if (page >= (ulong)&init_thread_union && |
318 | if (page >= address) | 326 | page < (ulong)&init_thread_union + THREAD_SIZE) |
319 | break; | 327 | continue; |
320 | page += PAGE_SIZE; | ||
321 | if (page == (ulong)__start_rodata) | ||
322 | page = (ulong)__end_rodata; | ||
323 | if (page == (ulong)&init_thread_union) | ||
324 | page += THREAD_SIZE; | ||
325 | if (page == (ulong)_sinitdata) | ||
326 | page = (ulong)_einitdata; | ||
327 | if (page == (ulong)empty_zero_page) | 328 | if (page == (ulong)empty_zero_page) |
328 | page += PAGE_SIZE; | 329 | continue; |
329 | #ifndef __tilegx__ | 330 | #ifndef __tilegx__ |
330 | #if !ATOMIC_LOCKS_FOUND_VIA_TABLE() | 331 | #if !ATOMIC_LOCKS_FOUND_VIA_TABLE() |
331 | if (page == (ulong)atomic_locks) | 332 | if (page == (ulong)atomic_locks) |
332 | page += PAGE_SIZE; | 333 | continue; |
333 | #endif | 334 | #endif |
334 | #endif | 335 | #endif |
335 | 336 | cpu = cpumask_next(cpu, &kdata_mask); | |
337 | if (cpu == NR_CPUS) | ||
338 | cpu = cpumask_first(&kdata_mask); | ||
336 | } | 339 | } |
337 | return construct_pgprot(PAGE_KERNEL, cpu); | 340 | return construct_pgprot(PAGE_KERNEL, cpu); |
338 | } | 341 | } |
@@ -362,7 +365,7 @@ static int __init setup_ktext(char *str) | |||
362 | /* If you have a leading "nocache", turn off ktext caching */ | 365 | /* If you have a leading "nocache", turn off ktext caching */ |
363 | if (strncmp(str, "nocache", 7) == 0) { | 366 | if (strncmp(str, "nocache", 7) == 0) { |
364 | ktext_nocache = 1; | 367 | ktext_nocache = 1; |
365 | printk("ktext: disabling local caching of kernel text\n"); | 368 | pr_info("ktext: disabling local caching of kernel text\n"); |
366 | str += 7; | 369 | str += 7; |
367 | if (*str == ',') | 370 | if (*str == ',') |
368 | ++str; | 371 | ++str; |
@@ -374,20 +377,20 @@ static int __init setup_ktext(char *str) | |||
374 | 377 | ||
375 | /* Default setting on Tile64: use a huge page */ | 378 | /* Default setting on Tile64: use a huge page */ |
376 | if (strcmp(str, "huge") == 0) | 379 | if (strcmp(str, "huge") == 0) |
377 | printk("ktext: using one huge locally cached page\n"); | 380 | pr_info("ktext: using one huge locally cached page\n"); |
378 | 381 | ||
379 | /* Pay TLB cost but get no cache benefit: cache small pages locally */ | 382 | /* Pay TLB cost but get no cache benefit: cache small pages locally */ |
380 | else if (strcmp(str, "local") == 0) { | 383 | else if (strcmp(str, "local") == 0) { |
381 | ktext_small = 1; | 384 | ktext_small = 1; |
382 | ktext_local = 1; | 385 | ktext_local = 1; |
383 | printk("ktext: using small pages with local caching\n"); | 386 | pr_info("ktext: using small pages with local caching\n"); |
384 | } | 387 | } |
385 | 388 | ||
386 | /* Neighborhood cache ktext pages on all cpus. */ | 389 | /* Neighborhood cache ktext pages on all cpus. */ |
387 | else if (strcmp(str, "all") == 0) { | 390 | else if (strcmp(str, "all") == 0) { |
388 | ktext_small = 1; | 391 | ktext_small = 1; |
389 | ktext_all = 1; | 392 | ktext_all = 1; |
390 | printk("ktext: using maximal caching neighborhood\n"); | 393 | pr_info("ktext: using maximal caching neighborhood\n"); |
391 | } | 394 | } |
392 | 395 | ||
393 | 396 | ||
@@ -397,10 +400,10 @@ static int __init setup_ktext(char *str) | |||
397 | cpulist_scnprintf(buf, sizeof(buf), &ktext_mask); | 400 | cpulist_scnprintf(buf, sizeof(buf), &ktext_mask); |
398 | if (cpumask_weight(&ktext_mask) > 1) { | 401 | if (cpumask_weight(&ktext_mask) > 1) { |
399 | ktext_small = 1; | 402 | ktext_small = 1; |
400 | printk("ktext: using caching neighborhood %s " | 403 | pr_info("ktext: using caching neighborhood %s " |
401 | "with small pages\n", buf); | 404 | "with small pages\n", buf); |
402 | } else { | 405 | } else { |
403 | printk("ktext: caching on cpu %s with one huge page\n", | 406 | pr_info("ktext: caching on cpu %s with one huge page\n", |
404 | buf); | 407 | buf); |
405 | } | 408 | } |
406 | } | 409 | } |
@@ -470,19 +473,19 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base) | |||
470 | 473 | ||
471 | #if CHIP_HAS_CBOX_HOME_MAP() | 474 | #if CHIP_HAS_CBOX_HOME_MAP() |
472 | if (ktext_arg_seen && ktext_hash) { | 475 | if (ktext_arg_seen && ktext_hash) { |
473 | printk("warning: \"ktext\" boot argument ignored" | 476 | pr_warning("warning: \"ktext\" boot argument ignored" |
474 | " if \"kcache_hash\" sets up text hash-for-home\n"); | 477 | " if \"kcache_hash\" sets up text hash-for-home\n"); |
475 | ktext_small = 0; | 478 | ktext_small = 0; |
476 | } | 479 | } |
477 | 480 | ||
478 | if (kdata_arg_seen && kdata_hash) { | 481 | if (kdata_arg_seen && kdata_hash) { |
479 | printk("warning: \"kdata\" boot argument ignored" | 482 | pr_warning("warning: \"kdata\" boot argument ignored" |
480 | " if \"kcache_hash\" sets up data hash-for-home\n"); | 483 | " if \"kcache_hash\" sets up data hash-for-home\n"); |
481 | } | 484 | } |
482 | 485 | ||
483 | if (kdata_huge && !hash_default) { | 486 | if (kdata_huge && !hash_default) { |
484 | printk("warning: disabling \"kdata=huge\"; requires" | 487 | pr_warning("warning: disabling \"kdata=huge\"; requires" |
485 | " kcache_hash=all or =allbutstack\n"); | 488 | " kcache_hash=all or =allbutstack\n"); |
486 | kdata_huge = 0; | 489 | kdata_huge = 0; |
487 | } | 490 | } |
488 | #endif | 491 | #endif |
@@ -556,11 +559,11 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base) | |||
556 | if (!cpumask_empty(&bad)) { | 559 | if (!cpumask_empty(&bad)) { |
557 | char buf[NR_CPUS * 5]; | 560 | char buf[NR_CPUS * 5]; |
558 | cpulist_scnprintf(buf, sizeof(buf), &bad); | 561 | cpulist_scnprintf(buf, sizeof(buf), &bad); |
559 | printk("ktext: not using unavailable cpus %s\n", buf); | 562 | pr_info("ktext: not using unavailable cpus %s\n", buf); |
560 | } | 563 | } |
561 | if (cpumask_empty(&ktext_mask)) { | 564 | if (cpumask_empty(&ktext_mask)) { |
562 | printk("ktext: no valid cpus; caching on %d.\n", | 565 | pr_warning("ktext: no valid cpus; caching on %d.\n", |
563 | smp_processor_id()); | 566 | smp_processor_id()); |
564 | cpumask_copy(&ktext_mask, | 567 | cpumask_copy(&ktext_mask, |
565 | cpumask_of(smp_processor_id())); | 568 | cpumask_of(smp_processor_id())); |
566 | } | 569 | } |
@@ -737,17 +740,18 @@ static void __init set_non_bootmem_pages_init(void) | |||
737 | for_each_zone(z) { | 740 | for_each_zone(z) { |
738 | unsigned long start, end; | 741 | unsigned long start, end; |
739 | int nid = z->zone_pgdat->node_id; | 742 | int nid = z->zone_pgdat->node_id; |
743 | int idx = zone_idx(z); | ||
740 | 744 | ||
741 | start = z->zone_start_pfn; | 745 | start = z->zone_start_pfn; |
742 | if (start == 0) | 746 | if (start == 0) |
743 | continue; /* bootmem */ | 747 | continue; /* bootmem */ |
744 | end = start + z->spanned_pages; | 748 | end = start + z->spanned_pages; |
745 | if (zone_idx(z) == ZONE_NORMAL) { | 749 | if (idx == ZONE_NORMAL) { |
746 | BUG_ON(start != node_start_pfn[nid]); | 750 | BUG_ON(start != node_start_pfn[nid]); |
747 | start = node_free_pfn[nid]; | 751 | start = node_free_pfn[nid]; |
748 | } | 752 | } |
749 | #ifdef CONFIG_HIGHMEM | 753 | #ifdef CONFIG_HIGHMEM |
750 | if (zone_idx(z) == ZONE_HIGHMEM) | 754 | if (idx == ZONE_HIGHMEM) |
751 | totalhigh_pages += z->spanned_pages; | 755 | totalhigh_pages += z->spanned_pages; |
752 | #endif | 756 | #endif |
753 | if (kdata_huge) { | 757 | if (kdata_huge) { |
@@ -841,9 +845,9 @@ void __init mem_init(void) | |||
841 | #ifdef CONFIG_HIGHMEM | 845 | #ifdef CONFIG_HIGHMEM |
842 | /* check that fixmap and pkmap do not overlap */ | 846 | /* check that fixmap and pkmap do not overlap */ |
843 | if (PKMAP_ADDR(LAST_PKMAP-1) >= FIXADDR_START) { | 847 | if (PKMAP_ADDR(LAST_PKMAP-1) >= FIXADDR_START) { |
844 | printk(KERN_ERR "fixmap and kmap areas overlap" | 848 | pr_err("fixmap and kmap areas overlap" |
845 | " - this will crash\n"); | 849 | " - this will crash\n"); |
846 | printk(KERN_ERR "pkstart: %lxh pkend: %lxh fixstart %lxh\n", | 850 | pr_err("pkstart: %lxh pkend: %lxh fixstart %lxh\n", |
847 | PKMAP_BASE, PKMAP_ADDR(LAST_PKMAP-1), | 851 | PKMAP_BASE, PKMAP_ADDR(LAST_PKMAP-1), |
848 | FIXADDR_START); | 852 | FIXADDR_START); |
849 | BUG(); | 853 | BUG(); |
@@ -863,7 +867,7 @@ void __init mem_init(void) | |||
863 | initsize = (unsigned long)&_einittext - (unsigned long)&_sinittext; | 867 | initsize = (unsigned long)&_einittext - (unsigned long)&_sinittext; |
864 | initsize += (unsigned long)&_einitdata - (unsigned long)&_sinitdata; | 868 | initsize += (unsigned long)&_einitdata - (unsigned long)&_sinitdata; |
865 | 869 | ||
866 | printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk data, %dk init, %ldk highmem)\n", | 870 | pr_info("Memory: %luk/%luk available (%dk kernel code, %dk data, %dk init, %ldk highmem)\n", |
867 | (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), | 871 | (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), |
868 | num_physpages << (PAGE_SHIFT-10), | 872 | num_physpages << (PAGE_SHIFT-10), |
869 | codesize >> 10, | 873 | codesize >> 10, |
@@ -968,7 +972,6 @@ static void mark_w1data_ro(void) | |||
968 | BUG_ON((addr & (PAGE_SIZE-1)) != 0); | 972 | BUG_ON((addr & (PAGE_SIZE-1)) != 0); |
969 | for (; addr <= (unsigned long)__w1data_end - 1; addr += PAGE_SIZE) { | 973 | for (; addr <= (unsigned long)__w1data_end - 1; addr += PAGE_SIZE) { |
970 | unsigned long pfn = kaddr_to_pfn((void *)addr); | 974 | unsigned long pfn = kaddr_to_pfn((void *)addr); |
971 | struct page *page = pfn_to_page(pfn); | ||
972 | pte_t *ptep = virt_to_pte(NULL, addr); | 975 | pte_t *ptep = virt_to_pte(NULL, addr); |
973 | BUG_ON(pte_huge(*ptep)); /* not relevant for kdata_huge */ | 976 | BUG_ON(pte_huge(*ptep)); /* not relevant for kdata_huge */ |
974 | set_pte_at(&init_mm, addr, ptep, pfn_pte(pfn, PAGE_KERNEL_RO)); | 977 | set_pte_at(&init_mm, addr, ptep, pfn_pte(pfn, PAGE_KERNEL_RO)); |
@@ -986,7 +989,7 @@ static long __write_once initfree = 1; | |||
986 | static int __init set_initfree(char *str) | 989 | static int __init set_initfree(char *str) |
987 | { | 990 | { |
988 | strict_strtol(str, 0, &initfree); | 991 | strict_strtol(str, 0, &initfree); |
989 | printk("initfree: %s free init pages\n", initfree ? "will" : "won't"); | 992 | pr_info("initfree: %s free init pages\n", initfree ? "will" : "won't"); |
990 | return 1; | 993 | return 1; |
991 | } | 994 | } |
992 | __setup("initfree=", set_initfree); | 995 | __setup("initfree=", set_initfree); |
@@ -996,8 +999,8 @@ static void free_init_pages(char *what, unsigned long begin, unsigned long end) | |||
996 | unsigned long addr = (unsigned long) begin; | 999 | unsigned long addr = (unsigned long) begin; |
997 | 1000 | ||
998 | if (kdata_huge && !initfree) { | 1001 | if (kdata_huge && !initfree) { |
999 | printk("Warning: ignoring initfree=0:" | 1002 | pr_warning("Warning: ignoring initfree=0:" |
1000 | " incompatible with kdata=huge\n"); | 1003 | " incompatible with kdata=huge\n"); |
1001 | initfree = 1; | 1004 | initfree = 1; |
1002 | } | 1005 | } |
1003 | end = (end + PAGE_SIZE - 1) & PAGE_MASK; | 1006 | end = (end + PAGE_SIZE - 1) & PAGE_MASK; |
@@ -1033,7 +1036,7 @@ static void free_init_pages(char *what, unsigned long begin, unsigned long end) | |||
1033 | free_page(addr); | 1036 | free_page(addr); |
1034 | totalram_pages++; | 1037 | totalram_pages++; |
1035 | } | 1038 | } |
1036 | printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); | 1039 | pr_info("Freeing %s: %ldk freed\n", what, (end - begin) >> 10); |
1037 | } | 1040 | } |
1038 | 1041 | ||
1039 | void free_initmem(void) | 1042 | void free_initmem(void) |