Exemple #1
0
/*
 * Test all pages in the range is free(means isolated) or not.
 * all pages in [start_pfn...end_pfn) must be in the same zone.
 * zone->lock must be held before call this.
 *
 * Returns the last tested pfn.
 */
static unsigned long
__test_page_isolated_in_pageblock(unsigned long pfn, unsigned long end_pfn,
				  bool skip_hwpoisoned_pages)
{
	struct page *page;

	while (pfn < end_pfn) {
		if (!pfn_valid_within(pfn)) {
			pfn++;
			continue;
		}
		page = pfn_to_page(pfn);
		if (PageBuddy(page))
			/*
			 * If the page is on a free list, it has to be on
			 * the correct MIGRATE_ISOLATE freelist. There is no
			 * simple way to verify that as VM_BUG_ON(), though.
			 */
			pfn += 1 << page_order(page);
		else if (skip_hwpoisoned_pages && PageHWPoison(page))
			/* A HWPoisoned page cannot be also PageBuddy */
			pfn++;
		else
			break;
	}

	return pfn;
}
__test_page_isolated_in_pageblock(struct zone *zone, unsigned long pfn,
			unsigned long end_pfn, bool skip_hwpoisoned_pages)
#endif
{
	struct page *page;

	while (pfn < end_pfn) {
		if (!pfn_valid_within(pfn)) {
			pfn++;
			continue;
		}
		page = pfn_to_page(pfn);
#if defined(CONFIG_CMA) && defined(CONFIG_MTK_SVP) // SVP 07
		if (page_zone(page) != zone)
			break;
#endif
		if (PageBuddy(page)) {
			/*
			 * If race between isolatation and allocation happens,
			 * some free pages could be in MIGRATE_MOVABLE list
			 * although pageblock's migratation type of the page
			 * is MIGRATE_ISOLATE. Catch it and move the page into
			 * MIGRATE_ISOLATE list.
			 */
			if (get_freepage_migratetype(page) != MIGRATE_ISOLATE) {
				struct page *end_page;

				end_page = page + (1 << page_order(page)) - 1;
				move_freepages(page_zone(page), page, end_page,
						MIGRATE_ISOLATE);
			}
			pfn += 1 << page_order(page);
		}
		else if (page_count(page) == 0 &&
			get_freepage_migratetype(page) == MIGRATE_ISOLATE)
			pfn += 1;
		else if (skip_hwpoisoned_pages && PageHWPoison(page)) {
			/*
			 * The HWPoisoned page may be not in buddy
			 * system, and page_count() is not 0.
			 */
			pfn++;
			continue;
		}
		else
			break;
	}
	if (pfn < end_pfn)
		return 0;
	return 1;
}
static void
bad_page(struct page *page) {
    static unsigned long resume;
    static unsigned long nr_shown;
    static unsigned long nr_unshown;

    /* Don't complain about poisoned pages */
    if (PageHWPoison(page)) {
        __ClearPageBuddy(page);
        return;
    }

    /*
     * 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   pfn:%05lx\n", page_to_pfn(page));
    //  dump_page(page);

    dump_stack();
out:
    /* Leave bad fields for debug, except PageBuddy could make trouble */
    __ClearPageBuddy(page);
    add_taint(TAINT_BAD_PAGE);
}