public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: "Michael Frank" <mhf@linuxmail.org>
To: "Pavel Machek" <pavel@ucw.cz>,
	"kernel list" <linux-kernel@vger.kernel.org>
Subject: Re: Highmem emulation for 2.6?
Date: Sun, 07 Mar 2004 21:17:27 +0800	[thread overview]
Message-ID: <opr4htvdoa4evsfm@smtp.pacific.net.th> (raw)
In-Reply-To: <20040307125939.GA965@elf.ucw.cz>

[-- Attachment #1: Type: text/plain, Size: 4507 bytes --]

On Sun, 7 Mar 2004 13:59:40 +0100, Pavel Machek <pavel@ucw.cz> wrote:

> Does anyone have `subj`?

Enclosed patches is tested and works on UP wo ramdisk.

It was in -mm until Andrew dropped it due to it causing
problems on SMP, NUMA and with ramdisk.

Ramdisk expects to be at the end of lowmem zone so it
wont work in it's current implementation with this patch
when memory is shiften into highmem zone.

I'll be looking into fixes when less busy.

Regards
Michael

no highmem option

0MB HIGHMEM available.
495MB LOWMEM available.
On node 0 totalpages: 126960, zones aligned at: 0x400000
   DMA zone: 4096 pages, LIFO batch:1, physical start address at: 0x0
   Normal zone: 122864 pages, LIFO batch:16, physical start address at: 0x1000000

highmem=1m

Warning highmem=1MB is too small and has been adjusted to: 8MB.
Warning bad highmem zone alignment 0x3f0000, highmem size will be adjusted.
Warning lowmem size adjusted  for zone alignment to: 488MB.
Warning highmem size adjusted for zone alignment to: 7MB.
7MB HIGHMEM available.
488MB LOWMEM available.
On node 0 totalpages: 126960, zones aligned at: 0x400000
   DMA zone: 4096 pages, LIFO batch:1, physical start address at: 0x0
   Normal zone: 120832 pages, LIFO batch:16, physical start address at: 0x1000000
   HighMem zone: 2032 pages, LIFO batch:1, physical start address at: 0x1e800000

highmem=300m

Warning bad highmem zone alignment 0x3f0000, highmem size will be adjusted.
Warning lowmem size adjusted  for zone alignment to: 196MB.
Warning highmem size adjusted for zone alignment to: 299MB.
299MB HIGHMEM available.
196MB LOWMEM available.
On node 0 totalpages: 126960, zones aligned at: 0x400000
   DMA zone: 4096 pages, LIFO batch:1, physical start address at: 0x0
   Normal zone: 46080 pages, LIFO batch:11, physical start address at: 0x1000000
   HighMem zone: 76784 pages, LIFO batch:16, physical start address at: 0xc400000

highmem=450m

Warning highmem size adjusted for a minimum of 64MB lowmem to: 431MB.
431MB HIGHMEM available.
64MB LOWMEM available.
On node 0 totalpages: 126960, zones aligned at: 0x400000
   DMA zone: 4096 pages, LIFO batch:1, physical start address at: 0x0
   Normal zone: 12288 pages, LIFO batch:3, physical start address at: 0x1000000
   HighMem zone: 110576 pages, LIFO batch:16, physical start address at: 0x4000000

highmem=5000m

Warning highmem=5000MB is bigger than available 495MB and will be adjusted.
Warning highmem size adjusted for a minimum of 64MB lowmem to: 431MB.
431MB HIGHMEM available.
64MB LOWMEM available.
On node 0 totalpages: 126960, zones aligned at: 0x400000
   DMA zone: 4096 pages, LIFO batch:1, physical start address at: 0x0
   Normal zone: 12288 pages, LIFO batch:3, physical start address at: 0x1000000
   HighMem zone: 110576 pages, LIFO batch:16, physical start address at: 0x4000000

mem=80m highmem=1m

Warning highmem=1MB is too small and has been adjusted to: 8MB.
8MB HIGHMEM available.
72MB LOWMEM available.
On node 0 totalpages: 20480, zones aligned at: 0x400000
   DMA zone: 4096 pages, LIFO batch:1, physical start address at: 0x0
   Normal zone: 14336 pages, LIFO batch:3, physical start address at: 0x1000000
   HighMem zone: 2048 pages, LIFO batch:1, physical start address at: 0x4800000

mem=80m highmem=300m

Warning highmem=300MB is bigger than available 80MB and will be adjusted.
Warning highmem size adjusted for a minimum of 64MB lowmem to: 16MB.
16MB HIGHMEM available.
64MB LOWMEM available.
On node 0 totalpages: 20480, zones aligned at: 0x400000
   DMA zone: 4096 pages, LIFO batch:1, physical start address at: 0x0
   Normal zone: 12288 pages, LIFO batch:3, physical start address at: 0x1000000
   HighMem zone: 4096 pages, LIFO batch:1, physical start address at: 0x4000000

mem=71m highmem=1m

Error highmem support requires at least 72MB but only 71MB are available.
0MB HIGHMEM available.
71MB LOWMEM available.
On node 0 totalpages: 18176, zones aligned at: 0x400000
   DMA zone: 4096 pages, LIFO batch:1, physical start address at: 0x0
   Normal zone: 14080 pages, LIFO batch:3, physical start address at: 0x1000000

mem=72m highmem=10m

Warning highmem size adjusted for a minimum of 64MB lowmem to: 8MB.
8MB HIGHMEM available.
64MB LOWMEM available.
On node 0 totalpages: 18432, zones aligned at: 0x400000
   DMA zone: 4096 pages, LIFO batch:1, physical start address at: 0x0
   Normal zone: 12288 pages, LIFO batch:3, physical start address at: 0x1000000
   HighMem zone: 2048 pages, LIFO batch:1, physical start address at: 0x4000000

[-- Attachment #2: highmem-equals-user-friendliness.patch --]
[-- Type: application/octet-stream, Size: 6616 bytes --]


From: Michael Frank <mhf@linuxmail.org>

Enclosed is a patch for x86 to make highmem= option easier to use.

- Automates alignment of highmem zone

- Fixes invalid highmem settings whether too small or to large

- Adds entry in kernel-parameters.txt

- Permits highmem emulation, so people with less than 896MB of memory can
  test CONFIG_HIGHMEM.  Highmem emulation can be used on any machine with at
  least 72MB RAM.

The patch does not add to bloat as it is part of __init code.




---

 Documentation/kernel-parameters.txt |    8 +++
 arch/i386/kernel/setup.c            |   91 +++++++++++++++++++++++++++---------
 2 files changed, 77 insertions(+), 22 deletions(-)

diff -puN arch/i386/kernel/setup.c~highmem-equals-user-friendliness arch/i386/kernel/setup.c
--- 25/arch/i386/kernel/setup.c~highmem-equals-user-friendliness	2004-02-09 00:14:08.000000000 -0800
+++ 25-akpm/arch/i386/kernel/setup.c	2004-02-09 00:14:08.000000000 -0800
@@ -588,9 +588,12 @@ static void __init parse_cmdline_early (
 #endif /* CONFIG_ACPI_BOOT */
 
 		/*
-		 * highmem=size forces highmem to be exactly 'size' bytes.
+		 * highmem=size forces highmem to be at most 'size' bytes.
 		 * This works even on boxes that have no highmem otherwise.
 		 * This also works to reduce highmem size on bigger boxes.
+		 *
+		 * Note: highmem sise is adjusted downward for proper zone
+		 *       alignment of the highmem physical start address.
 		 */
 		if (c == ' ' && !memcmp(from, "highmem=", 8))
 			highmem_pages = memparse(from+8, &from) >> PAGE_SHIFT;
@@ -657,6 +660,11 @@ void __init find_max_pfn(void)
 /*
  * Determine low and high memory ranges:
  */
+
+#define ZONE_REQUIRED_PAGE_ALIGNMENT (1UL << (MAX_ORDER-1))
+#define ZONE_REQUIRED_PAGE_ALIGNMENT_MASK (ZONE_REQUIRED_PAGE_ALIGNMENT-1)
+#define PAGES_FOR_64MB (64*1024*1024/PAGE_SIZE)
+
 unsigned long __init find_max_low_pfn(void)
 {
 	unsigned long max_low_pfn;
@@ -668,14 +676,16 @@ unsigned long __init find_max_low_pfn(vo
 		if (highmem_pages + MAXMEM_PFN < max_pfn)
 			max_pfn = MAXMEM_PFN + highmem_pages;
 		if (highmem_pages + MAXMEM_PFN > max_pfn) {
-			printk("only %luMB highmem pages available, ignoring highmem size of %uMB.\n", pages_to_mb(max_pfn - MAXMEM_PFN), pages_to_mb(highmem_pages));
-			highmem_pages = 0;
+			printk("Warning reducing highmem=%uMB to: %luMB.\n",
+				pages_to_mb(highmem_pages),
+				pages_to_mb((max_pfn - MAXMEM_PFN)));
+			highmem_pages = max_pfn - MAXMEM_PFN;
 		}
 		max_low_pfn = MAXMEM_PFN;
 #ifndef CONFIG_HIGHMEM
 		/* Maximum memory usable is what is directly addressable */
-		printk(KERN_WARNING "Warning only %ldMB will be used.\n",
-					MAXMEM>>20);
+		printk(KERN_WARNING "Warning only %luMB will be used.\n",
+			MAXMEM >> 20);
 		if (max_pfn > MAX_NONPAE_PFN)
 			printk(KERN_WARNING "Use a PAE enabled kernel.\n");
 		else
@@ -690,26 +700,63 @@ unsigned long __init find_max_low_pfn(vo
 		}
 #endif /* !CONFIG_X86_PAE */
 #endif /* !CONFIG_HIGHMEM */
-	} else {
-		if (highmem_pages == -1)
-			highmem_pages = 0;
+	} else if (highmem_pages == -1)
+		highmem_pages = 0;
 #ifdef CONFIG_HIGHMEM
-		if (highmem_pages >= max_pfn) {
-			printk(KERN_ERR "highmem size specified (%uMB) is bigger than pages available (%luMB)!.\n", pages_to_mb(highmem_pages), pages_to_mb(max_pfn));
-			highmem_pages = 0;
-		}
-		if (highmem_pages) {
-			if (max_low_pfn-highmem_pages < 64*1024*1024/PAGE_SIZE){
-				printk(KERN_ERR "highmem size %uMB results in smaller than 64MB lowmem, ignoring it.\n", pages_to_mb(highmem_pages));
-				highmem_pages = 0;
-			}
-			max_low_pfn -= highmem_pages;
-		}
+	if (!highmem_pages)
+		goto out;
+	if (max_pfn < PAGES_FOR_64MB + ZONE_REQUIRED_PAGE_ALIGNMENT * 2) {
+		printk(KERN_ERR "Error highmem support requires at least %luMB "
+			"but only %luMB are available.\n",
+			pages_to_mb(PAGES_FOR_64MB +
+					ZONE_REQUIRED_PAGE_ALIGNMENT * 2),
+			pages_to_mb(max_pfn));
+		highmem_pages = 0;
+		goto out;
+	}
+	if (highmem_pages > max_pfn) {
+		printk(KERN_WARNING "Warning highmem=%uMB is bigger than "
+				"available %luMB and will be adjusted.\n",
+		pages_to_mb(highmem_pages), pages_to_mb(max_pfn));
+	}
+	if (highmem_pages <= ZONE_REQUIRED_PAGE_ALIGNMENT) {
+		printk(KERN_WARNING "Warning highmem=%uMB is too small and has "
+			"been adjusted to: %luMB.\n",
+			pages_to_mb(highmem_pages),
+			pages_to_mb(ZONE_REQUIRED_PAGE_ALIGNMENT * 2));
+		highmem_pages = ZONE_REQUIRED_PAGE_ALIGNMENT * 2;
+	}
+	if (max_low_pfn < highmem_pages ||
+			max_low_pfn-highmem_pages < PAGES_FOR_64MB){
+		highmem_pages = max_low_pfn - PAGES_FOR_64MB;
+		printk(KERN_WARNING "Warning highmem size adjusted for a "
+				"minimum of 64MB lowmem to: %uMB.\n",
+			pages_to_mb(highmem_pages));
+	}
+	max_low_pfn -= highmem_pages;
+
+	if (max_low_pfn & ZONE_REQUIRED_PAGE_ALIGNMENT_MASK) {
+		printk(KERN_WARNING "Warning bad highmem zone alignment 0x%lx, "
+			"highmem size will be adjusted.\n",
+			(max_low_pfn & ZONE_REQUIRED_PAGE_ALIGNMENT_MASK) <<
+					PAGE_SHIFT);
+		highmem_pages -= ZONE_REQUIRED_PAGE_ALIGNMENT -
+			(max_low_pfn & ZONE_REQUIRED_PAGE_ALIGNMENT_MASK);
+		max_low_pfn &= ~ZONE_REQUIRED_PAGE_ALIGNMENT_MASK;
+		max_low_pfn += ZONE_REQUIRED_PAGE_ALIGNMENT;
+		printk(KERN_WARNING "Warning lowmem size adjusted for zone "
+			"alignment to: %luMB.\n",
+			pages_to_mb(max_low_pfn));
+		printk(KERN_WARNING "Warning highmem size adjusted for zone "
+				"alignment to: %uMB.\n",
+			pages_to_mb(highmem_pages));
+	}
+out:
 #else
-		if (highmem_pages)
-			printk(KERN_ERR "ignoring highmem size on non-highmem kernel!\n");
+	if (highmem_pages)
+		printk(KERN_ERR "ignoring highmem size on non-highmem "
+					"kernel!\n");
 #endif
-	}
 	return max_low_pfn;
 }
 
diff -puN Documentation/kernel-parameters.txt~highmem-equals-user-friendliness Documentation/kernel-parameters.txt
--- 25/Documentation/kernel-parameters.txt~highmem-equals-user-friendliness	2004-02-09 00:14:08.000000000 -0800
+++ 25-akpm/Documentation/kernel-parameters.txt	2004-02-09 00:14:08.000000000 -0800
@@ -394,6 +394,14 @@ running once the system is up.
 	hd?=		[HW] (E)IDE subsystem
 	hd?lun=		See Documentation/ide.txt.
 
+	highmem=size[KMG] [IA32,KNL,BOOT] forces highmem to be at most 'size' bytes.
+			This works even on boxes with at least 72MB RAM that have no
+                        highmem otherwise. This also works to reduce highmem size on
+                        bigger boxes.
+
+                        Note: highmem is adjusted downward for proper zone alignment
+                        of  the highmem physical start address
+
 	hisax=		[HW,ISDN]
 			See Documentation/isdn/README.HiSax.
 

_

  reply	other threads:[~2004-03-07 13:18 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-03-07 12:59 Highmem emulation for 2.6? Pavel Machek
2004-03-07 13:17 ` Michael Frank [this message]
2004-03-07 13:41   ` Michael Frank
2004-03-07 13:19 ` Marc-Christian Petersen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=opr4htvdoa4evsfm@smtp.pacific.net.th \
    --to=mhf@linuxmail.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pavel@ucw.cz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox