Re: [PATCH 56 of 67] Memory compaction core

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Johannes,

On Thu, Apr 08, 2010 at 06:18:14PM +0200, Johannes Weiner wrote:
> Andrea,
> 
> > +		/* Get the page and skip if free */
> > +		page = pfn_to_page(low_pfn);
> > +		if (PageBuddy(page)) {
> 
> Should this be
> 
> 		if (PageBuddy(page) || PageTransHuge(page)) {
> 
> > +			low_pfn += (1 << page_order(page)) - 1;
> > +			continue;
> > +		}
> 
> instead?

That was the original code (without PageTransHuge) and what you will
find in -mm. But calling page_order crashes because there's only the
lru_lock here (not the zone->lock), so PageBuddy will go away from
under us and it won't be set when page_order is called.

It's a minor optimization so the fix is what I implemented with:

     if (PageBuddy(page))
     	continue;

I also noticed this loop misses the check for PageTransCompound. Your
PageTransHuge check above would make it crash if it touches a tail
page. this scans all pfn so if a order 10 allocation exists in the
system, that could trip on it. PageTransCompound is the right check
and it'll fix Avi's issue.

I'm undecided if it's safe to have PageTransCompound checked before or
after __isolate_lru_page.

Now split_huge_page_refcount clears PG_head/tail gauranteed under
zone->lru_lock so there's zero risk of PageTransCompound to go away
from under us there. In fact we can also check the
compound_order(page) there, safely. It can't go away from under us
(unlike the page_order when PageBuddy is set).

But khugepaged might create hugepages from under us at that
point. While if we run it after __isolate_lru_page we keep khugepaged
away too, because khugepaged has to isolate the pages to collapse
them, and secondly because khugepaged will never touch a page with
pinned page_count.

> 
> > +
> > +		/* Try isolate the page */
> > +		if (__isolate_lru_page(page, ISOLATE_BOTH, 0) != 0)
> > +			continue;
> > +
> > +		/* Successfully isolated */
> > +		del_page_from_lru_list(zone, page, page_lru(page));
> > +		list_add(&page->lru, migratelist);
> > +		mem_cgroup_del_lru(page);
> > +		cc->nr_migratepages++;
> > +
> > +		/* Avoid isolating too much */
> > +		if (cc->nr_migratepages == COMPACT_CLUSTER_MAX)
> > +			break;
> > +	}
> > +
> > +	acct_isolated(zone, cc);
> > +
> > +	spin_unlock_irq(&zone->lru_lock);
> > +	cc->migrate_pfn = low_pfn;
> > +
> > +	return cc->nr_migratepages;
> 

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@xxxxxxxxxx  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@xxxxxxxxx";> email@xxxxxxxxx </a>

[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]