[Crash-utility] [RFC]Patch to add sparse memory support

David Wilder dwilder at us.ibm.com
Tue Mar 21 18:28:36 UTC 2006


David Anderson wrote:

> Olaf Hering wrote:
>
>> On Fri, Mar 17, David Wilder wrote:
>>
>>    
>>
>>>This patch add sparsemem support to crash.  Please comment.
>>>Per-node memory display functions (kmem -n) are not yet working
>>>for sparsemem kernels.  This will come in a later patch.  This patch 
>>>applies to 4.0-2.21.
>>>      
>>>
>>
>>This patch is incomplete.
>>
>>
>>missing defines for ia64, s390, s390x
>>pick some random numbers.
>>
>>---
>> defs.h |   11 +++++++++++
>> 1 file changed, 11 insertions(+)
>>
>>Index: crash-4.0-2.18/defs.h
>>===================================================================
>>--- crash-4.0-2.18.orig/defs.h
>>+++ crash-4.0-2.18/defs.h
>>@@ -2024,6 +2024,7 @@ struct load_module {
>> #define KERNEL_CACHED_BASE    ((ulong)KERNEL_CACHED_REGION << REGION_SHIFT)
>> 
>> #define _SECTION_SIZE_BITS	30
>>+#define _MAX_PHYSADDR_BITS	50	/* FIXME */
>> #define _MAX_PHYSMEM_BITS	50
>> 
>> /*
>>@@ -2256,6 +2257,11 @@ struct efi_memory_desc_t {
>> 
>> #define TIF_SIGPENDING (2)
>> 
>>+/* FIXME */
>>+#define _SECTION_SIZE_BITS	24
>>+#define _MAX_PHYSADDR_BITS	44
>>+#define _MAX_PHYSMEM_BITS	44
>>+
>> #endif  /* S390 */
>> 
>> #ifdef S390X
>>@@ -2276,6 +2282,11 @@ struct efi_memory_desc_t {
>> 
>> #define TIF_SIGPENDING (2)<
>>br> 
>>+/* FIXME */
>>+#define _SECTION_SIZE_BITS	24
>>+#define _MAX_PHYSADDR_BITS	44
>>+#define _MAX_PHYSMEM_BITS	44
>>+
>> #endif  /* S390X */
>> 
>> #ifdef PLATFORM
>>
>>--
>>Crash-utility mailing list
>>Crash-utility at redhat.com
>>https://www.redhat.com/mailman/listinfo/crash-utility
>>    
>>
> Probably ought to add some alpha processor #defines to keep that arch
> building as well.
>
> Hmmm -- for that matter, I don't see the _MAX_PHYSADDR_BITS being used
> anywhere other than setting each per-processor 
> machdep->max_physaddr_bits(),
> and by extension, in the MAX_PHYSADDR_BITS() macro.  But that macro 
> doesn't
> get used anywhere?  Also, none of the *_PAE additions get used.
>
> Dave
>
>
>
>
>
>
>------------------------------------------------------------------------
>
>--
>Crash-utility mailing list
>Crash-utility at redhat.com
>https://www.redhat.com/mailman/listinfo/crash-utility
>  
>
Here is an updated patch.
ia64, s390, s390x and alpha do not support sparse mem (in the kernel) 
yet so I removed the references to those.  I added a check so if sparse 
mem support is later added for ia64, s390, s390x and alpha (and used), 
crash will print an error message.  I removed _MAX_PHYSADDR_BITS as it 
is not used anymore in the kernel. Lastly I fixed PAE additions for 
sparsemem.

diff -Naur crash-4.0-2.21/defs.h crash-4.0-2.21.sparse/defs.h
--- crash-4.0-2.21/defs.h    2006-02-14 14:40:02.000000000 -0800
+++ crash-4.0-2.21.sparse/defs.h    2006-03-20 13:45:48.000000000 -0800
@@ -663,6 +663,9 @@
     int ptrs_per_pgd;
     char *cmdline_arg;
     struct machine_specific *machspec;
+    ulong section_size_bits;
+    ulong max_physmem_bits;
+    ulong sections_per_root;
 };
 
 /*
@@ -1230,6 +1233,7 @@
     long x8664_pda_cpunumber;
     long x8664_pda_me;
     long tss_struct_ist;
+    long mem_section_section_mem_map;
 };
 
 struct size_table {         /* stash of commonly-used sizes */
@@ -1464,6 +1468,7 @@
         ulong cached_vma_hits[VMA_CACHE];
         int vma_cache_index;
         ulong vma_cache_fills;
+    void *mem_sec;
 };
 
 #define NODES                (0x1)
@@ -1474,7 +1479,15 @@
 #define V_MEM_MAP           (0x20)
 #define PERCPU_KMALLOC_V2   (0x40)
 #define KMEM_CACHE_UNAVAIL  (0x80)
-#define DISCONTIGMEM       (0x100)
+#define FLATMEM            (0x100)
+#define DISCONTIGMEM        (0x200)
+#define SPARSEMEM        (0x400)
+#define SPARSEMEM_EX        (0x800)
+
+#define IS_FLATMEM()        (vt->flags & FLATMEM)
+#define IS_DISCONTIGMEM()    (vt->flags & DISCONTIGMEM)
+#define IS_SPARSEMEM()        (vt->flags & SPARSEMEM)
+#define IS_SPARSEMEM_EX()    (vt->flags & SPARSEMEM_EX)
 
 #define COMMON_VADDR_SPACE() (vt->flags & COMMON_VADDR)
 #define PADDR_PRLEN          (vt->paddr_prlen)
@@ -1703,6 +1716,33 @@
 #define VIRTPAGEBASE(X)  (((ulong)(X)) & (ulong)machdep->pagemask)
 #define PHYSPAGEBASE(X)  (((physaddr_t)(X)) & 
(physaddr_t)machdep->pagemask)
 
+/*
+ * Sparse memory stuff
+ *  These must follow the definitions in the kernel mmzone.h
+ */
+#define SECTION_SIZE_BITS()    (machdep->section_size_bits)
+#define MAX_PHYSMEM_BITS()    (machdep->max_physmem_bits)
+#define SECTIONS_SHIFT()    (MAX_PHYSMEM_BITS() - SECTION_SIZE_BITS())
+#define PA_SECTION_SHIFT()    (SECTION_SIZE_BITS())
+#define PFN_SECTION_SHIFT()    (SECTION_SIZE_BITS() - PAGESHIFT())
+#define NR_MEM_SECTIONS()    (1UL << SECTIONS_SHIFT())
+#define PAGES_PER_SECTION()    (1UL << PFN_SECTION_SHIFT())
+#define PAGE_SECTION_MASK()    (~(PAGES_PER_SECTION()-1))
+
+#define pfn_to_section_nr(pfn) ((pfn) >> PFN_SECTION_SHIFT())
+#define section_nr_to_pfn(sec) ((sec) << PFN_SECTION_SHIFT())
+
+#define SECTIONS_PER_ROOT()    (machdep->sections_per_root)
+
+/* CONFIG_SPARSEMEM_EXTREME */
+#define _SECTIONS_PER_ROOT_EXTREME()    (PAGESIZE() / 
STRUCT_SIZE("mem_section"))
+/* !CONFIG_SPARSEMEM_EXTREME */
+#define _SECTIONS_PER_ROOT()    (1)
+
+#define SECTION_NR_TO_ROOT(sec)    ((sec) / SECTIONS_PER_ROOT())
+#define NR_SECTION_ROOTS()    (NR_MEM_SECTIONS() / SECTIONS_PER_ROOT())
+#define SECTION_ROOT_MASK()    (SECTIONS_PER_ROOT() - 1)
+
 /*
  *  Machine specific stuff
  */
@@ -1747,6 +1787,14 @@
 
 #define TIF_SIGPENDING  (2)
 
+// CONFIG_X86_PAE
+#define _SECTION_SIZE_BITS_PAE    30
+#define _MAX_PHYSMEM_BITS_PAE    36
+
+// !CONFIG_X86_PAE  
+#define _SECTION_SIZE_BITS    26
+#define _MAX_PHYSMEM_BITS    32
+
 #endif  /* X86 */
 
 #ifdef X86_64
@@ -1861,6 +1909,9 @@
 #define VALID_LEVEL4_PGT_ADDR(X) \
     (((X) == VIRTPAGEBASE(X)) && IS_KVADDR(X) && !IS_VMALLOC_ADDR(X))
 
+#define _SECTION_SIZE_BITS    27
+#define _MAX_PHYSMEM_BITS    40
+
 #endif  /* X86_64 */
 
 #ifdef ALPHA
@@ -1939,6 +1990,9 @@
 
 #define TIF_SIGPENDING (2)
 
+#define _SECTION_SIZE_BITS    24
+#define _MAX_PHYSMEM_BITS    44
+
 #endif  /* PPC */
 
 #ifdef IA64
@@ -2168,6 +2222,9 @@
 #define STACK_FRAME_OVERHEAD            112
 #define EXCP_FRAME_MARKER               0x7265677368657265
 
+#define _SECTION_SIZE_BITS    24
+#define _MAX_PHYSMEM_BITS    44
+
 #endif /* PPC64 */
 
 #ifdef S390
diff -Naur crash-4.0-2.21/memory.c crash-4.0-2.21.sparse/memory.c
--- crash-4.0-2.21/memory.c    2006-02-14 14:40:02.000000000 -0800
+++ crash-4.0-2.21.sparse/memory.c    2006-03-20 14:24:23.000000000 -0800
@@ -132,8 +132,18 @@
 static void do_vm_flags(ulong);
 static void PG_reserved_flag_init(void);
 static ulong nr_blockdev_pages(void);
-
-
+void sparse_mem_init(void);
+void list_mem_sections(void);
+void sparse_dump_mem_map(void);
+ulong sparse_decode_mem_map(ulong, ulong);
+char *read_mem_section(ulong);
+ulong nr_to_section(ulong);
+int valid_section(ulong);
+int section_has_mem_map(ulong);
+ulong section_mem_map_addr(ulong);
+ulong valid_section_nr(ulong);
+void list_mem_sections(void);
+ulong pfn_to_map(ulong);
 
 /*
  *  Memory display modes specific to this file.
@@ -447,10 +457,17 @@
         error(FATAL, "no swapper_pg_dir or cpu_pgd symbols exist?\n");
 
     get_symbol_data("high_memory", sizeof(ulong), &vt->high_memory);
-    if (kernel_symbol_exists("mem_map"))
+
+    if (kernel_symbol_exists("mem_map")){
         get_symbol_data("mem_map", sizeof(char *), &vt->mem_map);
+        vt->flags |= FLATMEM;
+    } else if (kernel_symbol_exists("mem_section"))
+        vt->flags |= SPARSEMEM;
     else
         vt->flags |= DISCONTIGMEM;
+
+    sparse_mem_init();
+
     vt->vmalloc_start = machdep->vmalloc_start();
     if (IS_VMALLOC_ADDR(vt->mem_map))
         vt->flags |= V_MEM_MAP;
@@ -3480,9 +3497,9 @@
 static void
 dump_mem_map(struct meminfo *mi)
 {
-    long i, n;
+    long node;
     long total_pages;
-    int others, page_not_mapped, phys_not_mapped;
+    int others, page_not_mapped, phys_not_mapped, page_mapping;
     ulong pp, ppend;
     physaddr_t phys, physend;
     ulong tmp, reserved, shared, slabs;
@@ -3502,6 +3519,7 @@
     char buf4[BUFSIZE];
     char *page_cache;
     char *pcache;
+    ulong section, section_nr, nr_mem_sections, node_or_section_size;
 
     v22 = VALID_MEMBER(page_inode);  /* page.inode vs. page.mapping */
 
@@ -3589,22 +3607,63 @@
     done = FALSE;
     total_pages = 0;
 
-    for (n = 0; n < vt->numnodes; n++) {
+    if (IS_SPARSEMEM()){
+        nr_mem_sections = NR_MEM_SECTIONS();
+    }else{
+        nr_mem_sections = 1;
+    }
+
+    /* iterate over all possable section */
+    node = 0;
+        for (section_nr = 0; section_nr < nr_mem_sections ; section_nr++){
+
+
+        if (CRASHDEBUG(2))
+            printf("section_nr = %d\n",section_nr);
+
+        /* If we are looking up a spicific address jump directly
+           to the section with that page */
+        if (IS_SPARSEMEM() && mi->flags&ADDRESS_SPECIFIED){       
+            ulong pfn  = mi->spec_addr >> PAGESHIFT();
+            section_nr=pfn_to_section_nr(pfn);
+        }
+
+                if(IS_SPARSEMEM() && 
!(section=valid_section_nr(section_nr))){
+                        /*break;   on a real sparsemem system we need 
to check
+                   * every section as gaps may exist.  But this
+                   * can be slow.  If we know we dont have gaps
+                   * just stop validating sections when we
+                   * get to the end of the valid ones. 
+                   * In the future find a way to short circuit
+                   * this loop.
+                   */
+            continue;
+        }
+
         if (print_hdr) {
-            fprintf(fp, "%s%s", n ? "\n" : "", hdr);
+            fprintf(fp, "%s%s", node ? "\n" : "", hdr);
             print_hdr = FALSE;
         }
 
-        nt = &vt->node_table[n];
-        total_pages += nt->size;
-        pp = nt->mem_map;
-        phys = nt->start_paddr;
-        if ((vt->flags & V_MEM_MAP) && (vt->numnodes == 1))
-            node_size = vt->max_mapnr;
-        else
-            node_size = nt->size;
+next_node:
+        if (IS_SPARSEMEM()){
+            pp = section_mem_map_addr(section);
+            pp = sparse_decode_mem_map(pp,section_nr);
+            phys = section_nr*PAGES_PER_SECTION()*PAGESIZE();
+            node_or_section_size = PAGES_PER_SECTION();
+        }else{
+            nt = &vt->node_table[node];
+            total_pages += nt->size;
+            pp = nt->mem_map;
+            phys = nt->start_paddr;
+            if ((vt->flags & V_MEM_MAP) && (vt->numnodes == 1))
+                node_or_section_size = vt->max_mapnr;
+            else
+                node_or_section_size = nt->size;
+        }
 
-        for (i = 0; i < node_size;
+        ulong i;
+        for (i = 0; i < node_or_section_size;
              i++, pp += SIZE(page), phys += PAGESIZE()) {
 
             if ((i % PGMM_CACHED) == 0) {
@@ -3693,11 +3752,12 @@
                 }
                             continue;
                     }
+            page_mapping = VALID_MEMBER(page_mapping);
    
             if (v22) {
                 inode = ULONG(pcache + OFFSET(page_inode));
                 offset = ULONG(pcache + OFFSET(page_offset));
-            } else {
+            } else if (page_mapping) {
                 mapping = ULONG(pcache +
                     OFFSET(page_mapping));
                 index = ULONG(pcache + OFFSET(page_index));
@@ -3740,6 +3800,20 @@
                                         space(MINSPACE),
                     mkstring(buf4, 8, CENTER|RJUST, " "),
                                         " ");
+                else if (!page_mapping)
+                 fprintf(fp, "%s%s%s%s%s%s%s %2d ",
+                     mkstring(buf0, VADDR_PRLEN,
+                     LJUST|LONG_HEX, MKSTR(pp)),
+                     space(MINSPACE),
+                     mkstring(buf1, MAX(PADDR_PRLEN,
+                     strlen("PHYSICAL")),
+                     RJUST|LONGLONG_HEX, MKSTR(&phys)),
+                     space(MINSPACE),
+                     mkstring(buf3, VADDR_PRLEN,
+                     CENTER|RJUST, "-------"),
+                     space(MINSPACE),
+                     mkstring(buf4, 8, CENTER|RJUST, "-----"),
+                     count);
                 else
                                 fprintf(fp, "%s%s%s%s%s%s%8ld %2d ",
                     mkstring(buf0, VADDR_PRLEN,
@@ -3801,6 +3875,7 @@
                 fprintf(fp, "\n");
             } else if (THIS_KERNEL_VERSION > LINUX(2,4,9)) {
                 fprintf(fp, "%lx\n", flags);
+                node=node;
             } else {
    
                         if ((flags >> v24_PG_locked) & 1)
@@ -3864,9 +3939,12 @@
             if (done)
                 break;
         }
-
         if (done)
             break;
+        node++;
+        if ( (node < vt->numnodes) && (!IS_SPARSEMEM())) {
+            goto next_node;
+        }
     }
 
     switch (mi->flags)
@@ -8904,6 +8982,16 @@
     physaddr_t pstart, pend;
     ulong node_size;
 
+    if (IS_SPARSEMEM()){
+        ulong map;
+        map = pfn_to_map(phys >> PAGESHIFT());
+        if ( map ){
+            *pp = map;
+            return TRUE;
+        }
+        return FALSE;
+    }
+
         for (n = 0; n < vt->numnodes; n++) {
                 nt = &vt->node_table[n];
                 if ((vt->flags & V_MEM_MAP) && (vt->numnodes == 1))
@@ -9009,8 +9097,12 @@
         fprintf(fp, "%sV_MEM_MAP", others++ ? "|" : "");
     if (vt->flags & KMEM_CACHE_UNAVAIL)
         fprintf(fp, "%sKMEM_CACHE_UNAVAIL", others++ ? "|" : "");
-    if (vt->flags & DISCONTIGMEM)
-        fprintf(fp, "%sDISCONTIGMEM", others++ ? "|" : "");
+    if (vt->flags & FLATMEM)
+        fprintf(fp, "%sFLATMEM", others++ ? "|" : "");
+    if (vt->flags & SPARSEMEM)
+        fprintf(fp, "%sSPARSEMEM", others++ ? "|" : "");\
+    if (vt->flags & SPARSEMEM_EX)
+        fprintf(fp, "%sSPARSEMEM_EX", others++ ? "|" : "");\
     fprintf(fp, ")\n");
     if (vt->kernel_pgd[0] == vt->kernel_pgd[1])
                fprintf(fp, "     kernel_pgd[NR_CPUS]: %lx ...\n",
@@ -10015,6 +10107,11 @@
     char buf5[BUFSIZE];
     struct node_table *nt;
 
+    if (IS_SPARSEMEM() && !initialize){
+        error(WARNING,"Per node memory data is not available for this 
kernel\n");
+        return;
+    }
+
         if (!(vt->flags & NODES)) {
         if (!initialize)
             error(FATAL,
@@ -10054,12 +10151,6 @@
                 "node_mem_map", FAULT_ON_ERROR);
         } else {
             node_mem_map = BADADDR;
-            if (!badaddr && initialize) {
-                error(INFO,
-           "pglist_data.node_mem_map structure member does not exist.\n");
-                error(INFO,
-       "certain memory-related commands will fail or display invalid 
data\n\n");
-            }
             badaddr = TRUE;
         }
 
@@ -10570,3 +10661,176 @@
     return retval;
 }
 
+
+/* Functions for sparse mem support */
+ulong sparse_decode_mem_map(ulong coded_mem_map, ulong section_nr)
+{
+        return coded_mem_map + 
(section_nr_to_pfn(section_nr)*STRUCT_SIZE("struct page"));
+}
+
+void
+sparse_mem_init(void)
+{
+    ulong addr;
+    ulong mem_section_size;
+
+    if (!IS_SPARSEMEM())
+        return;
+
+    if (!MAX_PHYSMEM_BITS())
+        error(FATAL, "Crash will not support CONFIG_SPARSEMEM for this 
architecture\n");
+       
+    if (get_array_length("mem_section", NULL, 0) ==
+         (NR_MEM_SECTIONS() / _SECTIONS_PER_ROOT_EXTREME()))
+        vt->flags |= SPARSEMEM_EX;
+
+
+    if (IS_SPARSEMEM_EX()){
+        machdep->sections_per_root = _SECTIONS_PER_ROOT_EXTREME();
+        mem_section_size = sizeof(void *)*NR_SECTION_ROOTS();
+    }else{
+        machdep->sections_per_root = _SECTIONS_PER_ROOT();
+        mem_section_size = STRUCT_SIZE("struct 
mem_section")*NR_SECTION_ROOTS();
+    }
+
+    if (CRASHDEBUG(1)){
+        fprintf(fp, "PAGESIZE=%d\n",PAGESIZE());
+        fprintf(fp,"mem_section_size = %d\n",mem_section_size);
+        fprintf(fp, "NR_SECTION_ROOTS=%d\n", NR_SECTION_ROOTS());
+        fprintf(fp, "NR_MEM_SECTIONS=%d\n",NR_MEM_SECTIONS());
+        fprintf(fp, "SECTIONS_PER_ROOT = %d\n",SECTIONS_PER_ROOT() );
+        fprintf(fp, "SECTION_ROOT_MASK=0x%x\n", SECTION_ROOT_MASK());
+        fprintf(fp, "PAGES_PER_SECTION=%d\n", PAGES_PER_SECTION());
+    }
+
+    if (!(vt->mem_sec = malloc(mem_section_size)))
+        error(FATAL, "cannot malloc mem_sec cache\n");
+
+    addr = symbol_value("mem_section");
+    readmem(addr, KVADDR,vt->mem_sec ,mem_section_size,
+            "memory section root table", FAULT_ON_ERROR);
+
+    MEMBER_OFFSET_INIT(mem_section_section_mem_map, 
"mem_section","section_mem_map");
+}
+
+char
+*read_mem_section(ulong addr)
+{
+    static char *mem_section;
+
+    if (!mem_section){
+        mem_section = GETBUF(STRUCT_SIZE("struct mem_section"));
+    }
+
+    if (!IS_KVADDR(addr))
+        return 0;
+   
+    readmem(addr,KVADDR,mem_section,STRUCT_SIZE("struct mem_section"),
+        "memory section", FAULT_ON_ERROR);
+
+    return mem_section;
+}
+
+ulong
+nr_to_section(ulong nr)
+{
+    ulong addr;
+
+    ulong *mem_sec = vt->mem_sec;
+    if (!IS_KVADDR(mem_sec[SECTION_NR_TO_ROOT(nr)]))
+        return 0;
+
+    if (IS_SPARSEMEM_EX())
+        addr=mem_sec[SECTION_NR_TO_ROOT(nr)] + (nr & 
SECTION_ROOT_MASK())* STRUCT_SIZE("struct mem_section");
+    else
+        addr=mem_sec[0] + (nr & SECTION_ROOT_MASK())* 
STRUCT_SIZE("struct mem_section");
+
+    if (!IS_KVADDR(addr))
+        return 0;
+
+    return addr;
+}
+
+/*
+ * We use the lower bits of the mem_map pointer to store
+ * a little bit of information.  There should be at least
+ * 3 bits here due to 32-bit alignment.
+ */
+#define SECTION_MARKED_PRESENT    (1UL<<0)
+#define SECTION_HAS_MEM_MAP    (1UL<<1)
+#define SECTION_MAP_LAST_BIT    (1UL<<2)
+#define SECTION_MAP_MASK    (~(SECTION_MAP_LAST_BIT-1))
+
+
+int valid_section(ulong addr)
+{
+    char *mem_section;
+
+    if ((mem_section = read_mem_section(addr)))
+            return (ULONG(mem_section+OFFSET(mem_section_section_mem_map))
+            && SECTION_MARKED_PRESENT);
+    return 0;
+}
+
+int section_has_mem_map(ulong addr)
+{
+    char *mem_section;
+
+    if ((mem_section = read_mem_section(addr)))
+        return (ULONG(mem_section+OFFSET(mem_section_section_mem_map))
+            && SECTION_HAS_MEM_MAP);
+    return 0;
+}
+
+ulong section_mem_map_addr(ulong addr)
+{  
+    char *mem_section;
+    ulong map;
+
+    if ((mem_section = read_mem_section(addr))){
+        map = ULONG(mem_section+OFFSET(mem_section_section_mem_map));
+        map &= SECTION_MAP_MASK;
+        return map;
+    }
+    return 0;
+}
+
+
+ulong valid_section_nr(ulong nr)
+{
+    ulong addr = nr_to_section(nr);
+    if(valid_section(addr))
+        return addr;
+    return 0;
+}
+
+ulong pfn_to_map(ulong pfn)
+{
+    ulong section, page_offset;
+
+    section=pfn_to_section_nr(pfn);
+    if (section_has_mem_map(section)){
+        page_offset = pfn - section_nr_to_pfn(section);
+        return(section_mem_map_addr(section) + (page_offset*PAGESIZE()));
+    }
+    return 0;
+}
+
+void list_mem_sections(void)
+{
+    ulong nr,addr;
+    ulong nr_mem_sections = NR_MEM_SECTIONS();
+    ulong coded_mem_map;
+
+    for (nr = 0; nr <= nr_mem_sections ; nr++){
+        if( (addr=valid_section_nr(nr)) ){
+            coded_mem_map=section_mem_map_addr(addr);
+            fprintf(fp,"nr=%d section = %llx coded_mem_map=%lx pfn=%d 
mem_map=%lx\n",
+            nr,
+            addr,
+            coded_mem_map,
+            section_nr_to_pfn(nr),
+            sparse_decode_mem_map(coded_mem_map,nr));
+        }
+    }
+}
diff -Naur crash-4.0-2.21/ppc64.c crash-4.0-2.21.sparse/ppc64.c
--- crash-4.0-2.21/ppc64.c    2006-02-14 14:40:02.000000000 -0800
+++ crash-4.0-2.21.sparse/ppc64.c    2006-03-20 09:26:06.000000000 -0800
@@ -162,7 +162,8 @@
             m->l3_shift = m->l2_shift + m->l2_index_size;
             m->l4_shift = m->l3_shift + m->l3_index_size;
         }
-
+        machdep->section_size_bits = _SECTION_SIZE_BITS;
+        machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
         ppc64_paca_init();
         machdep->vmalloc_start = ppc64_vmalloc_start;
         MEMBER_OFFSET_INIT(thread_struct_pg_tables,
diff -Naur crash-4.0-2.21/ppc.c crash-4.0-2.21.sparse/ppc.c
--- crash-4.0-2.21/ppc.c    2006-02-14 14:40:02.000000000 -0800
+++ crash-4.0-2.21.sparse/ppc.c    2006-03-20 09:28:40.000000000 -0800
@@ -138,6 +138,8 @@
         machdep->hz = HZ;
         if (THIS_KERNEL_VERSION >= LINUX(2,6,0))
             machdep->hz = 1000;
+        machdep->section_size_bits = _SECTION_SIZE_BITS;
+        machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
         break;
 
     case POST_INIT:
diff -Naur crash-4.0-2.21/x86_64.c crash-4.0-2.21.sparse/x86_64.c
--- crash-4.0-2.21/x86_64.c    2006-02-14 14:40:02.000000000 -0800
+++ crash-4.0-2.21.sparse/x86_64.c    2006-03-20 09:27:37.000000000 -0800
@@ -211,6 +211,8 @@
         machdep->hz = HZ;
         if (THIS_KERNEL_VERSION >= LINUX(2,6,0))
             machdep->hz = 1000;
+        machdep->section_size_bits = _SECTION_SIZE_BITS;
+        machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
         break;
 
     case POST_INIT:
diff -Naur crash-4.0-2.21/x86.c crash-4.0-2.21.sparse/x86.c
--- crash-4.0-2.21/x86.c    2006-02-14 14:40:02.000000000 -0800
+++ crash-4.0-2.21.sparse/x86.c    2006-03-20 14:35:30.000000000 -0800
@@ -1741,6 +1741,13 @@
         machdep->hz = HZ;
         if (THIS_KERNEL_VERSION >= LINUX(2,6,0))
             machdep->hz = 1000;
+        if (machdep->flags & PAE){
+            machdep->section_size_bits = _SECTION_SIZE_BITS_PAE;
+            machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_PAE;
+        } else {
+            machdep->section_size_bits = _SECTION_SIZE_BITS;
+            machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
+        }
         break;
 
     case POST_INIT:
-- 

David Wilder
IBM Linux Technology Center
Beaverton, Oregon, USA 
dwilder at us.ibm.com
(503)578-3789




More information about the Crash-utility mailing list