Skip to contentSkip to conversation

clean up mem_map usage ... part 1

PATCH Martin J. Bligh 3 participants 7 messages Aug 16, 2002 – Aug 17, 2002

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

This simply converts direct usage of mem_map to the correct macros (mem_map doesn't work like this for discontigmem). It also fixes a bug in bad_range, that happens to work for contig mem systems, but is incorrect. Tested both with and without discontigmem support.

please forward to Linus if you're happy with it .... applies on top of the i386 discontigmem patches.

M.

arch/i386/mm/init.c +3 -3
diff -urN 2.5.31-13-numa/arch/i386/mm/init.c 2.5.31-21-bad_range/arch/i386/mm/init.c
@@ -235,7 +235,7 @@
 {
 	int pfn;
 	for (pfn = highstart_pfn; pfn < highend_pfn; pfn++)
-		one_highpage_init((struct page *)(mem_map + pfn), pfn, bad_ppro);
+		one_highpage_init((struct page *)pfn_to_page(pfn), pfn, bad_ppro);
 	totalram_pages += totalhigh_pages;
 }
 #else
@@ -419,7 +419,7 @@
 static void __init set_max_mapnr_init(void)
 {
 #ifdef CONFIG_HIGHMEM
-	highmem_start_page = mem_map + highstart_pfn;
+	highmem_start_page = pfn_to_page(highstart_pfn);
 	max_mapnr = num_physpages = highend_pfn;
 #else
 	max_mapnr = num_physpages = max_low_pfn;
@@ -458,7 +458,7 @@
 		/*
 		 * Only count reserved RAM pages
 		 */
-		if (page_is_ram(tmp) && PageReserved(mem_map+tmp))
+		if (page_is_ram(tmp) && PageReserved(pfn_to_page(tmp)))
 			reservedpages++;
 
 	set_highmem_pages_init(bad_ppro);
arch/i386/mm/pgtable.c +10 -8
diff -urN 2.5.31-13-numa/arch/i386/mm/pgtable.c 2.5.31-21-bad_range/arch/i386/mm/pgtable.c
@@ -22,24 +22,26 @@
 
 void show_mem(void)
 {
-	int i, total = 0, reserved = 0;
+	int pfn, total = 0, reserved = 0;
 	int shared = 0, cached = 0;
 	int highmem = 0;
+	struct page *page;
 
 	printk("Mem-info:\n");
 	show_free_areas();
 	printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
-	i = max_mapnr;
-	while (i-- > 0) {
+	pfn = max_mapnr;
+	while (pfn-- > 0) {
+		page = pfn_to_page(pfn);
 		total++;
-		if (PageHighMem(mem_map+i))
+		if (PageHighMem(page))
 			highmem++;
-		if (PageReserved(mem_map+i))
+		if (PageReserved(page))
 			reserved++;
-		else if (PageSwapCache(mem_map+i))
+		else if (PageSwapCache(page))
 			cached++;
-		else if (page_count(mem_map+i))
-			shared += page_count(mem_map+i) - 1;
+		else if (page_count(page))
+			shared += page_count(page) - 1;
 	}
 	printk("%d pages of RAM\n", total);
 	printk("%d pages of HIGHMEM\n",highmem);
drivers/net/ns83820.c +1 -1
diff -urN 2.5.31-13-numa/drivers/net/ns83820.c 2.5.31-21-bad_range/drivers/net/ns83820.c
@@ -1081,7 +1081,7 @@
 				   frag->page_offset,
 				   frag->size, PCI_DMA_TODEVICE);
 		dprintk("frag: buf=%08Lx  page=%08lx offset=%08lx\n",
-			(long long)buf, (long)(frag->page - mem_map),
+			(long long)buf, (long) page_to_pfn(frag->page),
 			frag->page_offset);
 		len = frag->size;
 		frag++;
include/asm-i386/pci.h +2 -2
diff -urN 2.5.31-13-numa/include/asm-i386/pci.h 2.5.31-21-bad_range/include/asm-i386/pci.h
@@ -109,7 +109,7 @@
 	if (direction == PCI_DMA_NONE)
 		BUG();
 
-	return (dma_addr_t)(page - mem_map) * PAGE_SIZE + offset;
+	return (dma_addr_t)(page_to_pfn(page)) * PAGE_SIZE + offset;
 }
 
 static inline void pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
@@ -240,7 +240,7 @@
 {
 	unsigned long poff = (dma_addr >> PAGE_SHIFT);
 
-	return mem_map + poff;
+	return pfn_to_page(poff);
 }
 
 static __inline__ unsigned long
include/asm-i386/pgtable.h +1 -1
diff -urN 2.5.31-13-numa/include/asm-i386/pgtable.h 2.5.31-21-bad_range/include/asm-i386/pgtable.h
@@ -236,7 +236,7 @@
 
 #ifndef CONFIG_DISCONTIGMEM
 #define pmd_page(pmd) \
-	(mem_map + (pmd_val(pmd) >> PAGE_SHIFT))
+	(pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
 #endif /* !CONFIG_DISCONTIGMEM */
 
 #define pmd_large(pmd) \
kernel/suspend.c +15 -13
diff -urN 2.5.31-13-numa/kernel/suspend.c 2.5.31-21-bad_range/kernel/suspend.c
@@ -468,31 +468,33 @@
 {
 	int chunk_size;
 	int nr_copy_pages = 0;
-	int loop;
+	int pfn;
+	struct page *page;
 	
 	if (max_mapnr != num_physpages)
 		panic("mapnr is not expected");
-	for (loop = 0; loop < max_mapnr; loop++) {
-		if (PageHighMem(mem_map+loop))
+	for (pfn = 0; pfn < max_mapnr; pfn++) {
+		page = pfn_to_page(pfn);
+		if (PageHighMem(page))
 			panic("Swsusp not supported on highmem boxes. Send 1GB of RAM to <[email protected]> and try again ;-).");
-		if (!PageReserved(mem_map+loop)) {
-			if (PageNosave(mem_map+loop))
+		if (!PageReserved(page)) {
+			if (PageNosave(page))
 				continue;
 
-			if ((chunk_size=is_head_of_free_region(mem_map+loop))!=0) {
-				loop += chunk_size - 1;
+			if ((chunk_size=is_head_of_free_region(page))!=0) {
+				pfn += chunk_size - 1;
 				continue;
 			}
-		} else if (PageReserved(mem_map+loop)) {
-			BUG_ON (PageNosave(mem_map+loop));
+		} else if (PageReserved(page)) {
+			BUG_ON (PageNosave(page));
 
 			/*
 			 * Just copy whole code segment. Hopefully it is not that big.
 			 */
-			if (ADDRESS(loop) >= (unsigned long)
-				&__nosave_begin && ADDRESS(loop) < 
+			if (ADDRESS(pfn) >= (unsigned long)
+				&__nosave_begin && ADDRESS(pfn) < 
 				(unsigned long)&__nosave_end) {
-				PRINTK("[nosave %x]", ADDRESS(loop));
+				PRINTK("[nosave %x]", ADDRESS(pfn));
 				continue;
 			}
 			/* Hmm, perhaps copying all reserved pages is not too healthy as they may contain 
@@ -501,7 +503,7 @@
 
 		nr_copy_pages++;
 		if (pagedir_p) {
-			pagedir_p->orig_address = ADDRESS(loop);
+			pagedir_p->orig_address = ADDRESS(pfn);
 			copy_page(pagedir_p->address, pagedir_p->orig_address);
 			pagedir_p++;
 		}
mm/page_alloc.c +2 -2
diff -urN 2.5.31-13-numa/mm/page_alloc.c 2.5.31-21-bad_range/mm/page_alloc.c
@@ -47,9 +47,9 @@
  */
 static inline int bad_range(zone_t *zone, struct page *page)
 {
-	if (page - mem_map >= zone->zone_start_mapnr + zone->size)
+	if (page_to_pfn(page) >= zone->zone_start_pfn + zone->size)
 		return 1;
-	if (page - mem_map < zone->zone_start_mapnr)
+	if (page_to_pfn(page) < zone->zone_start_pfn)
 		return 1;
 	if (zone != page_zone(page))
 		return 1;

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/

#1 lore raw
Quoted 6 lines · Martin J. Bligh

This simply converts direct usage of mem_map to the correct macros (mem_map doesn't work like this for discontigmem). It also fixes a bug in bad_range, that happens to work for contig mem systems, but is incorrect. Tested both with and without discontigmem support.

Looks good, thanks. I'll nail an unneeded typecast in there.

My queue runneth over at present, and the kmap patches need to percolate forwards soon (once they're agreeably written). I'm planning on sending per-zone-lru next, then discontigmem (again) then kmap. Probably kmap needs to come earlier..

I won't send the rmap locking hacklets until we've nailed that BUG in __free_pages_ok.

Does pci_map_page() work on discontigmem?

What _is_ zone_start_mapnr?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/

#2 lore raw
Quoted 3 lines

Looks good, thanks. I'll nail an unneeded typecast in there.

My queue runneth over at present, and the kmap patches need to

I'm not suprised ;-) I can queue more stuff here rather than send it to your queue, but I'd like you to keep an eye on me before I go too far astray from what you want to see ;-)

Quoted 2 lines

I won't send the rmap locking hacklets until we've nailed that BUG in __free_pages_ok.

That seems to occur with 2.5.31, AFIACS, it's not the extra patches you have ... unless you mean just not stirring the pot at the moment.

Quoted 1 line

Does pci_map_page() work on discontigmem?

I think it will now I've replaced it with the macro, definitely wouldn't have done before.

Quoted 1 line

What _is_ zone_start_mapnr?

A stinking piece of crap that I'm going to rip out in round 2 ;-) Just testing that now .... (along with node_start_mapnr)

Basically, unless I'm very much mistaken the two things we have floating around are

1. pfn - this is a page frame number and
pfn == physaddr >> PAGE_SHIFT

2. mapnr. This is the index into the mem_map array. For contigmem,
thats equiv to a pfn, and more or less made some sense.
For discontigmem that's a nasty hack. We don't have a mem_map array,
we have an lmem_map array per pg_data_t (aka node or memory chunk).
But we somehow decided to define mem_map = PAGE_OFFSET, then
retend the whole of the virtual address space is some kind of klunky mem_map array with holes in. So node_start_mapnr = lmem_map - mem_map .... except that's really arith on struct pages, so it's the distance / sizeof(struct page). So we have to align lmem_map allocations on a boundary of size sizeof(struct page), except that's really a boundary from PAGE_OFFSET, not absolute vaddr. Gack. Look at free_area_init_core. It's unpleasant ;-)

M.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/

#3 lore raw
Quoted 8 lines · Martin J. Bligh
Quoted 4 lines

Looks good, thanks. I'll nail an unneeded typecast in there.

My queue runneth over at present, and the kmap patches need to

I'm not suprised ;-) I can queue more stuff here rather than send it to your queue, but I'd like you to keep an eye on me before I go too far astray from what you want to see ;-)

Oh whatever. If it's in my pile then a few more people get to bang on it for a while. Looks like a long backlog will become a permanent state, so I'll need to do something more organised there.

Quoted 5 lines
Quoted 2 lines

I won't send the rmap locking hacklets until we've nailed that BUG in __free_pages_ok.

That seems to occur with 2.5.31, AFIACS, it's not the extra patches you have ... unless you mean just not stirring the pot at the moment.

Well yes. The code at present is pretty much the same as well-tested 2.4 code which presumably will make it easier to find this bug. Changing the code now would increase the volume of suspect code.

Quoted 4 lines

...
2. mapnr. This is the index into the mem_map array. For contigmem, thats equiv to a pfn, and more or less made some sense. For discontigmem that's a nasty hack. We don't have a mem_map array,

Quoted 8 lines

we have an lmem_map array per pg_data_t (aka node or memory chunk).
But we somehow decided to define mem_map = PAGE_OFFSET, then
retend the whole of the virtual address space is some kind of klunky mem_map array with holes in. So node_start_mapnr = lmem_map - mem_map .... except that's really arith on struct pages, so it's the distance / sizeof(struct page). So we have to align lmem_map allocations on a boundary of size sizeof(struct page), except that's really a boundary from PAGE_OFFSET, not absolute vaddr. Gack. Look at free_area_init_core. It's unpleasant ;-)

I wish you hadn't told me all that.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/

#4 lore raw
Quoted 12 lines
Quoted 11 lines

2. mapnr. This is the index into the mem_map array. For contigmem,
thats equiv to a pfn, and more or less made some sense.
For discontigmem that's a nasty hack. We don't have a mem_map array,
we have an lmem_map array per pg_data_t (aka node or memory chunk).
But we somehow decided to define mem_map = PAGE_OFFSET, then
retend the whole of the virtual address space is some kind of klunky mem_map array with holes in. So node_start_mapnr = lmem_map - mem_map .... except that's really arith on struct pages, so it's the distance / sizeof(struct page). So we have to align lmem_map allocations on a boundary of size sizeof(struct page), except that's really a boundary from PAGE_OFFSET, not absolute vaddr. Gack. Look at free_area_init_core. It's unpleasant ;-)

Quoted 1 line

I wish you hadn't told me all that.

;-)

But when I send you the patch to rip it all out, you'll be happy now ;-)

M.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/

#5 lore raw
In reply to Andrew Morton
Quoted 4 lines · Andrew Morton

Oh whatever. If it's in my pile then a few more people get to bang on it for a while. Looks like a long backlog will become a permanent state, so I'll need to do something more organised there.

Another reason why I decided to do the page_launder/shrink_cache rewrite on 2.4 first. Once it's stable and the corner cases have been ironed out I'll give you something that just works. ;)

cheers,

Rik

Signature · 8 lines
Bravely reimplemented by the knights who say "NIH".

http://www.surriel.com/		http://distro.conectiva.com/

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/
#6 lore raw
Quoted 12 lines · Rik van Riel
Quoted 4 lines · Andrew Morton

Oh whatever. If it's in my pile then a few more people get to bang on it for a while. Looks like a long backlog will become a permanent state, so I'll need to do something more organised there.

Another reason why I decided to do the page_launder/shrink_cache rewrite on 2.4 first. Once it's stable and the corner cases have been ironed out I'll give you something that just works. ;)

I'd like to find a way to improve the stability of the patches which are being submitted. I had 1.5 screwups in the latest batch, and there's the page->pte.chain BUG, and a rather worrisome batch of BUGs against the latest everything.gz from Badari which may propagate to 2.5.32.

So I'll go for a more formal off-stream patchset after .32 comes out - I assume Martin & co will test against that, if only for the kmap carrot. We can stage any code you want tested within that.

As things are shown to be stable and worthwhile in that tree I can pop patches off the bottom and submit them to Linus.

The problem with this rosy picture is that Linus may bounce some of it back, and all the testing gets invalidated. So I'll attempt to get comment from him at a prior-to-submission stage.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/