Commit f5046231 authored by Andrew Morton's avatar Andrew Morton Committed by Jens Axboe

[PATCH] less buslocked operations in the page allocator

Sort-of-but-not-really from High Dickins.

We're doing a lot of buslocked operations in the page allocator just
for debug.  Plus when they _do_ trigger, there are so many BUG_ONs in
there that it's rather hard to work out from user reports which one
actually triggered.

So redo all that and also print out some more useful info about the
page state before taking the machine out.

(And yes, we need to take the machine out.  Incorrect page handling in
there can cause file corruption).
parent 6b390b3b
...@@ -59,6 +59,14 @@ static inline int bad_range(struct zone *zone, struct page *page) ...@@ -59,6 +59,14 @@ static inline int bad_range(struct zone *zone, struct page *page)
return 0; return 0;
} }
static void bad_page(const char *function, struct page *page)
{
printk("Bad page state at %s\n", function);
printk("flags:0x%08lx mapping:%p mapped:%d count:%d\n",
page->flags, page->mapping,
page_mapped(page), page_count(page));
}
/* /*
* Freeing function for a buddy system allocator. * Freeing function for a buddy system allocator.
* *
...@@ -91,16 +99,19 @@ void __free_pages_ok (struct page *page, unsigned int order) ...@@ -91,16 +99,19 @@ void __free_pages_ok (struct page *page, unsigned int order)
mod_page_state(pgfree, 1<<order); mod_page_state(pgfree, 1<<order);
BUG_ON(PageLRU(page)); if ( page_mapped(page) ||
BUG_ON(PagePrivate(page)); page->mapping != NULL ||
BUG_ON(page->mapping != NULL); page_count(page) != 0 ||
BUG_ON(PageLocked(page)); (page->flags & (
BUG_ON(PageActive(page)); 1 << PG_lru |
BUG_ON(PageWriteback(page)); 1 << PG_private |
BUG_ON(page->pte.direct != 0); 1 << PG_locked |
1 << PG_active |
1 << PG_writeback )))
bad_page(__FUNCTION__, page);
if (PageDirty(page)) if (PageDirty(page))
ClearPageDirty(page); ClearPageDirty(page);
BUG_ON(page_count(page) != 0);
if (unlikely(current->flags & PF_FREE_PAGES)) { if (unlikely(current->flags & PF_FREE_PAGES)) {
if (!current->nr_local_pages && !in_interrupt()) { if (!current->nr_local_pages && !in_interrupt()) {
...@@ -181,14 +192,17 @@ expand(struct zone *zone, struct page *page, ...@@ -181,14 +192,17 @@ expand(struct zone *zone, struct page *page,
*/ */
static inline void prep_new_page(struct page *page) static inline void prep_new_page(struct page *page)
{ {
BUG_ON(page->mapping); if ( page->mapping ||
BUG_ON(PagePrivate(page)); page_mapped(page) ||
BUG_ON(PageLocked(page)); (page->flags & (
BUG_ON(PageLRU(page)); 1 << PG_private |
BUG_ON(PageActive(page)); 1 << PG_locked |
BUG_ON(PageDirty(page)); 1 << PG_lru |
BUG_ON(PageWriteback(page)); 1 << PG_active |
BUG_ON(page->pte.direct != 0); 1 << PG_dirty |
1 << PG_writeback )))
bad_page(__FUNCTION__, page);
page->flags &= ~(1 << PG_uptodate | 1 << PG_error | page->flags &= ~(1 << PG_uptodate | 1 << PG_error |
1 << PG_referenced | 1 << PG_arch_1 | 1 << PG_referenced | 1 << PG_arch_1 |
1 << PG_checked); 1 << PG_checked);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment