Messages in this thread Patch in this message |  | | Date | Mon, 6 May 2002 21:07:30 +0200 (CEST) | From | Roman Zippel <> | Subject | Re: Bug: Discontigmem virt_to_page() [Alpha,ARM,Mips64?] |
| |
Hi,
On Mon, 6 May 2002, Daniel Phillips wrote:
> I don't, I observed that in all known instances of config_discontigmem, that > linear relationship is preserved.
That's true, but m68k isn't using config_discontigmem. :)
> > There is little common code (and only during > > initialization), which assumes a direct mapping. I can send you the > > patches to fix this. > > I already have patches to do that, that is, config_nonlinear. I'm interested in > looking at your patches though, because we might as well give all the different > approaches a fair examination.
See below, the patch is almost complete: - the only other free_area_init_core() needs to be updated - the virt_to_page(phys_to_virt()) sequence could be replaced now with pfn_page()
> You're talking about your 68K solution with the loops that search through > memory regions? If so, I've already looked at it and understand it.
That's just how the virtual<->physical conversion is implemented.
> Or, if > it's a new approach, then naturally I'd be interested.
It's not really new, you only have to take care, that you don't iterate with the physical address over a pgdat, this is what the patch below fixes, the rest can be hidden in the arch macros and no special config options is needed.
bye, Roman
Index: mm/bootmem.c =================================================================== RCS file: /home/linux-m68k/cvsroot/linux/mm/bootmem.c,v retrieving revision 1.1.1.4 retrieving revision 1.5 diff -u -p -r1.1.1.4 -r1.5 --- mm/bootmem.c 11 Feb 2002 17:51:47 -0000 1.1.1.4 +++ mm/bootmem.c 11 Feb 2002 18:34:49 -0000 1.5 @@ -243,7 +243,7 @@ found: static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat) { - struct page *page = pgdat->node_mem_map; + struct page *page; bootmem_data_t *bdata = pgdat->bdata; unsigned long i, count, total = 0; unsigned long idx; @@ -256,21 +256,22 @@ static unsigned long __init free_all_boo map = bdata->node_bootmem_map; for (i = 0; i < idx; ) { unsigned long v = ~map[i / BITS_PER_LONG]; - if (v) { - unsigned long m; - for (m = 1; m && i < idx; m<<=1, page++, i++) { - if (v & m) { + unsigned long m; + if (!v) { + i+=BITS_PER_LONG; + continue; + } + for (m = 1; m && i < idx; m<<=1, i++) { + if (!(v & m)) + continue; + page = virt_to_page(phys_to_virt((i << PAGE_SHIFT) + + bdata->node_boot_start)); count++; ClearPageReserved(page); set_page_count(page, 1); __free_page(page); } } - } else { - i+=BITS_PER_LONG; - page+=BITS_PER_LONG; - } - } total += count; /* Index: mm/page_alloc.c =================================================================== RCS file: /home/linux-m68k/cvsroot/linux/mm/page_alloc.c,v retrieving revision 1.1.1.14 retrieving revision 1.17 diff -u -p -r1.1.1.14 -r1.17 --- mm/page_alloc.c 6 May 2002 08:52:16 -0000 1.1.1.14 +++ mm/page_alloc.c 6 May 2002 09:11:36 -0000 1.17 @@ -796,7 +796,7 @@ static inline unsigned long wait_table_b * - clear the memory bitmaps */ void __init free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap, - unsigned long *zones_size, unsigned long zone_start_paddr, + unsigned long *zones_size, unsigned long zone_start_vaddr, unsigned long *zholes_size, struct page *lmem_map) { unsigned long i, j; @@ -804,7 +804,7 @@ void __init free_area_init_core(int nid, unsigned long totalpages, offset, realtotalpages; const unsigned long zone_required_alignment = 1UL << (MAX_ORDER-1); - if (zone_start_paddr & ~PAGE_MASK) + if (zone_start_vaddr & ~PAGE_MASK) BUG(); totalpages = 0; @@ -837,7 +837,7 @@ void __init free_area_init_core(int nid, } *gmap = pgdat->node_mem_map = lmem_map; pgdat->node_size = totalpages; - pgdat->node_start_paddr = zone_start_paddr; + pgdat->node_start_paddr = __pa(zone_start_vaddr); pgdat->node_start_mapnr = (lmem_map - mem_map); pgdat->nr_zones = 0; @@ -889,9 +889,9 @@ void __init free_area_init_core(int nid, zone->zone_mem_map = mem_map + offset; zone->zone_start_mapnr = offset; - zone->zone_start_paddr = zone_start_paddr; + zone->zone_start_paddr = __pa(zone_start_vaddr); - if ((zone_start_paddr >> PAGE_SHIFT) & (zone_required_alignment-1)) + if ((zone_start_vaddr >> PAGE_SHIFT) & (zone_required_alignment-1)) printk("BUG: wrong zone alignment, it will crash\n"); /* @@ -906,8 +906,8 @@ void __init free_area_init_core(int nid, SetPageReserved(page); memlist_init(&page->list); if (j != ZONE_HIGHMEM) - set_page_address(page, __va(zone_start_paddr)); - zone_start_paddr += PAGE_SIZE; + set_page_address(page, zone_start_vaddr); + zone_start_vaddr += PAGE_SIZE; } offset += size; @@ -954,7 +954,7 @@ void __init free_area_init_core(int nid, void __init free_area_init(unsigned long *zones_size) { - free_area_init_core(0, &contig_page_data, &mem_map, zones_size, 0, 0, 0); + free_area_init_core(0, &contig_page_data, &mem_map, zones_size, PAGE_OFFSET, 0, 0); } static int __init setup_mem_frac(char *str)
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|  |