From 1bf1eba74ec14bc10966a8ddb23bc8deeb91facd Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Fri, 23 Jun 2006 13:15:55 -0600 Subject: [IA64] Format /proc/pal/*/version_info correctly /proc/pal/*/version_info is a bit confusing. HP firmware, at least, reports 07.31 instead of 0.7.31. Also, the comment is out of place; it's an internal detail about the implementation of ia64_pal_version. Since the 2.2 revision of the SDM still states that PAL_VERSION can be called in virtual mode, correct the comment to be more accurate. Signed-off-by: Matthew Wilcox Signed-off-by: Tony Luck --- arch/ia64/kernel/palinfo.c | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) (limited to 'arch/ia64') diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c index 3f5bac5..ce9f199 100644 --- a/arch/ia64/kernel/palinfo.c +++ b/arch/ia64/kernel/palinfo.c @@ -566,29 +566,23 @@ version_info(char *page) pal_version_u_t min_ver, cur_ver; char *p = page; - /* The PAL_VERSION call is advertised as being able to support - * both physical and virtual mode calls. This seems to be a documentation - * bug rather than firmware bug. In fact, it does only support physical mode. - * So now the code reflects this fact and the pal_version() has been updated - * accordingly. - */ - if (ia64_pal_version(&min_ver, &cur_ver) != 0) return 0; + if (ia64_pal_version(&min_ver, &cur_ver) != 0) + return 0; p += sprintf(p, "PAL_vendor : 0x%02x (min=0x%02x)\n" - "PAL_A : %x.%x.%x (min=%x.%x.%x)\n" - "PAL_B : %x.%x.%x (min=%x.%x.%x)\n", - cur_ver.pal_version_s.pv_pal_vendor, min_ver.pal_version_s.pv_pal_vendor, - - cur_ver.pal_version_s.pv_pal_a_model>>4, - cur_ver.pal_version_s.pv_pal_a_model&0xf, cur_ver.pal_version_s.pv_pal_a_rev, - min_ver.pal_version_s.pv_pal_a_model>>4, - min_ver.pal_version_s.pv_pal_a_model&0xf, min_ver.pal_version_s.pv_pal_a_rev, - - cur_ver.pal_version_s.pv_pal_b_model>>4, - cur_ver.pal_version_s.pv_pal_b_model&0xf, cur_ver.pal_version_s.pv_pal_b_rev, - min_ver.pal_version_s.pv_pal_b_model>>4, - min_ver.pal_version_s.pv_pal_b_model&0xf, min_ver.pal_version_s.pv_pal_b_rev); + "PAL_A : %02x.%02x (min=%02x.%02x)\n" + "PAL_B : %02x.%02x (min=%02x.%02x)\n", + cur_ver.pal_version_s.pv_pal_vendor, + min_ver.pal_version_s.pv_pal_vendor, + cur_ver.pal_version_s.pv_pal_a_model, + cur_ver.pal_version_s.pv_pal_a_rev, + min_ver.pal_version_s.pv_pal_a_model, + min_ver.pal_version_s.pv_pal_a_rev, + cur_ver.pal_version_s.pv_pal_b_model, + cur_ver.pal_version_s.pv_pal_b_rev, + min_ver.pal_version_s.pv_pal_b_model, + min_ver.pal_version_s.pv_pal_b_rev); return p - page; } -- cgit v1.1 From 4f2ef124b274baac80f64e290aa44e87a7753933 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Fri, 28 Jul 2006 13:20:23 -0700 Subject: [IA64] Fix breakage in simscsi.c arch/ia64/hp/sim/simscsi.c: In function `simscsi_sg_readwrite': arch/ia64/hp/sim/simscsi.c:154: error: structure has no member named `buffer' arch/ia64/hp/sim/simscsi.c: In function `simscsi_fillresult': arch/ia64/hp/sim/simscsi.c:247: error: structure has no member named `buffer' hch said: >Just change it to access the request_buffer member instead. buffer >and request_buffer have been synonymous 99% of the time, and a driver >never even wants to access buffer. Signed-off-by: Tony Luck --- arch/ia64/hp/sim/simscsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/ia64') diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c index a3fe975..8a4f0d0 100644 --- a/arch/ia64/hp/sim/simscsi.c +++ b/arch/ia64/hp/sim/simscsi.c @@ -151,7 +151,7 @@ static void simscsi_sg_readwrite (struct scsi_cmnd *sc, int mode, unsigned long offset) { int list_len = sc->use_sg; - struct scatterlist *sl = (struct scatterlist *)sc->buffer; + struct scatterlist *sl = (struct scatterlist *)sc->request_buffer; struct disk_stat stat; struct disk_req req; @@ -244,7 +244,7 @@ static void simscsi_fillresult(struct scsi_cmnd *sc, char *buf, unsigned len) if (scatterlen == 0) memcpy(sc->request_buffer, buf, len); - else for (slp = (struct scatterlist *)sc->buffer; scatterlen-- > 0 && len > 0; slp++) { + else for (slp = (struct scatterlist *)sc->request_buffer; scatterlen-- > 0 && len > 0; slp++) { unsigned thislen = min(len, slp->length); memcpy(page_address(slp->page) + slp->offset, buf, thislen); -- cgit v1.1 From e037cda559547e6353c5a792802963572d0b750e Mon Sep 17 00:00:00 2001 From: Keith Owens Date: Mon, 17 Jul 2006 15:41:59 +1000 Subject: [IA64] sparse cleanups Fix some sparse warnings on ia64. Large constants that should be long instead of int. Use NULL instead of 0. Add some missing __iomem casts. Replace a non-C99 structure assignment. Signed-off-by: Keith Owens Signed-off-by: Tony Luck --- arch/ia64/kernel/efi.c | 6 +++--- arch/ia64/mm/ioremap.c | 6 +++--- arch/ia64/sn/kernel/xpc_main.c | 2 +- arch/ia64/sn/pci/tioce_provider.c | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'arch/ia64') diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index e4bfa9d..bb8770a 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -632,7 +632,7 @@ kern_memory_descriptor (unsigned long phys_addr) if (phys_addr - md->start < (md->num_pages << EFI_PAGE_SHIFT)) return md; } - return 0; + return NULL; } static efi_memory_desc_t * @@ -652,7 +652,7 @@ efi_memory_descriptor (unsigned long phys_addr) if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT)) return md; } - return 0; + return NULL; } u32 @@ -923,7 +923,7 @@ find_memmap_space (void) void efi_memmap_init(unsigned long *s, unsigned long *e) { - struct kern_memdesc *k, *prev = 0; + struct kern_memdesc *k, *prev = NULL; u64 contig_low=0, contig_high=0; u64 as, ae, lim; void *efi_map_start, *efi_map_end, *p, *q; diff --git a/arch/ia64/mm/ioremap.c b/arch/ia64/mm/ioremap.c index 07bd02b..4280c07 100644 --- a/arch/ia64/mm/ioremap.c +++ b/arch/ia64/mm/ioremap.c @@ -32,7 +32,7 @@ ioremap (unsigned long offset, unsigned long size) */ attr = kern_mem_attribute(offset, size); if (attr & EFI_MEMORY_WB) - return phys_to_virt(offset); + return (void __iomem *) phys_to_virt(offset); else if (attr & EFI_MEMORY_UC) return __ioremap(offset, size); @@ -43,7 +43,7 @@ ioremap (unsigned long offset, unsigned long size) gran_base = GRANULEROUNDDOWN(offset); gran_size = GRANULEROUNDUP(offset + size) - gran_base; if (efi_mem_attribute(gran_base, gran_size) & EFI_MEMORY_WB) - return phys_to_virt(offset); + return (void __iomem *) phys_to_virt(offset); return __ioremap(offset, size); } @@ -53,7 +53,7 @@ void __iomem * ioremap_nocache (unsigned long offset, unsigned long size) { if (kern_mem_attribute(offset, size) & EFI_MEMORY_WB) - return 0; + return NULL; return __ioremap(offset, size); } diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c index 99b123a..5e8e59e 100644 --- a/arch/ia64/sn/kernel/xpc_main.c +++ b/arch/ia64/sn/kernel/xpc_main.c @@ -480,7 +480,7 @@ xpc_activating(void *__partid) partid_t partid = (u64) __partid; struct xpc_partition *part = &xpc_partitions[partid]; unsigned long irq_flags; - struct sched_param param = { sched_priority: MAX_RT_PRIO - 1 }; + struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 }; int ret; diff --git a/arch/ia64/sn/pci/tioce_provider.c b/arch/ia64/sn/pci/tioce_provider.c index 17cd342..af7171a 100644 --- a/arch/ia64/sn/pci/tioce_provider.c +++ b/arch/ia64/sn/pci/tioce_provider.c @@ -74,7 +74,7 @@ tioce_mmr_war_pre(struct tioce_kernel *kern, void *mmr_addr) else mmr_war_offset = 0x158; - readq_relaxed((void *)(mmr_base + mmr_war_offset)); + readq_relaxed((void __iomem *)(mmr_base + mmr_war_offset)); } } @@ -92,8 +92,8 @@ tioce_mmr_war_post(struct tioce_kernel *kern, void *mmr_addr) if (mmr_offset < 0x45000) { if (mmr_offset == 0x100) - readq_relaxed((void *)(mmr_base + 0x38)); - readq_relaxed((void *)(mmr_base + 0xb050)); + readq_relaxed((void __iomem *)(mmr_base + 0x38)); + readq_relaxed((void __iomem *)(mmr_base + 0xb050)); } } -- cgit v1.1 From acb15c85de57d81d773b6e4184b7cb143ce83eba Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Wed, 26 Jul 2006 07:26:51 +0800 Subject: [IA64] Do not assume output registers be reservered. We found an issue in pal.S. According to the software runtime SPEC, The caller's output registers do not need to be preserved for caller. The callee may reuse input registers for any other purpose within the procedure. in ia64_pal_call_phys_stacked, input registers are copied to output registers before call into ia64_switch_mode_phys, then used to call into PAL. This assumes output registers are preserved in ia64_switch_mode_phys, which may not be true. In this particular case, ia64_switch_mode_phys alloc a null frame , and mask off psr.i. If an interrupt comes at this small window, or an MCA comes inside the procedure, output registers maybe changed, then the pal call may got some staled input registers. This patch moves the copies from input to output after ia64_switch_mode_phys to follow the software runtime convention. It also removed some unused labels in ia64_pal_call_phys_stacked. Signed-off-by: Zou Nan hai Signed-off-by: Tony Luck --- arch/ia64/kernel/pal.S | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'arch/ia64') diff --git a/arch/ia64/kernel/pal.S b/arch/ia64/kernel/pal.S index 5018c7f..ebaf1e6 100644 --- a/arch/ia64/kernel/pal.S +++ b/arch/ia64/kernel/pal.S @@ -217,12 +217,7 @@ GLOBAL_ENTRY(ia64_pal_call_phys_stacked) .body ;; ld8 loc2 = [loc2] // loc2 <- entry point - mov out0 = in0 // first argument - mov out1 = in1 // copy arg2 - mov out2 = in2 // copy arg3 - mov out3 = in3 // copy arg3 - ;; - mov loc3 = psr // save psr + mov loc3 = psr // save psr ;; mov loc4=ar.rsc // save RSE configuration dep.z loc2=loc2,0,61 // convert pal entry point to physical @@ -236,18 +231,23 @@ GLOBAL_ENTRY(ia64_pal_call_phys_stacked) ;; andcm r16=loc3,r16 // removes bits to clear from psr br.call.sptk.many rp=ia64_switch_mode_phys -.ret6: + + mov out0 = in0 // first argument + mov out1 = in1 // copy arg2 + mov out2 = in2 // copy arg3 + mov out3 = in3 // copy arg3 mov loc5 = r19 mov loc6 = r20 + br.call.sptk.many rp=b7 // now make the call -.ret7: + mov ar.rsc=0 // put RSE in enforced lazy, LE mode mov r16=loc3 // r16= original psr mov r19=loc5 mov r20=loc6 br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode -.ret8: mov psr.l = loc3 // restore init PSR + mov psr.l = loc3 // restore init PSR mov ar.pfs = loc1 mov rp = loc0 ;; -- cgit v1.1 From e55ce456155813ca34e105d0e05306edad05cf6e Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Wed, 26 Jul 2006 07:36:40 +0800 Subject: [IA64] Don't alloc empty frame in ia64_switch_mode_phys I think ia64_switch_mode_phys and ia64_switch_mode_virt does not need to alloc an empty frame. An empty frame is required by loadrs but flushrs does not need that. Signed-off-by: Zou Nan hai Signed-off-by: Tony Luck --- arch/ia64/kernel/head.S | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch/ia64') diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S index 561b8f1..29236f0 100644 --- a/arch/ia64/kernel/head.S +++ b/arch/ia64/kernel/head.S @@ -853,7 +853,6 @@ END(__ia64_init_fpu) */ GLOBAL_ENTRY(ia64_switch_mode_phys) { - alloc r2=ar.pfs,0,0,0,0 rsm psr.i | psr.ic // disable interrupts and interrupt collection mov r15=ip } @@ -902,7 +901,6 @@ END(ia64_switch_mode_phys) */ GLOBAL_ENTRY(ia64_switch_mode_virt) { - alloc r2=ar.pfs,0,0,0,0 rsm psr.i | psr.ic // disable interrupts and interrupt collection mov r15=ip } -- cgit v1.1 From 0a69ca91be2b36f99a48daacd1f12d9d49ecaf87 Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Mon, 31 Jul 2006 09:12:11 -0400 Subject: [PATCH] Fix RAID5 + IA64 compile CONFIG_MD_RAID5 became CONFIG_MD_RAID456 in drivers/md/Kconfig. Make the same change in arch/ia64 Signed-off-by: Prarit Bhargava Signed-off-by: Aron Griffis Acked-by: Jes Sorenson Signed-off-by: Tony Luck --- arch/ia64/kernel/ia64_ksyms.c | 2 +- arch/ia64/lib/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/ia64') diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c index b7cf651..3ead20f 100644 --- a/arch/ia64/kernel/ia64_ksyms.c +++ b/arch/ia64/kernel/ia64_ksyms.c @@ -62,7 +62,7 @@ EXPORT_SYMBOL(__udivdi3); EXPORT_SYMBOL(__moddi3); EXPORT_SYMBOL(__umoddi3); -#if defined(CONFIG_MD_RAID5) || defined(CONFIG_MD_RAID5_MODULE) +#if defined(CONFIG_MD_RAID456) || defined(CONFIG_MD_RAID456_MODULE) extern void xor_ia64_2(void); extern void xor_ia64_3(void); extern void xor_ia64_4(void); diff --git a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile index d8536a2..38fa6e4 100644 --- a/arch/ia64/lib/Makefile +++ b/arch/ia64/lib/Makefile @@ -14,7 +14,7 @@ lib-y := __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \ lib-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o lib-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o lib-$(CONFIG_PERFMON) += carta_random.o -lib-$(CONFIG_MD_RAID5) += xor.o +lib-$(CONFIG_MD_RAID456) += xor.o AFLAGS___divdi3.o = AFLAGS___udivdi3.o = -DUNSIGNED -- cgit v1.1 From 921eea1cdf6ce7f0db88e4579474a04b1fb0fe6d Mon Sep 17 00:00:00 2001 From: Bob Picco Date: Wed, 28 Jun 2006 12:54:55 -0400 Subject: [IA64] align high endpoint of VIRTUAL_MEM_MAP Assure that vmem_map's high endpoint is MAX_ORDER aligned. Not doing so violates the buddy allocator algorithm. Also anyone using mem=XXX on boot line and not aligned to MAX_ORDER requires this patch in order to satisfy buddy allocator. vmem_map always starts at pfn 0. The potentially large MAX_ORDER on ia64 (due to hugetlbfs) requires that the end of vmem_map be aligned to MAX_ORDER_NR_PAGES. This was boot tested for: FLATMEM, FLATMEM+VIRTUAL_MEM_MAP, DISCONTIGMEM+VIRTUAL_MEM_MAP and SPARSEMEM. Signed-off-by: Bob Picco Signed-off-by: Tony Luck --- arch/ia64/mm/contig.c | 3 ++- arch/ia64/mm/discontig.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/ia64') diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c index 2a88cdd..8919fed 100644 --- a/arch/ia64/mm/contig.c +++ b/arch/ia64/mm/contig.c @@ -277,7 +277,8 @@ paging_init (void) /* allocate virtual_mem_map */ - map_size = PAGE_ALIGN(max_low_pfn * sizeof(struct page)); + map_size = PAGE_ALIGN(ALIGN(max_low_pfn, MAX_ORDER_NR_PAGES) * + sizeof(struct page)); vmalloc_end -= map_size; vmem_map = (struct page *) vmalloc_end; efi_memmap_walk(create_mem_map_page_table, NULL); diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index 99bd9e3..8eeb669 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c @@ -751,7 +751,8 @@ void __init paging_init(void) efi_memmap_walk(filter_rsvd_memory, count_node_pages); #ifdef CONFIG_VIRTUAL_MEM_MAP - vmalloc_end -= PAGE_ALIGN(max_low_pfn * sizeof(struct page)); + vmalloc_end -= PAGE_ALIGN(ALIGN(max_low_pfn, MAX_ORDER_NR_PAGES) * + sizeof(struct page)); vmem_map = (struct page *) vmalloc_end; efi_memmap_walk(create_mem_map_page_table, NULL); printk("Virtual mem_map starts at 0x%p\n", vmem_map); -- cgit v1.1 From e44e41d0c832ebbda7311a1fe43584d844026357 Mon Sep 17 00:00:00 2001 From: Bob Picco Date: Wed, 28 Jun 2006 12:55:43 -0400 Subject: [IA64] fix show_mem for VIRTUAL_MEM_MAP+FLATMEM contig.c (FLATMEM) requires the same optimization as in discontig.c for show_mem when VIRTUAL_MEM_MAP is in use. Otherwise FLATMEM has softlockup timeouts. This was boot tested for memory configuration: SPARSEMEM, DISCONTIG+VIRTUAL_MEM_MAP, FLATMEM, FLATMEM+VIRTUAL_MEM_MAP and FLATMEM+VIRTUAL_MEM_MAP with largest memory gap less than LARGE_GAP by using boot parameter "mem=". This was boot tested and "echo m >/proc/sysrq-trigger" output evaluated for : FLATMEM, FLATMEM+VIRTUAL_MEM_MAP, DISCONTIGMEM+VIRTUAL_MEM_MAP and SPARSEMEM. Signed-off-by: Bob Picco Signed-off-by: Tony Luck --- arch/ia64/mm/contig.c | 13 +++++++--- arch/ia64/mm/discontig.c | 65 ++---------------------------------------------- arch/ia64/mm/init.c | 55 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 67 deletions(-) (limited to 'arch/ia64') diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c index 8919fed..e004143 100644 --- a/arch/ia64/mm/contig.c +++ b/arch/ia64/mm/contig.c @@ -27,6 +27,7 @@ #ifdef CONFIG_VIRTUAL_MEM_MAP static unsigned long num_dma_physpages; +static unsigned long max_gap; #endif /** @@ -45,9 +46,15 @@ show_mem (void) printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; - while (i-- > 0) { - if (!pfn_valid(i)) + for (i = 0; i < max_mapnr; i++) { + if (!pfn_valid(i)) { +#ifdef CONFIG_VIRTUAL_MEM_MAP + if (max_gap < LARGE_GAP) + continue; + i = vmemmap_find_next_valid_pfn(0, i) - 1; +#endif continue; + } total++; if (PageReserved(mem_map+i)) reserved++; @@ -234,7 +241,6 @@ paging_init (void) unsigned long zones_size[MAX_NR_ZONES]; #ifdef CONFIG_VIRTUAL_MEM_MAP unsigned long zholes_size[MAX_NR_ZONES]; - unsigned long max_gap; #endif /* initialize mem_map[] */ @@ -266,7 +272,6 @@ paging_init (void) } } - max_gap = 0; efi_memmap_walk(find_largest_hole, (u64 *)&max_gap); if (max_gap < LARGE_GAP) { vmem_map = (struct page *) 0; diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index 8eeb669..d260bff 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c @@ -534,68 +534,6 @@ void __cpuinit *per_cpu_init(void) } #endif /* CONFIG_SMP */ -#ifdef CONFIG_VIRTUAL_MEM_MAP -static inline int find_next_valid_pfn_for_pgdat(pg_data_t *pgdat, int i) -{ - unsigned long end_address, hole_next_pfn; - unsigned long stop_address; - - end_address = (unsigned long) &vmem_map[pgdat->node_start_pfn + i]; - end_address = PAGE_ALIGN(end_address); - - stop_address = (unsigned long) &vmem_map[ - pgdat->node_start_pfn + pgdat->node_spanned_pages]; - - do { - pgd_t *pgd; - pud_t *pud; - pmd_t *pmd; - pte_t *pte; - - pgd = pgd_offset_k(end_address); - if (pgd_none(*pgd)) { - end_address += PGDIR_SIZE; - continue; - } - - pud = pud_offset(pgd, end_address); - if (pud_none(*pud)) { - end_address += PUD_SIZE; - continue; - } - - pmd = pmd_offset(pud, end_address); - if (pmd_none(*pmd)) { - end_address += PMD_SIZE; - continue; - } - - pte = pte_offset_kernel(pmd, end_address); -retry_pte: - if (pte_none(*pte)) { - end_address += PAGE_SIZE; - pte++; - if ((end_address < stop_address) && - (end_address != ALIGN(end_address, 1UL << PMD_SHIFT))) - goto retry_pte; - continue; - } - /* Found next valid vmem_map page */ - break; - } while (end_address < stop_address); - - end_address = min(end_address, stop_address); - end_address = end_address - (unsigned long) vmem_map + sizeof(struct page) - 1; - hole_next_pfn = end_address / sizeof(struct page); - return hole_next_pfn - pgdat->node_start_pfn; -} -#else -static inline int find_next_valid_pfn_for_pgdat(pg_data_t *pgdat, int i) -{ - return i + 1; -} -#endif - /** * show_mem - give short summary of memory stats * @@ -625,7 +563,8 @@ void show_mem(void) if (pfn_valid(pgdat->node_start_pfn + i)) page = pfn_to_page(pgdat->node_start_pfn + i); else { - i = find_next_valid_pfn_for_pgdat(pgdat, i) - 1; + i = vmemmap_find_next_valid_pfn(pgdat->node_id, + i) - 1; continue; } if (PageReserved(page)) diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 2f50c06..30617cc 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -415,6 +415,61 @@ ia64_mmu_init (void *my_cpu_data) } #ifdef CONFIG_VIRTUAL_MEM_MAP +int vmemmap_find_next_valid_pfn(int node, int i) +{ + unsigned long end_address, hole_next_pfn; + unsigned long stop_address; + pg_data_t *pgdat = NODE_DATA(node); + + end_address = (unsigned long) &vmem_map[pgdat->node_start_pfn + i]; + end_address = PAGE_ALIGN(end_address); + + stop_address = (unsigned long) &vmem_map[ + pgdat->node_start_pfn + pgdat->node_spanned_pages]; + + do { + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *pte; + + pgd = pgd_offset_k(end_address); + if (pgd_none(*pgd)) { + end_address += PGDIR_SIZE; + continue; + } + + pud = pud_offset(pgd, end_address); + if (pud_none(*pud)) { + end_address += PUD_SIZE; + continue; + } + + pmd = pmd_offset(pud, end_address); + if (pmd_none(*pmd)) { + end_address += PMD_SIZE; + continue; + } + + pte = pte_offset_kernel(pmd, end_address); +retry_pte: + if (pte_none(*pte)) { + end_address += PAGE_SIZE; + pte++; + if ((end_address < stop_address) && + (end_address != ALIGN(end_address, 1UL << PMD_SHIFT))) + goto retry_pte; + continue; + } + /* Found next valid vmem_map page */ + break; + } while (end_address < stop_address); + + end_address = min(end_address, stop_address); + end_address = end_address - (unsigned long) vmem_map + sizeof(struct page) - 1; + hole_next_pfn = end_address / sizeof(struct page); + return hole_next_pfn - pgdat->node_start_pfn; +} int __init create_mem_map_page_table (u64 start, u64 end, void *arg) -- cgit v1.1