On Thu, 06 Oct 2011 15:54:44 +0200 Marek Szyprowski <m.szyprowski@xxxxxxxxxxx> wrote: > From: Michal Nazarewicz <m.nazarewicz@xxxxxxxxxxx> > > The MIGRATE_CMA migration type has two main characteristics: > (i) only movable pages can be allocated from MIGRATE_CMA > pageblocks and (ii) page allocator will never change migration > type of MIGRATE_CMA pageblocks. > > This guarantees that page in a MIGRATE_CMA page block can > always be migrated somewhere else (unless there's no memory left > in the system). > > It is designed to be used with Contiguous Memory Allocator > (CMA) for allocating big chunks (eg. 10MiB) of physically > contiguous memory. Once driver requests contiguous memory, > CMA will migrate pages from MIGRATE_CMA pageblocks. > > To minimise number of migrations, MIGRATE_CMA migration type > is the last type tried when page allocator falls back to other > migration types then requested. > > > ... > > +#ifdef CONFIG_CMA_MIGRATE_TYPE > +# define is_migrate_cma(migratetype) unlikely((migratetype) == MIGRATE_CMA) > +#else > +# define is_migrate_cma(migratetype) false > +#endif Implement in C, please. > > ... > > --- a/mm/compaction.c > +++ b/mm/compaction.c > @@ -115,6 +115,16 @@ static bool suitable_migration_target(struct page *page) > if (migratetype == MIGRATE_ISOLATE || migratetype == MIGRATE_RESERVE) > return false; > > + /* Keep MIGRATE_CMA alone as well. */ > + /* > + * XXX Revisit. We currently cannot let compaction touch CMA > + * pages since compaction insists on changing their migration > + * type to MIGRATE_MOVABLE (see split_free_page() called from > + * isolate_freepages_block() above). > + */ Talk to us about this. How serious is this shortcoming in practice? What would a fix look like? Is anyone working on an implementation, or planning to do so? > + if (is_migrate_cma(migratetype)) > + return false; > + > /* If the page is a large free page, then allow migration */ > if (PageBuddy(page) && page_order(page) >= pageblock_order) > return true; > > ... > > +void __init init_cma_reserved_pageblock(struct page *page) > +{ > + struct page *p = page; > + unsigned i = pageblock_nr_pages; > + > + prefetchw(p); > + do { > + if (--i) > + prefetchw(p + 1); > + __ClearPageReserved(p); > + set_page_count(p, 0); > + } while (++p, i); > + > + set_page_refcounted(page); > + set_pageblock_migratetype(page, MIGRATE_CMA); > + __free_pages(page, pageblock_order); > + totalram_pages += pageblock_nr_pages; > +} I wonder if the prefetches do any good. it doesn't seem very important in an __init function. > +#endif > > > ... > -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html