]> Pileus Git - ~andy/linux/blobdiff - mm/page_alloc.c
mm: direct IO starvation improvement
[~andy/linux] / mm / page_alloc.c
index 3acb216e9a782d8ea2e2edbd918131f4b58ba486..d531e8ef9984d3fa6064cc148acc1f2b186f38a6 100644 (file)
@@ -69,6 +69,7 @@ EXPORT_SYMBOL(node_states);
 
 unsigned long totalram_pages __read_mostly;
 unsigned long totalreserve_pages __read_mostly;
+unsigned long highest_memmap_pfn __read_mostly;
 int percpu_pagelist_fraction;
 
 #ifdef CONFIG_HUGETLB_PAGE_SIZE_VARIABLE
@@ -222,16 +223,39 @@ static inline int bad_range(struct zone *zone, struct page *page)
 
 static void bad_page(struct page *page)
 {
-       printk(KERN_EMERG "Bad page state in process %s  pfn:%05lx\n",
+       static unsigned long resume;
+       static unsigned long nr_shown;
+       static unsigned long nr_unshown;
+
+       /*
+        * Allow a burst of 60 reports, then keep quiet for that minute;
+        * or allow a steady drip of one report per second.
+        */
+       if (nr_shown == 60) {
+               if (time_before(jiffies, resume)) {
+                       nr_unshown++;
+                       goto out;
+               }
+               if (nr_unshown) {
+                       printk(KERN_ALERT
+                             "BUG: Bad page state: %lu messages suppressed\n",
+                               nr_unshown);
+                       nr_unshown = 0;
+               }
+               nr_shown = 0;
+       }
+       if (nr_shown++ == 0)
+               resume = jiffies + 60 * HZ;
+
+       printk(KERN_ALERT "BUG: Bad page state in process %s  pfn:%05lx\n",
                current->comm, page_to_pfn(page));
-       printk(KERN_EMERG
+       printk(KERN_ALERT
                "page:%p flags:%p count:%d mapcount:%d mapping:%p index:%lx\n",
                page, (void *)page->flags, page_count(page),
                page_mapcount(page), page->mapping, page->index);
-       printk(KERN_EMERG "Trying to fix it up, but a reboot is needed\n");
 
        dump_stack();
-
+out:
        /* Leave bad fields for debug, except PageBuddy could make trouble */
        __ClearPageBuddy(page);
        add_taint(TAINT_BAD_PAGE);
@@ -2597,6 +2621,9 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
        unsigned long pfn;
        struct zone *z;
 
+       if (highest_memmap_pfn < end_pfn - 1)
+               highest_memmap_pfn = end_pfn - 1;
+
        z = &NODE_DATA(nid)->node_zones[zone];
        for (pfn = start_pfn; pfn < end_pfn; pfn++) {
                /*