Hi Russell, > -----Original Message----- > From: Russell King - ARM Linux [mailto:linux@xxxxxxxxxxxxxxxx] > Sent: Saturday, August 15, 2009 11:47 PM > To: Syed Mohammed, Khasim > Cc: linux-arm-kernel@xxxxxxxxxxxxxxxxxxxxxx; linux-omap@xxxxxxxxxxxxxxx > Subject: Re: Exception while handling MEM Hole on OMAP3 / ARM Cortex A8 > > On Sat, Aug 15, 2009 at 09:47:18PM +0530, Syed Mohammed, Khasim wrote: > > Backtrace: > > [<c002c884>] (__flush_dcache_page+0x0/0x3c) from [<c002c7c0>] (update_mmu_cache+ > > 0x8c/0xb0) > > [<c002c734>] (update_mmu_cache+0x0/0xb0) from [<c008611c>] (handle_mm_fault+0x53 > > 4/0x5ac) > > Bingo! > <snip> > The question is how best to handle determining if a PFN (which could be > somewhere in the range 0 to 0xfffff for 32-bit address space) is valid > without eating up too much memory. One simple way would be to allocate > a bitmap. That'll eat up 128K of memory though, and we know that we > normally have a small amount of that range used... I think a binary > search of the meminfo struct might be the best all-round solution. > > Could you try this patch please? > This patch seem to be working, I don't see any dump like before. Can you please advice on how to get this patch into kernel? I mean, will you be handling it or we need to re-submit them with your signed off? Please let me know if there are any corrections that you want me to test, I will be more happy to do the same. Thanks for all your help. Regards, Khasim > diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h > index 376be1a..cefedf0 100644 > --- a/arch/arm/include/asm/memory.h > +++ b/arch/arm/include/asm/memory.h > @@ -218,7 +218,6 @@ static inline __deprecated void *bus_to_virt(unsigned long x) > * > * page_to_pfn(page) convert a struct page * to a PFN number > * pfn_to_page(pfn) convert a _valid_ PFN number to struct page * > - * pfn_valid(pfn) indicates whether a PFN number is valid > * > * virt_to_page(k) convert a _valid_ virtual address to struct page * > * virt_addr_valid(k) indicates whether a virtual address is valid > @@ -227,10 +226,6 @@ static inline __deprecated void *bus_to_virt(unsigned long x) > > #define ARCH_PFN_OFFSET PHYS_PFN_OFFSET > > -#ifndef CONFIG_SPARSEMEM > -#define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr)) > -#endif > - > #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) > #define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) > < (unsigned long)high_memory) > > @@ -247,18 +242,6 @@ static inline __deprecated void *bus_to_virt(unsigned long x) > #define arch_pfn_to_nid(pfn) PFN_TO_NID(pfn) > #define arch_local_page_offset(pfn, nid) LOCAL_MAP_NR((pfn) << PAGE_SHIFT) > > -#define pfn_valid(pfn) \ > - ({ \ > - unsigned int nid = PFN_TO_NID(pfn); \ > - int valid = nid < MAX_NUMNODES; \ > - if (valid) { \ > - pg_data_t *node = NODE_DATA(nid); \ > - valid = (pfn - node->node_start_pfn) < \ > - node->node_spanned_pages; \ > - } \ > - valid; \ > - }) > - > #define virt_to_page(kaddr) \ > (ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr)) > > diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h > index 9c746af..3a32af4 100644 > --- a/arch/arm/include/asm/page.h > +++ b/arch/arm/include/asm/page.h > @@ -194,6 +194,10 @@ typedef unsigned long pgprot_t; > > typedef struct page *pgtable_t; > > +#ifndef CONFIG_SPARSEMEM > +extern int pfn_valid(unsigned long); > +#endif > + > #include <asm/memory.h> > > #endif /* !__ASSEMBLY__ */ > diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c > index 8277802..2542583 100644 > --- a/arch/arm/mm/init.c > +++ b/arch/arm/mm/init.c > @@ -15,6 +15,7 @@ > #include <linux/mman.h> > #include <linux/nodemask.h> > #include <linux/initrd.h> > +#include <linux/sort.h> > #include <linux/highmem.h> > > #include <asm/mach-types.h> > @@ -334,12 +335,42 @@ static void __init bootmem_free_node(int node, struct meminfo *mi) > free_area_init_node(node, zone_size, start_pfn, zhole_size); > } > > +#ifndef CONFIG_SPARSEMEM > +int pfn_valid(unsigned long pfn) > +{ > + struct meminfo *mi = &meminfo; > + unsigned int mid, left = 0, right = mi->nr_banks; > + > + while ((mid = (right - left) / 2) > 0) { > + struct membank *bank = &mi->bank[mid]; > + > + if (pfn < bank_pfn_start(bank)) > + right = mid; > + else if (pfn >= bank_pfn_end(bank)) > + left = mid + 1; > + else > + return 1; > + } > + return 0; > +} > +EXPORT_SYMBOL(pfn_valid); > +#endif > + > +static int __init meminfo_cmp(const void *_a, const void *_b) > +{ > + const struct membank *a = _a, *b = _b; > + long cmp = bank_pfn_start(b) - bank_pfn_start(a); > + return cmp < 0 ? -1 : cmp > 0 ? 1 : 0; > +} > + > void __init bootmem_init(void) > { > struct meminfo *mi = &meminfo; > unsigned long memend_pfn = 0; > int node, initrd_node; > > + sort(&mi->bank, mi->nr_banks, sizeof(mi->bank[0]), meminfo_cmp, NULL); > + > /* > * Locate which node contains the ramdisk image, if any. > */ > -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html