- update to 2.6.1-rc2 -- first cut.
[linux-flexiantxendom0-3.2.10.git] / mm / page_alloc.c
index f7e0ff6..622364e 100644 (file)
@@ -267,9 +267,11 @@ free_pages_bulk(struct zone *zone, int count,
 void __free_pages_ok(struct page *page, unsigned int order)
 {
        LIST_HEAD(list);
+       int i;
 
        mod_page_state(pgfree, 1 << order);
-       free_pages_check(__FUNCTION__, page);
+       for (i = 0 ; i < (1 << order) ; ++i)
+               free_pages_check(__FUNCTION__, page + i);
        list_add(&page->list, &list);
        kernel_map_pages(page, 1<<order, 0);
        free_pages_bulk(page_zone(page), 1, &list, order);
@@ -1589,7 +1591,7 @@ void __init page_alloc_init(void)
  *     that the pages_{min,low,high} values for each zone are set correctly 
  *     with respect to min_free_kbytes.
  */
-void setup_per_zone_pages_min(void)
+static void setup_per_zone_pages_min(void)
 {
        unsigned long pages_min = min_free_kbytes >> (PAGE_SHIFT - 10);
        unsigned long lowmem_pages = 0;
@@ -1633,6 +1635,45 @@ void setup_per_zone_pages_min(void)
 }
 
 /*
+ * Initialise min_free_kbytes.
+ *
+ * For small machines we want it small (128k min).  For large machines
+ * we want it large (16MB max).  But it is not linear, because network
+ * bandwidth does not increase linearly with machine size.  We use
+ *
+ *     min_free_kbytes = sqrt(lowmem_kbytes)
+ *
+ * which yields
+ *
+ * 16MB:       128k
+ * 32MB:       181k
+ * 64MB:       256k
+ * 128MB:      362k
+ * 256MB:      512k
+ * 512MB:      724k
+ * 1024MB:     1024k
+ * 2048MB:     1448k
+ * 4096MB:     2048k
+ * 8192MB:     2896k
+ * 16384MB:    4096k
+ */
+static int __init init_per_zone_pages_min(void)
+{
+       unsigned long lowmem_kbytes;
+
+       lowmem_kbytes = nr_free_buffer_pages() * (PAGE_SIZE >> 10);
+
+       min_free_kbytes = int_sqrt(lowmem_kbytes);
+       if (min_free_kbytes < 128)
+               min_free_kbytes = 128;
+       if (min_free_kbytes > 16384)
+               min_free_kbytes = 16384;
+       setup_per_zone_pages_min();
+       return 0;
+}
+module_init(init_per_zone_pages_min)
+
+/*
  * min_free_kbytes_sysctl_handler - just a wrapper around proc_dointvec() so 
  *     that we can call setup_per_zone_pages_min() whenever min_free_kbytes 
  *     changes.