]> git.hungrycats.org Git - linux/commitdiff
allow the boot-time sizing of the highmem pool.
authorIngo Molnar <mingo@elte.hu>
Mon, 18 Feb 2002 21:21:32 +0000 (22:21 +0100)
committerIngo Molnar <mingo@elte.hu>
Mon, 18 Feb 2002 21:21:32 +0000 (22:21 +0100)
arch/i386/kernel/setup.c

index d7f8e2a1e676a29475c08dce68bf98bfac089463..844d923b183a58697bbbd068bceff9121d59699b 100644 (file)
@@ -139,6 +139,9 @@ unsigned int mca_pentium_flag;
 /* For PCI or other memory-mapped resources */
 unsigned long pci_mem_start = 0x10000000;
 
+/* user-defined highmem size */
+static unsigned int highmem_pages = -1;
+
 /*
  * Setup options
  */
@@ -638,8 +641,15 @@ static void __init parse_mem_cmdline (char ** cmdline_p)
                        }
                }
                /* acpismp=force forces parsing and use of the ACPI SMP table */
-               if (c == ' ' && !memcmp(from, "acpismp=force", 13))     
+               if (c == ' ' && !memcmp(from, "acpismp=force", 13))
                         enable_acpi_smp_table = 1;
+               /*
+                * highmem=size forces highmem to be exactly 'size' bytes.
+                * This works even on boxes that have no highmem otherwise.
+                * This also works to reduce highmem size on bigger boxes.
+                */
+               if (c == ' ' && !memcmp(from, "highmem=", 8))
+                       highmem_pages = memparse(from+8, &from) >> PAGE_SHIFT;
        
                c = *(from++);
                if (!c)
@@ -737,6 +747,14 @@ void __init setup_arch(char **cmdline_p)
         */
        max_low_pfn = max_pfn;
        if (max_low_pfn > MAXMEM_PFN) {
+               if (highmem_pages == -1)
+                       highmem_pages = max_pfn - MAXMEM_PFN;
+               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;
+               }
                max_low_pfn = MAXMEM_PFN;
 #ifndef CONFIG_HIGHMEM
                /* Maximum memory usable is what is directly addressable */
@@ -756,16 +774,37 @@ void __init setup_arch(char **cmdline_p)
                }
 #endif /* !CONFIG_X86_PAE */
 #endif /* !CONFIG_HIGHMEM */
+       } else {
+               if (highmem_pages == -1)
+                       highmem_pages = 0;
+#if 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;
+               }
+#else
+               if (highmem_pages)
+                       printk(KERN_ERR "ignoring highmem size on non-highmem kernel!\n");
+#endif
        }
 
 #ifdef CONFIG_HIGHMEM
        highstart_pfn = highend_pfn = max_pfn;
-       if (max_pfn > MAXMEM_PFN) {
-               highstart_pfn = MAXMEM_PFN;
-               printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
-                       pages_to_mb(highend_pfn - highstart_pfn));
+       if (max_pfn > max_low_pfn) {
+               highstart_pfn = max_low_pfn;
        }
+       printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
+               pages_to_mb(highend_pfn - highstart_pfn));
 #endif
+       printk(KERN_NOTICE "%ldMB LOWMEM available.\n",
+                       pages_to_mb(max_low_pfn));
        /*
         * Initialize the boot-time allocator (with low memory only):
         */