Re: [RFC v2 10/10] mm, page_alloc: introduce MIGRATE_MIXED migratetype

Yisheng Xie
2017-03-08T02:17:42Z

Hi Vlastimil ,

On 2017/2/11 1:23, Vlastimil Babka wrote:
> @@ -1977,7 +1978,7 @@ static void steal_suitable_fallback(struct zone *zone, struct page *page,
> unsigned int current_order = page_order(page);
> struct free_area *area;
> int free_pages, good_pages;
> - int old_block_type;
> + int old_block_type, new_block_type;
>
> /* Take ownership for orders >= pageblock_order */
> if (current_order >= pageblock_order) {
> @@ -1991,11 +1992,27 @@ static void steal_suitable_fallback(struct zone *zone, struct page *page,
> if (!whole_block) {
> area = &zone->free_area[current_order];
> list_move(&page->lru, &area->free_list[start_type]);
> - return;
> + free_pages = 1 << current_order;
> + /* TODO: We didn't scan the block, so be pessimistic */
> + good_pages = 0;
> + } else {
> + free_pages = move_freepages_block(zone, page, start_type,
> + &good_pages);
> + /*
> + * good_pages is now the number of movable pages, but if we
> + * want UNMOVABLE or RECLAIMABLE, we consider all non-movable
> + * as good (but we can't fully distinguish them)
> + */
> + if (start_type != MIGRATE_MOVABLE)
> + good_pages = pageblock_nr_pages - free_pages -
> + good_pages;
> }
>
> free_pages = move_freepages_block(zone, page, start_type,
> &good_pages);
It seems this move_freepages_block() should be removed, if we can steal whole block
then just do it. If not we can check whether we can set it as mixed mt, right?
Please let me know if I miss something..

Thanks
Yisheng Xie

> +
> + new_block_type = old_block_type = get_pageblock_migratetype(page);
> +
> /*
> * good_pages is now the number of movable pages, but if we
> * want UNMOVABLE or RECLAIMABLE allocation, it's more tricky
> @@ -2007,7 +2024,6 @@ static void steal_suitable_fallback(struct zone *zone, struct page *page,
> * falling back to RECLAIMABLE or vice versa, be conservative
> * as we can't distinguish the exact migratetype.
> */
> - old_block_type = get_pageblock_migratetype(page);
> if (old_block_type == MIGRATE_MOVABLE)
> good_pages = pageblock_nr_pages
> - free_pages - good_pages;
> @@ -2015,10 +2031,34 @@ static void steal_suitable_fallback(struct zone *zone, struct page *page,
> good_pages = 0;
> }
>
> - /* Claim the whole block if over half of it is free or good type */
> - if (free_pages + good_pages >= (1 << (pageblock_order-1)) ||
> - page_group_by_mobility_disabled)
> - set_pageblock_migratetype(page, start_type);
> + if (page_group_by_mobility_disabled) {
> + new_block_type = start_type;
> + } else if (free_pages + good_pages >= (1 << (pageblock_order-1))) {
> + /*
> + * Claim the whole block if over half of it is free or good
> + * type. The exception is the transition to MIGRATE_MOVABLE
> + * where we require it to be fully free so that MIGRATE_MOVABLE
> + * pageblocks consist of purely movable pages. So if we steal
> + * less than whole pageblock, mark it as MIGRATE_MIXED.
> + */
> + if ((start_type == MIGRATE_MOVABLE) &&
> + free_pages + good_pages < pageblock_nr_pages)
> + new_block_type = MIGRATE_MIXED;
> + else
> + new_block_type = start_type;
> + } else {
> + /*
> + * We didn't steal enough to change the block's migratetype.
> + * But if we are stealing from a MOVABLE block for a
> + * non-MOVABLE allocation, mark the block as MIXED.
> + */
> + if (old_block_type == MIGRATE_MOVABLE
> + && start_type != MIGRATE_MOVABLE)
> + new_block_type = MIGRATE_MIXED;
> + }
> +
> + if (new_block_type != old_block_type)
> + set_pageblock_migratetype(page, new_block_type);
> }
>
> /*
> @@ -2560,16 +2600,18 @@ int __isolate_free_page(struct page *page, unsigned int order)
> rmv_page_order(page);
>
> /*
> - * Set the pageblock if the isolated page is at least half of a
> - * pageblock
> + * Set the pageblock's migratetype to MIXED if the isolated page is
> + * at least half of a pageblock, MOVABLE if at least whole pageblock
> */
> if (order >= pageblock_order - 1) {
> struct page *endpage = page + (1 << order) - 1;
> + int new_mt = (order >= pageblock_order) ?
> + MIGRATE_MOVABLE : MIGRATE_MIXED;
> for (; page < endpage; page += pageblock_nr_pages) {
> int mt = get_pageblock_migratetype(page);
> - if (!is_migrate_isolate(mt) && !is_migrate_cma(mt))
> - set_pageblock_migratetype(page,
> - MIGRATE_MOVABLE);
> +
> + if (!is_migrate_isolate(mt) && !is_migrate_movable(mt))
> + set_pageblock_migratetype(page, new_mt);
> }
> }
>
> @@ -4252,6 +4294,7 @@ static void show_migration_types(unsigned char type)
> [MIGRATE_MOVABLE] = 'M',
> [MIGRATE_RECLAIMABLE] = 'E',
> [MIGRATE_HIGHATOMIC] = 'H',
> + [MIGRATE_MIXED] = 'M',
> #ifdef CONFIG_CMA
> [MIGRATE_CMA] = 'C',
> #endif
>