Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1620863 > unrolled thread
| Started by | js1304@gmail.com |
|---|---|
| First post | 2017-04-11 05:20 +0200 |
| Last post | 2017-04-24 06:10 +0200 |
| Articles | 12 — 4 participants |
Back to article view | Back to linux.kernel
[PATCH v7 0/7] Introduce ZONE_CMA js1304@gmail.com - 2017-04-11 05:20 +0200
[PATCH v7 7/7] ARM: CMA: avoid re-mapping CMA region if CONFIG_HIGHMEM js1304@gmail.com - 2017-04-11 05:20 +0200
[PATCH v7 5/7] mm/cma: remove MIGRATE_CMA js1304@gmail.com - 2017-04-11 05:20 +0200
Re: [PATCH v7 0/7] Introduce ZONE_CMA Michal Hocko <mhocko@kernel.org> - 2017-04-11 20:20 +0200
Re: [PATCH v7 0/7] Introduce ZONE_CMA Joonsoo Kim <js1304@gmail.com> - 2017-04-12 03:40 +0200
Re: [PATCH v7 0/7] Introduce ZONE_CMA Michal Hocko <mhocko@kernel.org> - 2017-04-13 14:00 +0200
Re: [PATCH v7 0/7] Introduce ZONE_CMA Joonsoo Kim <js1304@gmail.com> - 2017-04-17 04:10 +0200
Re: [PATCH v7 0/7] Introduce ZONE_CMA Joonsoo Kim <js1304@gmail.com> - 2017-04-21 03:40 +0200
Re: [PATCH v7 0/7] Introduce ZONE_CMA Michal Hocko <mhocko@kernel.org> - 2017-04-21 09:00 +0200
Re: [PATCH v7 0/7] Introduce ZONE_CMA Michal Hocko <mhocko@kernel.org> - 2017-04-24 15:20 +0200
Re: [PATCH v7 0/7] Introduce ZONE_CMA Joonsoo Kim <js1304@gmail.com> - 2017-04-12 03:40 +0200
Re: [PATCH v7 0/7] Introduce ZONE_CMA Bob Liu <liubo95@huawei.com> - 2017-04-24 06:10 +0200
| From | js1304@gmail.com |
|---|---|
| Date | 2017-04-11 05:20 +0200 |
| Subject | [PATCH v7 0/7] Introduce ZONE_CMA |
| Message-ID | <tuUvw-1sy-3@gated-at.bofh.it> |
From: Joonsoo Kim <iamjoonsoo.kim@lge.com> Changed from v6 o Rebase on next-20170405 o Add a fix for lowmem mapping on ARM (last patch) o Re-organize the cover letter Changes from v5 o Rebase on next-20161013 o Cosmetic change on patch 1 o Optimize span of ZONE_CMA on multiple node system Changes from v4 o Rebase on next-20160825 o Add general fix patch for lowmem reserve o Fix lowmem reserve ratio o Fix zone span optimizaion per Vlastimil o Fix pageset initialization o Change invocation timing on cma_init_reserved_areas() Changes from v3 o Rebase on next-20160805 o Split first patch per Vlastimil o Remove useless function parameter per Vlastimil o Add code comment per Vlastimil o Add following description on cover-letter Changes from v2 o Rebase on next-20160525 o No other changes except following description Changes from v1 o Separate some patches which deserve to submit independently o Modify description to reflect current kernel state (e.g. high-order watermark problem disappeared by Mel's work) o Don't increase SECTION_SIZE_BITS to make a room in page flags (detailed reason is on the patch that adds ZONE_CMA) o Adjust ZONE_CMA population code Hello, This is the 7th version of ZONE_CMA patchset. One patch is added to fix potential problem on ARM. Other changes are just due to rebase. This patchset has long history and got some reviews before. This cover-letter has the summary and my opinion on those reviews. Content order is so confusing so I make a simple index. If anyone want to understand the history properly, please read them by reverse order. PART 1. Strong points of the zone approach PART 2. Summary in LSF/MM 2016 discussion PART 3. Original motivation of this patchset ***** PART 1 ***** CMA has many problems and I mentioned them on the bottom of the cover letter. These problems comes from limitation of CMA memory that should be always migratable for device usage. I think that introducing a new zone is the best approach to solve them. Here are the reasons. Zone is introduced to solve some issues due to H/W addressing limitation. MM subsystem is implemented to work efficiently with these zones. Allocation/reclaim logic in MM consider this limitation very much. What I did in this patchset is introducing a new zone and extending zone's concept slightly. New concept is that zone can have not only H/W addressing limitation but also S/W limitation to guarantee page migration. This concept is originated from ZONE_MOVABLE and it works well for a long time. So, ZONE_CMA should not be special at this moment. There is a major concern from Mel that ZONE_MOVABLE which has S/W limitation causes highmem/lowmem problem. Highmem/lowmem problem is that some of memory cannot be usable for kernel memory due to limitation of the zone. It causes to break LRU ordering and makes hard to find kernel usable memory when memory pressure. However, important point is that this problem doesn't come from implementation detail (ZONE_MOVABLE/MIGRATETYPE). Even if we implement it by MIGRATETYPE instead of by ZONE_MOVABLE, we cannot use that type of memory for kernel allocation because it isn't migratable. So, it will cause to break LRU ordering, too. We cannot avoid the problem in any case. Therefore, we should focus on which solution is better for maintenance and not intrusive for MM subsystem. In this viewpoint, I think that zone approach is better. As mentioned earlier, MM subsystem already have many infrastructures to deal with zone's H/W addressing limitation. Adding S/W limitation on zone concept and adding a new zone doesn't change anything. It will work by itself. My patchset can remove many hooks related to CMA area management in MM while solving the problems. More hooks are required to solve the problems if we choose MIGRATETYPE approach. Although Mel withdrew the review, Vlastimil expressed an agreement on this new zone approach [6]. "I realize I differ here from much more experienced mm guys, and will probably deservingly regret it later on, but I think that the ZONE_CMA approach could work indeed better than current MIGRATE_CMA pageblocks." If anyone has a different opinion, please let me know. Thanks. ***** PART 2 ***** There was a discussion with Mel [5] after LSF/MM 2016. I could summarise it to help merge decision but it's better to read by yourself since if I summarise it, it would be biased for me. But, if anyone hope the summary, I will do it. :) Anyway, Mel's position on this patchset seems to be neutral. He saids: "I'm not going to outright NAK your series but I won't ACK it either" We can fix the problems with any approach but I hope to go a new zone approach because it is less error-prone. It reduces some corner case handling for now and remove need for potential corner case handling to fix problems. Note that our company is already using ZONE_CMA and there is no problem. If anyone has a different opinion, please let me know and let's discuss together. Andrew, if there is something to do for merge, please let me know. ***** PART 3 ***** This series try to solve problems of current CMA implementation. CMA is introduced to provide physically contiguous pages at runtime without exclusive reserved memory area. But, current implementation works like as previous reserved memory approach, because freepages on CMA region are used only if there is no movable freepage. In other words, freepages on CMA region are only used as fallback. In that situation where freepages on CMA region are used as fallback, kswapd would be woken up easily since there is no unmovable and reclaimable freepage, too. If kswapd starts to reclaim memory, fallback allocation to MIGRATE_CMA doesn't occur any more since movable freepages are already refilled by kswapd and then most of freepage on CMA are left to be in free. This situation looks like exclusive reserved memory case. In my experiment, I found that if system memory has 1024 MB memory and 512 MB is reserved for CMA, kswapd is mostly woken up when roughly 512 MB free memory is left. Detailed reason is that for keeping enough free memory for unmovable and reclaimable allocation, kswapd uses below equation when calculating free memory and it easily go under the watermark. Free memory for unmovable and reclaimable = Free total - Free CMA pages This is derivated from the property of CMA freepage that CMA freepage can't be used for unmovable and reclaimable allocation. Anyway, in this case, kswapd are woken up when (FreeTotal - FreeCMA) is lower than low watermark and tries to make free memory until (FreeTotal - FreeCMA) is higher than high watermark. That results in that FreeTotal is moving around 512MB boundary consistently. It then means that we can't utilize full memory capacity. To fix this problem, I submitted some patches [1] about 10 months ago, but, found some more problems to be fixed before solving this problem. It requires many hooks in allocator hotpath so some developers doesn't like it. Instead, some of them suggest different approach [2] to fix all the problems related to CMA, that is, introducing a new zone to deal with free CMA pages. I agree that it is the best way to go so implement here. Although properties of ZONE_MOVABLE and ZONE_CMA is similar, I decide to add a new zone rather than piggyback on ZONE_MOVABLE since they have some differences. First, reserved CMA pages should not be offlined. If freepage for CMA is managed by ZONE_MOVABLE, we need to keep MIGRATE_CMA migratetype and insert many hooks on memory hotplug code to distiguish hotpluggable memory and reserved memory for CMA in the same zone. It would make memory hotplug code which is already complicated more complicated. Second, cma_alloc() can be called more frequently than memory hotplug operation and possibly we need to control allocation rate of ZONE_CMA to optimize latency in the future. In this case, separate zone approach is easy to modify. Third, I'd like to see statistics for CMA, separately. Sometimes, we need to debug why cma_alloc() is failed and separate statistics would be more helpful in this situtaion. Anyway, this patchset solves four problems related to CMA implementation. 1) Utilization problem As mentioned above, we can't utilize full memory capacity due to the limitation of CMA freepage and fallback policy. This patchset implements a new zone for CMA and uses it for GFP_HIGHUSER_MOVABLE request. This typed allocation is used for page cache and anonymous pages which occupies most of memory usage in normal case so we can utilize full memory capacity. Below is the experiment result about this problem. 8 CPUs, 1024 MB, VIRTUAL MACHINE make -j16 <Before this series> CMA reserve: 0 MB 512 MB Elapsed-time: 92.4 186.5 pswpin: 82 18647 pswpout: 160 69839 <After this series> CMA reserve: 0 MB 512 MB Elapsed-time: 93.1 93.4 pswpin: 84 46 pswpout: 183 92 FYI, there is another attempt [3] trying to solve this problem in lkml. And, as far as I know, Qualcomm also has out-of-tree solution for this problem. 2) Reclaim problem Currently, there is no logic to distinguish CMA pages in reclaim path. If reclaim is initiated for unmovable and reclaimable allocation, reclaiming CMA pages doesn't help to satisfy the request and reclaiming CMA page is just waste. By managing CMA pages in the new zone, we can skip to reclaim ZONE_CMA completely if it is unnecessary. 3) Atomic allocation failure problem Kswapd isn't started to reclaim pages when allocation request is movable type and there is enough free page in the CMA region. After bunch of consecutive movable allocation requests, free pages in ordinary region (not CMA region) would be exhausted without waking up kswapd. At that time, if atomic unmovable allocation comes, it can't be successful since there is not enough page in ordinary region. This problem is reported by Aneesh [4] and can be solved by this patchset. 4) Inefficiently work of compaction Usual high-order allocation request is unmovable type and it cannot be serviced from CMA area. In compaction, migration scanner doesn't distinguish migratable pages on the CMA area and do migration. In this case, even if we make high-order page on that region, it cannot be used due to type mismatch. This patch will solve this problem by separating CMA pages from ordinary zones. I passed boot test on x86_64, x86_32, arm and arm64. I did some stress tests on x86_64 and x86_32 and there is no problem. Feel free to enjoy and please give me a feedback. :) Thanks. [1] https://lkml.org/lkml/2014/5/28/64 [2] https://lkml.org/lkml/2014/11/4/55 [3] https://lkml.org/lkml/2014/10/15/623 [4] http://www.spinics.net/lists/linux-mm/msg100562.html [5] https://lkml.kernel.org/r/20160425053653.GA25662@js1304-P5Q-DELUXE [6] https://lkml.kernel.org/r/1919a85d-6e1e-374f-b8c3-1236c36b0393@suse.cz Joonsoo Kim (7): mm/page_alloc: don't reserve ZONE_HIGHMEM for ZONE_MOVABLE request mm/cma: introduce new zone, ZONE_CMA mm/cma: populate ZONE_CMA mm/cma: remove ALLOC_CMA mm/cma: remove MIGRATE_CMA mm/cma: remove per zone CMA stat ARM: CMA: avoid re-mapping CMA region if CONFIG_HIGHMEM arch/arm/mm/dma-mapping.c | 7 +- arch/powerpc/mm/mmu_context_iommu.c | 2 +- arch/x86/mm/highmem_32.c | 8 ++ fs/proc/meminfo.c | 2 +- include/linux/cma.h | 7 ++ include/linux/gfp.h | 32 +++--- include/linux/memory_hotplug.h | 3 - include/linux/mempolicy.h | 2 +- include/linux/mm.h | 1 + include/linux/mmzone.h | 60 +++++----- include/linux/page-isolation.h | 5 +- include/linux/vm_event_item.h | 10 +- include/linux/vmstat.h | 8 -- include/trace/events/mmflags.h | 10 +- kernel/power/snapshot.c | 8 ++ mm/cma.c | 78 +++++++++++-- mm/compaction.c | 12 +- mm/hugetlb.c | 3 +- mm/internal.h | 4 +- mm/memory_hotplug.c | 7 +- mm/page_alloc.c | 220 ++++++++++++++++++------------------ mm/page_isolation.c | 15 +-- mm/page_owner.c | 6 +- mm/usercopy.c | 4 +- mm/vmstat.c | 10 +- 25 files changed, 310 insertions(+), 214 deletions(-) -- 2.7.4
[toc] | [next] | [standalone]
| From | js1304@gmail.com |
|---|---|
| Date | 2017-04-11 05:20 +0200 |
| Subject | [PATCH v7 7/7] ARM: CMA: avoid re-mapping CMA region if CONFIG_HIGHMEM |
| Message-ID | <tuUvw-1sy-17@gated-at.bofh.it> |
| In reply to | #1620863 |
From: Joonsoo Kim <iamjoonsoo.kim@lge.com> CMA region is now managed by the separate zone, ZONE_CMA, to fix many MM related problems. In this implementation, it is possible that ZONE_CMA contains two CMA regions that are on the both, lowmem and highmem, respectively. To handle this case properly, ZONE_CMA is considered as highmem. In dma_contiguous_remap(), mapping for CMA region on lowmem is cleared and remapped for DMA, but, in the new CMA implementation, remap isn't needed since the region is considered as highmem. And, remap should not be allowed since it would cause cache problems. So, this patch disables it. Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com> --- arch/arm/mm/dma-mapping.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 475811f..377053a 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -506,7 +506,12 @@ void __init dma_contiguous_remap(void) flush_tlb_kernel_range(__phys_to_virt(start), __phys_to_virt(end)); - iotable_init(&map, 1); + /* + * For highmem system, all the memory in CMA region will be + * considered as highmem, therefore, re-mapping isn't required. + */ + if (!IS_ENABLED(CONFIG_HIGHMEM)) + iotable_init(&map, 1); } } -- 2.7.4
[toc] | [prev] | [next] | [standalone]
| From | js1304@gmail.com |
|---|---|
| Date | 2017-04-11 05:20 +0200 |
| Subject | [PATCH v7 5/7] mm/cma: remove MIGRATE_CMA |
| Message-ID | <tuUvx-1sy-19@gated-at.bofh.it> |
| In reply to | #1620863 |
From: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Now, all reserved pages for CMA region are belong to the ZONE_CMA
and there is no other type of pages. Therefore, we don't need to
use MIGRATE_CMA to distinguish and handle differently for CMA pages
and ordinary pages. Remove MIGRATE_CMA.
Unfortunately, this patch make free CMA counter incorrect because
we count it when pages are on the MIGRATE_CMA. It will be fixed
by next patch. I can squash next patch here but it makes changes
complicated and hard to review so I separate that.
Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
---
arch/powerpc/mm/mmu_context_iommu.c | 2 +-
include/linux/gfp.h | 2 +-
include/linux/mmzone.h | 26 +----------
include/linux/page-isolation.h | 5 +--
include/linux/vmstat.h | 8 ----
mm/cma.c | 3 +-
mm/compaction.c | 8 +---
mm/hugetlb.c | 3 +-
mm/memory_hotplug.c | 7 ++-
mm/page_alloc.c | 86 ++++++++++---------------------------
mm/page_isolation.c | 15 +++----
mm/page_owner.c | 6 +--
mm/usercopy.c | 4 +-
13 files changed, 43 insertions(+), 132 deletions(-)
diff --git a/arch/powerpc/mm/mmu_context_iommu.c b/arch/powerpc/mm/mmu_context_iommu.c
index fc67bd7..330c495 100644
--- a/arch/powerpc/mm/mmu_context_iommu.c
+++ b/arch/powerpc/mm/mmu_context_iommu.c
@@ -184,7 +184,7 @@ long mm_iommu_get(struct mm_struct *mm, unsigned long ua, unsigned long entries,
* of the CMA zone if possible. NOTE: faulting in + migration
* can be expensive. Batching can be considered later
*/
- if (is_migrate_cma_page(page)) {
+ if (is_zone_cma(page_zone(page))) {
if (mm_iommu_move_page_from_cma(page))
goto populate;
if (1 != get_user_pages_fast(ua + (i << PAGE_SHIFT),
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index c2ed2eb..15987cc 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -563,7 +563,7 @@ static inline bool pm_suspended_storage(void)
#if (defined(CONFIG_MEMORY_ISOLATION) && defined(CONFIG_COMPACTION)) || defined(CONFIG_CMA)
/* The below functions must be run on a range from a single zone. */
extern int alloc_contig_range(unsigned long start, unsigned long end,
- unsigned migratetype, gfp_t gfp_mask);
+ gfp_t gfp_mask);
extern void free_contig_range(unsigned long pfn, unsigned nr_pages);
#endif
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 74eda07..efb69b1 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -41,22 +41,6 @@ enum migratetype {
MIGRATE_RECLAIMABLE,
MIGRATE_PCPTYPES, /* the number of types on the pcp lists */
MIGRATE_HIGHATOMIC = MIGRATE_PCPTYPES,
-#ifdef CONFIG_CMA
- /*
- * MIGRATE_CMA migration type is designed to mimic the way
- * ZONE_MOVABLE works. Only movable pages can be allocated
- * from MIGRATE_CMA pageblocks and page allocator never
- * implicitly change migration type of MIGRATE_CMA pageblock.
- *
- * The way to use it is to change migratetype of a range of
- * pageblocks to MIGRATE_CMA which can be done by
- * __free_pageblock_cma() function. What is important though
- * is that a range of pageblocks must be aligned to
- * MAX_ORDER_NR_PAGES should biggest page be bigger then
- * a single pageblock.
- */
- MIGRATE_CMA,
-#endif
#ifdef CONFIG_MEMORY_ISOLATION
MIGRATE_ISOLATE, /* can't allocate from here */
#endif
@@ -66,17 +50,9 @@ enum migratetype {
/* In mm/page_alloc.c; keep in sync also with show_migration_types() there */
extern char * const migratetype_names[MIGRATE_TYPES];
-#ifdef CONFIG_CMA
-# define is_migrate_cma(migratetype) unlikely((migratetype) == MIGRATE_CMA)
-# define is_migrate_cma_page(_page) (get_pageblock_migratetype(_page) == MIGRATE_CMA)
-#else
-# define is_migrate_cma(migratetype) false
-# define is_migrate_cma_page(_page) false
-#endif
-
static inline bool is_migrate_movable(int mt)
{
- return is_migrate_cma(mt) || mt == MIGRATE_MOVABLE;
+ return mt == MIGRATE_MOVABLE;
}
#define for_each_migratetype_order(order, type) \
diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
index d4cd201..67735f2 100644
--- a/include/linux/page-isolation.h
+++ b/include/linux/page-isolation.h
@@ -46,15 +46,14 @@ int move_freepages_block(struct zone *zone, struct page *page,
*/
int
start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
- unsigned migratetype, bool skip_hwpoisoned_pages);
+ bool skip_hwpoisoned_pages);
/*
* Changes MIGRATE_ISOLATE to MIGRATE_MOVABLE.
* target range is [start_pfn, end_pfn)
*/
int
-undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
- unsigned migratetype);
+undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn);
/*
* Test all pages in [start_pfn, end_pfn) are isolated or not.
diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h
index 6137719..ac6db88 100644
--- a/include/linux/vmstat.h
+++ b/include/linux/vmstat.h
@@ -341,14 +341,6 @@ static inline void drain_zonestat(struct zone *zone,
struct per_cpu_pageset *pset) { }
#endif /* CONFIG_SMP */
-static inline void __mod_zone_freepage_state(struct zone *zone, int nr_pages,
- int migratetype)
-{
- __mod_zone_page_state(zone, NR_FREE_PAGES, nr_pages);
- if (is_migrate_cma(migratetype))
- __mod_zone_page_state(zone, NR_FREE_CMA_PAGES, nr_pages);
-}
-
extern const char * const vmstat_text[];
#endif /* _LINUX_VMSTAT_H */
diff --git a/mm/cma.c b/mm/cma.c
index 6d8bd300..91dd85a 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -479,8 +479,7 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align,
pfn = cma->base_pfn + (bitmap_no << cma->order_per_bit);
mutex_lock(&cma_mutex);
- ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA,
- gfp_mask);
+ ret = alloc_contig_range(pfn, pfn + count, gfp_mask);
mutex_unlock(&cma_mutex);
if (ret == 0) {
page = pfn_to_page(pfn);
diff --git a/mm/compaction.c b/mm/compaction.c
index 80b1424..f6ae10f 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -1017,7 +1017,7 @@ static bool suitable_migration_target(struct compact_control *cc,
if (cc->ignore_block_suitable)
return true;
- /* If the block is MIGRATE_MOVABLE or MIGRATE_CMA, allow migration */
+ /* If the block is MIGRATE_MOVABLE, allow migration */
if (is_migrate_movable(get_pageblock_migratetype(page)))
return true;
@@ -1338,12 +1338,6 @@ static enum compact_result __compact_finished(struct zone *zone,
if (!list_empty(&area->free_list[migratetype]))
return COMPACT_SUCCESS;
-#ifdef CONFIG_CMA
- /* MIGRATE_MOVABLE can fallback on MIGRATE_CMA */
- if (migratetype == MIGRATE_MOVABLE &&
- !list_empty(&area->free_list[MIGRATE_CMA]))
- return COMPACT_SUCCESS;
-#endif
/*
* Job done if allocation would steal freepages from
* other migratetype buddy lists.
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index e582887..d26c837 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1053,8 +1053,7 @@ static int __alloc_gigantic_page(unsigned long start_pfn,
unsigned long nr_pages)
{
unsigned long end_pfn = start_pfn + nr_pages;
- return alloc_contig_range(start_pfn, end_pfn, MIGRATE_MOVABLE,
- GFP_KERNEL);
+ return alloc_contig_range(start_pfn, end_pfn, GFP_KERNEL);
}
static bool pfn_range_valid_gigantic(struct zone *z,
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 76d4745..c48c36f 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -1897,8 +1897,7 @@ static int __ref __offline_pages(unsigned long start_pfn,
return -EINVAL;
/* set above range as isolated */
- ret = start_isolate_page_range(start_pfn, end_pfn,
- MIGRATE_MOVABLE, true);
+ ret = start_isolate_page_range(start_pfn, end_pfn, true);
if (ret)
return ret;
@@ -1968,7 +1967,7 @@ static int __ref __offline_pages(unsigned long start_pfn,
We cannot do rollback at this point. */
offline_isolated_pages(start_pfn, end_pfn);
/* reset pagetype flags and makes migrate type to be MOVABLE */
- undo_isolate_page_range(start_pfn, end_pfn, MIGRATE_MOVABLE);
+ undo_isolate_page_range(start_pfn, end_pfn);
/* removal success */
adjust_managed_page_count(pfn_to_page(start_pfn), -offlined_pages);
zone->present_pages -= offlined_pages;
@@ -2005,7 +2004,7 @@ static int __ref __offline_pages(unsigned long start_pfn,
((unsigned long long) end_pfn << PAGE_SHIFT) - 1);
memory_notify(MEM_CANCEL_OFFLINE, &arg);
/* pushback to free area */
- undo_isolate_page_range(start_pfn, end_pfn, MIGRATE_MOVABLE);
+ undo_isolate_page_range(start_pfn, end_pfn);
return ret;
}
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 18f16bf..33a1b69 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -136,8 +136,8 @@ gfp_t gfp_allowed_mask __read_mostly = GFP_BOOT_MASK;
* put on a pcplist. Used to avoid the pageblock migratetype lookup when
* freeing from pcplists in most cases, at the cost of possibly becoming stale.
* Also the migratetype set in the page does not necessarily match the pcplist
- * index, e.g. page might have MIGRATE_CMA set but be on a pcplist with any
- * other index - this ensures that it will be put on the correct CMA freelist.
+ * index, e.g. page might have MIGRATE_MOVABLE set but be on a pcplist with any
+ * other index - this ensures that it will be put on the correct freelist.
*/
static inline int get_pcppage_migratetype(struct page *page)
{
@@ -247,9 +247,6 @@ char * const migratetype_names[MIGRATE_TYPES] = {
"Movable",
"Reclaimable",
"HighAtomic",
-#ifdef CONFIG_CMA
- "CMA",
-#endif
#ifdef CONFIG_MEMORY_ISOLATION
"Isolate",
#endif
@@ -681,7 +678,7 @@ static inline bool set_page_guard(struct zone *zone, struct page *page,
INIT_LIST_HEAD(&page->lru);
set_page_private(page, order);
/* Guard pages are not available for any usage */
- __mod_zone_freepage_state(zone, -(1 << order), migratetype);
+ __mod_zone_page_state(zone, NR_FREE_PAGES, -(1 << order));
return true;
}
@@ -702,7 +699,7 @@ static inline void clear_page_guard(struct zone *zone, struct page *page,
set_page_private(page, 0);
if (!is_migrate_isolate(migratetype))
- __mod_zone_freepage_state(zone, (1 << order), migratetype);
+ __mod_zone_page_state(zone, NR_FREE_PAGES, (1 << order));
}
#else
struct page_ext_operations debug_guardpage_ops;
@@ -809,7 +806,7 @@ static inline void __free_one_page(struct page *page,
VM_BUG_ON(migratetype == -1);
if (likely(!is_migrate_isolate(migratetype)))
- __mod_zone_freepage_state(zone, 1 << order, migratetype);
+ __mod_zone_page_state(zone, NR_FREE_PAGES, 1 << order);
VM_BUG_ON_PAGE(pfn & ((1 << order) - 1), page);
VM_BUG_ON_PAGE(bad_range(zone, page), page);
@@ -1591,7 +1588,7 @@ static void __init adjust_present_page_count(struct page *page, long count)
zone->present_pages += count;
}
-/* Free whole pageblock and set its migration type to MIGRATE_CMA. */
+/* Free whole pageblock and set its migration type to MIGRATE_MOVABLE. */
void __init init_cma_reserved_pageblock(struct page *page)
{
unsigned i = pageblock_nr_pages;
@@ -1616,7 +1613,7 @@ void __init init_cma_reserved_pageblock(struct page *page)
adjust_present_page_count(page, pageblock_nr_pages);
- set_pageblock_migratetype(page, MIGRATE_CMA);
+ set_pageblock_migratetype(page, MIGRATE_MOVABLE);
if (pageblock_order >= MAX_ORDER) {
i = pageblock_nr_pages;
@@ -1836,25 +1833,11 @@ static int fallbacks[MIGRATE_TYPES][4] = {
[MIGRATE_UNMOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_MOVABLE, MIGRATE_TYPES },
[MIGRATE_RECLAIMABLE] = { MIGRATE_UNMOVABLE, MIGRATE_MOVABLE, MIGRATE_TYPES },
[MIGRATE_MOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE, MIGRATE_TYPES },
-#ifdef CONFIG_CMA
- [MIGRATE_CMA] = { MIGRATE_TYPES }, /* Never used */
-#endif
#ifdef CONFIG_MEMORY_ISOLATION
[MIGRATE_ISOLATE] = { MIGRATE_TYPES }, /* Never used */
#endif
};
-#ifdef CONFIG_CMA
-static struct page *__rmqueue_cma_fallback(struct zone *zone,
- unsigned int order)
-{
- return __rmqueue_smallest(zone, order, MIGRATE_CMA);
-}
-#else
-static inline struct page *__rmqueue_cma_fallback(struct zone *zone,
- unsigned int order) { return NULL; }
-#endif
-
/*
* Move the free pages in a range to the free lists of the requested type.
* Note that start_page and end_pages are not aligned on a pageblock
@@ -2122,8 +2105,7 @@ static void reserve_highatomic_pageblock(struct page *page, struct zone *zone,
/* Yoink! */
mt = get_pageblock_migratetype(page);
- if (!is_migrate_highatomic(mt) && !is_migrate_isolate(mt)
- && !is_migrate_cma(mt)) {
+ if (!is_migrate_highatomic(mt) && !is_migrate_isolate(mt)) {
zone->nr_reserved_highatomic += pageblock_nr_pages;
set_pageblock_migratetype(page, MIGRATE_HIGHATOMIC);
move_freepages_block(zone, page, MIGRATE_HIGHATOMIC, NULL);
@@ -2267,13 +2249,8 @@ static struct page *__rmqueue(struct zone *zone, unsigned int order,
retry:
page = __rmqueue_smallest(zone, order, migratetype);
- if (unlikely(!page)) {
- if (migratetype == MIGRATE_MOVABLE)
- page = __rmqueue_cma_fallback(zone, order);
-
- if (!page && __rmqueue_fallback(zone, order, migratetype))
- goto retry;
- }
+ if (unlikely(!page) && __rmqueue_fallback(zone, order, migratetype))
+ goto retry;
trace_mm_page_alloc_zone_locked(page, order, migratetype);
return page;
@@ -2315,9 +2292,6 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
list_add_tail(&page->lru, list);
list = &page->lru;
alloced++;
- if (is_migrate_cma(get_pcppage_migratetype(page)))
- __mod_zone_page_state(zone, NR_FREE_CMA_PAGES,
- -(1 << order));
}
/*
@@ -2667,7 +2641,7 @@ int __isolate_free_page(struct page *page, unsigned int order)
if (!zone_watermark_ok(zone, 0, watermark, 0, 0))
return 0;
- __mod_zone_freepage_state(zone, -(1UL << order), mt);
+ __mod_zone_page_state(zone, NR_FREE_PAGES, -(1UL << order));
}
/* Remove page from free list */
@@ -2683,8 +2657,8 @@ int __isolate_free_page(struct page *page, unsigned int order)
struct page *endpage = page + (1 << order) - 1;
for (; page < endpage; page += pageblock_nr_pages) {
int mt = get_pageblock_migratetype(page);
- if (!is_migrate_isolate(mt) && !is_migrate_cma(mt)
- && !is_migrate_highatomic(mt))
+ if (!is_migrate_isolate(mt) &&
+ !is_migrate_highatomic(mt))
set_pageblock_migratetype(page,
MIGRATE_MOVABLE);
}
@@ -2807,8 +2781,7 @@ struct page *rmqueue(struct zone *preferred_zone,
spin_unlock(&zone->lock);
if (!page)
goto failed;
- __mod_zone_freepage_state(zone, -(1 << order),
- get_pcppage_migratetype(page));
+ __mod_zone_page_state(zone, NR_FREE_PAGES, -(1 << order));
__count_zid_vm_events(PGALLOC, page_zonenum(page), 1 << order);
zone_statistics(preferred_zone, zone);
@@ -2958,11 +2931,6 @@ bool __zone_watermark_ok(struct zone *z, unsigned int order, unsigned long mark,
if (!list_empty(&area->free_list[mt]))
return true;
}
-
-#ifdef CONFIG_CMA
- if (!list_empty(&area->free_list[MIGRATE_CMA]))
- return true;
-#endif
}
return false;
}
@@ -4469,9 +4437,6 @@ static void show_migration_types(unsigned char type)
[MIGRATE_MOVABLE] = 'M',
[MIGRATE_RECLAIMABLE] = 'E',
[MIGRATE_HIGHATOMIC] = 'H',
-#ifdef CONFIG_CMA
- [MIGRATE_CMA] = 'C',
-#endif
#ifdef CONFIG_MEMORY_ISOLATION
[MIGRATE_ISOLATE] = 'I',
#endif
@@ -7361,7 +7326,7 @@ bool has_unmovable_pages(struct zone *zone, struct page *page, int count,
if (zone_idx(zone) == ZONE_MOVABLE || is_zone_cma(zone))
return false;
mt = get_pageblock_migratetype(page);
- if (mt == MIGRATE_MOVABLE || is_migrate_cma(mt))
+ if (mt == MIGRATE_MOVABLE)
return false;
pfn = page_to_pfn(page);
@@ -7512,16 +7477,12 @@ static int __alloc_contig_migrate_range(struct compact_control *cc,
* alloc_contig_range() -- tries to allocate given range of pages
* @start: start PFN to allocate
* @end: one-past-the-last PFN to allocate
- * @migratetype: migratetype of the underlaying pageblocks (either
- * #MIGRATE_MOVABLE or #MIGRATE_CMA). All pageblocks
- * in range must have the same migratetype and it must
- * be either of the two.
* @gfp_mask: GFP mask to use during compaction
*
* The PFN range does not have to be pageblock or MAX_ORDER_NR_PAGES
* aligned, however it's the caller's responsibility to guarantee that
* we are the only thread that changes migrate type of pageblocks the
- * pages fall in.
+ * pages fall in and it should be MIGRATE_MOVABLE.
*
* The PFN range must belong to a single zone.
*
@@ -7530,7 +7491,7 @@ static int __alloc_contig_migrate_range(struct compact_control *cc,
* need to be freed with free_contig_range().
*/
int alloc_contig_range(unsigned long start, unsigned long end,
- unsigned migratetype, gfp_t gfp_mask)
+ gfp_t gfp_mask)
{
unsigned long outer_start, outer_end;
unsigned int order;
@@ -7564,15 +7525,14 @@ int alloc_contig_range(unsigned long start, unsigned long end,
* allocator removing them from the buddy system. This way
* page allocator will never consider using them.
*
- * This lets us mark the pageblocks back as
- * MIGRATE_CMA/MIGRATE_MOVABLE so that free pages in the
- * aligned range but not in the unaligned, original range are
- * put back to page allocator so that buddy can use them.
+ * This lets us mark the pageblocks back as MIGRATE_MOVABLE
+ * so that free pages in the aligned range but not in the
+ * unaligned, original range are put back to page allocator
+ * so that buddy can use them.
*/
ret = start_isolate_page_range(pfn_max_align_down(start),
- pfn_max_align_up(end), migratetype,
- false);
+ pfn_max_align_up(end), false);
if (ret)
return ret;
@@ -7650,7 +7610,7 @@ int alloc_contig_range(unsigned long start, unsigned long end,
done:
undo_isolate_page_range(pfn_max_align_down(start),
- pfn_max_align_up(end), migratetype);
+ pfn_max_align_up(end));
return ret;
}
diff --git a/mm/page_isolation.c b/mm/page_isolation.c
index 5092e4e..312f2f6 100644
--- a/mm/page_isolation.c
+++ b/mm/page_isolation.c
@@ -62,14 +62,13 @@ static int set_migratetype_isolate(struct page *page,
out:
if (!ret) {
unsigned long nr_pages;
- int migratetype = get_pageblock_migratetype(page);
set_pageblock_migratetype(page, MIGRATE_ISOLATE);
zone->nr_isolate_pageblock++;
nr_pages = move_freepages_block(zone, page, MIGRATE_ISOLATE,
NULL);
- __mod_zone_freepage_state(zone, -nr_pages, migratetype);
+ __mod_zone_page_state(zone, NR_FREE_PAGES, -nr_pages);
}
spin_unlock_irqrestore(&zone->lock, flags);
@@ -122,7 +121,7 @@ static void unset_migratetype_isolate(struct page *page, unsigned migratetype)
*/
if (!isolated_page) {
nr_pages = move_freepages_block(zone, page, migratetype, NULL);
- __mod_zone_freepage_state(zone, nr_pages, migratetype);
+ __mod_zone_page_state(zone, NR_FREE_PAGES, nr_pages);
}
set_pageblock_migratetype(page, migratetype);
zone->nr_isolate_pageblock--;
@@ -151,7 +150,6 @@ __first_valid_page(unsigned long pfn, unsigned long nr_pages)
* to be MIGRATE_ISOLATE.
* @start_pfn: The lower PFN of the range to be isolated.
* @end_pfn: The upper PFN of the range to be isolated.
- * @migratetype: migrate type to set in error recovery.
*
* Making page-allocation-type to be MIGRATE_ISOLATE means free pages in
* the range will never be allocated. Any free pages and pages freed in the
@@ -161,7 +159,7 @@ __first_valid_page(unsigned long pfn, unsigned long nr_pages)
* Returns 0 on success and -EBUSY if any part of range cannot be isolated.
*/
int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
- unsigned migratetype, bool skip_hwpoisoned_pages)
+ bool skip_hwpoisoned_pages)
{
unsigned long pfn;
unsigned long undo_pfn;
@@ -185,7 +183,7 @@ int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
for (pfn = start_pfn;
pfn < undo_pfn;
pfn += pageblock_nr_pages)
- unset_migratetype_isolate(pfn_to_page(pfn), migratetype);
+ unset_migratetype_isolate(pfn_to_page(pfn), MIGRATE_MOVABLE);
return -EBUSY;
}
@@ -193,8 +191,7 @@ int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
/*
* Make isolated pages available again.
*/
-int undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
- unsigned migratetype)
+int undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn)
{
unsigned long pfn;
struct page *page;
@@ -208,7 +205,7 @@ int undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
page = __first_valid_page(pfn, pageblock_nr_pages);
if (!page || !is_migrate_isolate_page(page))
continue;
- unset_migratetype_isolate(page, migratetype);
+ unset_migratetype_isolate(page, MIGRATE_MOVABLE);
}
return 0;
}
diff --git a/mm/page_owner.c b/mm/page_owner.c
index c3cee24..4016815 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -299,11 +299,7 @@ void pagetypeinfo_showmixedcount_print(struct seq_file *m,
page_mt = gfpflags_to_migratetype(
page_owner->gfp_mask);
if (pageblock_mt != page_mt) {
- if (is_migrate_cma(pageblock_mt))
- count[MIGRATE_MOVABLE]++;
- else
- count[pageblock_mt]++;
-
+ count[pageblock_mt]++;
pfn = block_end_pfn;
break;
}
diff --git a/mm/usercopy.c b/mm/usercopy.c
index a9852b2..f0a2c8f 100644
--- a/mm/usercopy.c
+++ b/mm/usercopy.c
@@ -179,7 +179,7 @@ static inline const char *check_page_span(const void *ptr, unsigned long n,
* several independently allocated pages.
*/
is_reserved = PageReserved(page);
- is_cma = is_migrate_cma_page(page);
+ is_cma = is_zone_cma(page_zone(page));
if (!is_reserved && !is_cma)
return "<spans multiple pages>";
@@ -187,7 +187,7 @@ static inline const char *check_page_span(const void *ptr, unsigned long n,
page = virt_to_head_page(ptr);
if (is_reserved && !PageReserved(page))
return "<spans Reserved and non-Reserved pages>";
- if (is_cma && !is_migrate_cma_page(page))
+ if (is_cma && !is_zone_cma(page_zone(page)))
return "<spans CMA and non-CMA pages>";
}
#endif
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Michal Hocko <mhocko@kernel.org> |
|---|---|
| Date | 2017-04-11 20:20 +0200 |
| Message-ID | <tv8yu-27K-15@gated-at.bofh.it> |
| In reply to | #1620863 |
Hi, I didn't get to read though patches yet but the cover letter didn't really help me to understand the basic concepts to have a good starting point before diving into implementation details. It contains a lot of history remarks which is not bad but IMHO too excessive here. I would appreciate the following information (some of that is already provided in the cover but could benefit from some rewording/text reorganization). - what is ZONE_CMA and how it is configured (from admin POV) - how does ZONE_CMA compare to other zones - who is allowed to allocate from this zone and what are the guarantees/requirements for successful allocation - how does the zone compare to a preallocate allocation pool - how is ZONE_CMA balanced/reclaimed due to internal memory pressure (from CMA users) - is this zone reclaimable for the global memory reclaim - why this was/is controversial -- Michal Hocko SUSE Labs
[toc] | [prev] | [next] | [standalone]
| From | Joonsoo Kim <js1304@gmail.com> |
|---|---|
| Date | 2017-04-12 03:40 +0200 |
| Message-ID | <tvfqh-6rL-1@gated-at.bofh.it> |
| In reply to | #1621525 |
On Tue, Apr 11, 2017 at 08:15:20PM +0200, Michal Hocko wrote: > Hi, > I didn't get to read though patches yet but the cover letter didn't > really help me to understand the basic concepts to have a good starting > point before diving into implementation details. It contains a lot of > history remarks which is not bad but IMHO too excessive here. I would > appreciate the following information (some of that is already provided > in the cover but could benefit from some rewording/text reorganization). > > - what is ZONE_CMA and how it is configured (from admin POV) > - how does ZONE_CMA compare to other zones > - who is allowed to allocate from this zone and what are the > guarantees/requirements for successful allocation > - how does the zone compare to a preallocate allocation pool > - how is ZONE_CMA balanced/reclaimed due to internal memory pressure > (from CMA users) > - is this zone reclaimable for the global memory reclaim > - why this was/is controversial Hello, I hope that following summary helps you to understand this patchset. I skip some basic things about CMA. I will attach this description to the cover-letter if re-spin is needed. 1. What is ZONE_CMA ZONE_CMA is a newly introduced zone that manages freepages in CMA areas. Previously, freepages in CMA areas are in the ordinary zone and managed/distinguished by the special migratetype, MIGRATE_CMA. However, it causes too many subtle problems and fixing all the problems due to it seems to be impossible and too intrusive to MM subsystem. Therefore, different solution is requested and this is the outcome of this request. Problem details are described in PART 3. There is no change in admin POV. It is just implementation detail. If the kernel is congifured to use CMA, it is managed by MM like as before except pages are now belong to the separate zone, ZONE_CMA. 2. How does ZONE_CMA compare to other zones ZONE_CMA is conceptually the same with ZONE_MOVABLE. There is a software constraint to guarantee the success of future allocation request from the device. If the device requests the specific range of the memory in CMA area at the runtime, page that allocated by MM will be migrated to the other page and it will be returned to the device. To guarantee it, ZONE_CMA only takes the allocation request with GFP_MOVABLE. The other important point about ZONE_CMA is that span of ZONE_CMA would be overlapped with the other zone. This is not new to MM subsystem and MM subsystem has enough logic to handle such situation so there would be no problem. Other things are completely the same with other zones. For MM POV, there is no difference in allocation process except that it only takes GFP_MOVABLE request. In reclaim, pages that are allocated by MM will be reclaimed by the same policy of the MM. So, no difference. This 'no difference' is a strong point of this approach. ZONE_CMA is naturally handled by MM subsystem unlike as before (special handling is required for MIGRATE_CMA). 3. Controversial Point Major concern from Mel is that zone concept is abused. ZONE is originally introduced to solve some issues due to H/W addressing limitation. However, from the age of ZONE_MOVABLE, ZONE is used to solve the issues due to S/W limitation. This S/W limitation causes highmem/lowmem problem that is some of memory cannot be usable for kernel memory and LRU ordering would be broken easily. My major objection to this point is that this problem isn't related to implementation detail like as ZONE. Problems just comes from S/W limitation that we cannot use this memory for kernel memory to guarantee offlining the memory (ZONE_MOVABLE) or allocation from the device (ZONE_CMA) in the future. See PART 1 for more information. Thanks.
[toc] | [prev] | [next] | [standalone]
| From | Michal Hocko <mhocko@kernel.org> |
|---|---|
| Date | 2017-04-13 14:00 +0200 |
| Message-ID | <tvLzP-2vl-1@gated-at.bofh.it> |
| In reply to | #1621737 |
On Wed 12-04-17 10:35:06, Joonsoo Kim wrote: > On Tue, Apr 11, 2017 at 08:15:20PM +0200, Michal Hocko wrote: > > Hi, > > I didn't get to read though patches yet but the cover letter didn't > > really help me to understand the basic concepts to have a good starting > > point before diving into implementation details. It contains a lot of > > history remarks which is not bad but IMHO too excessive here. I would > > appreciate the following information (some of that is already provided > > in the cover but could benefit from some rewording/text reorganization). > > > > - what is ZONE_CMA and how it is configured (from admin POV) > > - how does ZONE_CMA compare to other zones > > - who is allowed to allocate from this zone and what are the > > guarantees/requirements for successful allocation > > - how does the zone compare to a preallocate allocation pool > > - how is ZONE_CMA balanced/reclaimed due to internal memory pressure > > (from CMA users) > > - is this zone reclaimable for the global memory reclaim > > - why this was/is controversial > > Hello, > > I hope that following summary helps you to understand this patchset. > I skip some basic things about CMA. I will attach this description to > the cover-letter if re-spin is needed. I believe that sorting out these questions is more important than what you have in the current cover letter. Andrew tends to fold the cover into the first patch so I think you should update. > 2. How does ZONE_CMA compare to other zones > > ZONE_CMA is conceptually the same with ZONE_MOVABLE. There is a software > constraint to guarantee the success of future allocation request from > the device. If the device requests the specific range of the memory in CMA > area at the runtime, page that allocated by MM will be migrated to > the other page and it will be returned to the device. To guarantee it, > ZONE_CMA only takes the allocation request with GFP_MOVABLE. The immediate follow up question is. Why cannot we reuse ZONE_MOVABLE for that purpose? > The other important point about ZONE_CMA is that span of ZONE_CMA would be > overlapped with the other zone. This is not new to MM subsystem and > MM subsystem has enough logic to handle such situation > so there would be no problem. I am not really sure this is actually true. Zones are disjoint from the early beginning. I remember that we had something like numa nodes interleaving but that is such a rare configuration that I wouldn't be surprised if it wasn't very well tested and actually broken in some subtle ways. There are many page_zone(page) != zone checks sprinkled in the code but I do not see anything consistent there. Similarly pageblock_pfn_to_page is only used by compaction but there are other pfn walkers which do ad-hoc checking. I was staring into that code these days due to my hotplug patches. That being said, I think that interleaving zones are an interesting concept but I would be rather nervous to consider this as working currently without a deeper review. > Other things are completely the same with other zones. For MM POV, there is > no difference in allocation process except that it only takes > GFP_MOVABLE request. In reclaim, pages that are allocated by MM will > be reclaimed by the same policy of the MM. So, no difference. OK, so essentially this is yet another "highmem" zone. We already know that only GFP_MOVABLE are allowed to fallback to ZONE_CMA but do CMA allocations fallback to other zones and punch new holes? In which zone order? > This 'no difference' is a strong point of this approach. ZONE_CMA is > naturally handled by MM subsystem unlike as before (special handling is > required for MIGRATE_CMA). > > 3. Controversial Point > > Major concern from Mel is that zone concept is abused. ZONE is originally > introduced to solve some issues due to H/W addressing limitation. Yes, very much agreed on that. You basically want to punch holes into other zones to guarantee an allocation progress. Marking those wholes with special migrate type sounds quite natural but I will have to study the current code some more to see whether issues you mention are inherently unfixable. This might very well turn out to be the case. > However, from the age of ZONE_MOVABLE, ZONE is used to solve the issues > due to S/W limitation. copying ZONE_MOVABLE pattern doesn't sound all that great to me to be honest. > This S/W limitation causes highmem/lowmem problem > that is some of memory cannot be usable for kernel memory and LRU ordering > would be broken easily. My major objection to this point is that > this problem isn't related to implementation detail like as ZONE. yes, agreement on that. > Problems just comes from S/W limitation that we cannot use this memory > for kernel memory to guarantee offlining the memory (ZONE_MOVABLE) or > allocation from the device (ZONE_CMA) in the future. See PART 1 for > more information. -- Michal Hocko SUSE Labs
[toc] | [prev] | [next] | [standalone]
| From | Joonsoo Kim <js1304@gmail.com> |
|---|---|
| Date | 2017-04-17 04:10 +0200 |
| Message-ID | <tx4h4-31r-1@gated-at.bofh.it> |
| In reply to | #1622951 |
On Thu, Apr 13, 2017 at 01:56:15PM +0200, Michal Hocko wrote: > On Wed 12-04-17 10:35:06, Joonsoo Kim wrote: > > On Tue, Apr 11, 2017 at 08:15:20PM +0200, Michal Hocko wrote: > > > Hi, > > > I didn't get to read though patches yet but the cover letter didn't > > > really help me to understand the basic concepts to have a good starting > > > point before diving into implementation details. It contains a lot of > > > history remarks which is not bad but IMHO too excessive here. I would > > > appreciate the following information (some of that is already provided > > > in the cover but could benefit from some rewording/text reorganization). > > > > > > - what is ZONE_CMA and how it is configured (from admin POV) > > > - how does ZONE_CMA compare to other zones > > > - who is allowed to allocate from this zone and what are the > > > guarantees/requirements for successful allocation > > > - how does the zone compare to a preallocate allocation pool > > > - how is ZONE_CMA balanced/reclaimed due to internal memory pressure > > > (from CMA users) > > > - is this zone reclaimable for the global memory reclaim > > > - why this was/is controversial > > > > Hello, > > > > I hope that following summary helps you to understand this patchset. > > I skip some basic things about CMA. I will attach this description to > > the cover-letter if re-spin is needed. > > I believe that sorting out these questions is more important than what > you have in the current cover letter. Andrew tends to fold the cover > into the first patch so I think you should update. Okay. > > 2. How does ZONE_CMA compare to other zones > > > > ZONE_CMA is conceptually the same with ZONE_MOVABLE. There is a software > > constraint to guarantee the success of future allocation request from > > the device. If the device requests the specific range of the memory in CMA > > area at the runtime, page that allocated by MM will be migrated to > > the other page and it will be returned to the device. To guarantee it, > > ZONE_CMA only takes the allocation request with GFP_MOVABLE. > > The immediate follow up question is. Why cannot we reuse ZONE_MOVABLE > for that purpose? I can make CMA reuses the ZONE_MOVABLE but I don't want it. Reasons are that 1. If ZONE_MOVABLE has two different types of memory, hotpluggable and CMA, it may need special handling for each type. This would lead to a new migratetype again (to distinguish them) and easy to be error-prone. I don't want that case. 2. CMA users want to see usage stat separately since CMA often causes the problems and separate stat would helps to debug it. > > The other important point about ZONE_CMA is that span of ZONE_CMA would be > > overlapped with the other zone. This is not new to MM subsystem and > > MM subsystem has enough logic to handle such situation > > so there would be no problem. > > I am not really sure this is actually true. Zones are disjoint from the > early beginning. I remember that we had something like numa nodes > interleaving but that is such a rare configuration that I wouldn't be > surprised if it wasn't very well tested and actually broken in some > subtle ways. I agree with your concern however if something is broken for them, it just shows that we need to fix it. MM should handle this situation since we already know that such architecture exists. > > There are many page_zone(page) != zone checks sprinkled in the code but > I do not see anything consistent there. Similarly pageblock_pfn_to_page > is only used by compaction but there are other pfn walkers which do > ad-hoc checking. I was staring into that code these days due to my > hotplug patches. > > That being said, I think that interleaving zones are an interesting > concept but I would be rather nervous to consider this as working > currently without a deeper review. I have tried to audit all the pfn walkers before and have added above mentioned check. Perhaps, I missed something however I believe not that much. Our production already have used ZONE_CMA and I haven't get the report about such problem. > > > Other things are completely the same with other zones. For MM POV, there is > > no difference in allocation process except that it only takes > > GFP_MOVABLE request. In reclaim, pages that are allocated by MM will > > be reclaimed by the same policy of the MM. So, no difference. > > OK, so essentially this is yet another "highmem" zone. We already know > that only GFP_MOVABLE are allowed to fallback to ZONE_CMA but do CMA > allocations fallback to other zones and punch new holes? In which zone > order? Hmm... I don't understand your question. Could you elaborate it more? > > This 'no difference' is a strong point of this approach. ZONE_CMA is > > naturally handled by MM subsystem unlike as before (special handling is > > required for MIGRATE_CMA). > > > > 3. Controversial Point > > > > Major concern from Mel is that zone concept is abused. ZONE is originally > > introduced to solve some issues due to H/W addressing limitation. > > Yes, very much agreed on that. You basically want to punch holes into > other zones to guarantee an allocation progress. Marking those wholes > with special migrate type sounds quite natural but I will have to study > the current code some more to see whether issues you mention are > inherently unfixable. This might very well turn out to be the case. At a glance, special migratetype sound natural. I also did. However, it's not natural in implementation POV. Zone consists of the same type of memory (by definition ?) and MM subsystem is implemented with that assumption. If difference type of memory shares the same zone, it easily causes the problem and CMA problems are the such case. Thanks.
[toc] | [prev] | [next] | [standalone]
| From | Joonsoo Kim <js1304@gmail.com> |
|---|---|
| Date | 2017-04-21 03:40 +0200 |
| Message-ID | <tyvId-7Y8-1@gated-at.bofh.it> |
| In reply to | #1624509 |
On Mon, Apr 17, 2017 at 11:02:12AM +0900, Joonsoo Kim wrote: > On Thu, Apr 13, 2017 at 01:56:15PM +0200, Michal Hocko wrote: > > On Wed 12-04-17 10:35:06, Joonsoo Kim wrote: > > > On Tue, Apr 11, 2017 at 08:15:20PM +0200, Michal Hocko wrote: > > > > Hi, > > > > I didn't get to read though patches yet but the cover letter didn't > > > > really help me to understand the basic concepts to have a good starting > > > > point before diving into implementation details. It contains a lot of > > > > history remarks which is not bad but IMHO too excessive here. I would > > > > appreciate the following information (some of that is already provided > > > > in the cover but could benefit from some rewording/text reorganization). > > > > > > > > - what is ZONE_CMA and how it is configured (from admin POV) > > > > - how does ZONE_CMA compare to other zones > > > > - who is allowed to allocate from this zone and what are the > > > > guarantees/requirements for successful allocation > > > > - how does the zone compare to a preallocate allocation pool > > > > - how is ZONE_CMA balanced/reclaimed due to internal memory pressure > > > > (from CMA users) > > > > - is this zone reclaimable for the global memory reclaim > > > > - why this was/is controversial > > > > > > Hello, > > > > > > I hope that following summary helps you to understand this patchset. > > > I skip some basic things about CMA. I will attach this description to > > > the cover-letter if re-spin is needed. > > > > I believe that sorting out these questions is more important than what > > you have in the current cover letter. Andrew tends to fold the cover > > into the first patch so I think you should update. > > Okay. > > > > 2. How does ZONE_CMA compare to other zones > > > > > > ZONE_CMA is conceptually the same with ZONE_MOVABLE. There is a software > > > constraint to guarantee the success of future allocation request from > > > the device. If the device requests the specific range of the memory in CMA > > > area at the runtime, page that allocated by MM will be migrated to > > > the other page and it will be returned to the device. To guarantee it, > > > ZONE_CMA only takes the allocation request with GFP_MOVABLE. > > > > The immediate follow up question is. Why cannot we reuse ZONE_MOVABLE > > for that purpose? > > I can make CMA reuses the ZONE_MOVABLE but I don't want it. Reasons > are that > > 1. If ZONE_MOVABLE has two different types of memory, hotpluggable and > CMA, it may need special handling for each type. This would lead to a new > migratetype again (to distinguish them) and easy to be error-prone. I > don't want that case. > > 2. CMA users want to see usage stat separately since CMA often causes > the problems and separate stat would helps to debug it. > > > > The other important point about ZONE_CMA is that span of ZONE_CMA would be > > > overlapped with the other zone. This is not new to MM subsystem and > > > MM subsystem has enough logic to handle such situation > > > so there would be no problem. > > > > I am not really sure this is actually true. Zones are disjoint from the > > early beginning. I remember that we had something like numa nodes > > interleaving but that is such a rare configuration that I wouldn't be > > surprised if it wasn't very well tested and actually broken in some > > subtle ways. > > I agree with your concern however if something is broken for them, it > just shows that we need to fix it. MM should handle this situation > since we already know that such architecture exists. > > > > > There are many page_zone(page) != zone checks sprinkled in the code but > > I do not see anything consistent there. Similarly pageblock_pfn_to_page > > is only used by compaction but there are other pfn walkers which do > > ad-hoc checking. I was staring into that code these days due to my > > hotplug patches. > > > > That being said, I think that interleaving zones are an interesting > > concept but I would be rather nervous to consider this as working > > currently without a deeper review. > > I have tried to audit all the pfn walkers before and have added above > mentioned check. Perhaps, I missed something however I believe not > that much. Our production already have used ZONE_CMA and I haven't get > the report about such problem. > > > > > > Other things are completely the same with other zones. For MM POV, there is > > > no difference in allocation process except that it only takes > > > GFP_MOVABLE request. In reclaim, pages that are allocated by MM will > > > be reclaimed by the same policy of the MM. So, no difference. > > > > OK, so essentially this is yet another "highmem" zone. We already know > > that only GFP_MOVABLE are allowed to fallback to ZONE_CMA but do CMA > > allocations fallback to other zones and punch new holes? In which zone > > order? > > Hmm... I don't understand your question. Could you elaborate it more? > > > > This 'no difference' is a strong point of this approach. ZONE_CMA is > > > naturally handled by MM subsystem unlike as before (special handling is > > > required for MIGRATE_CMA). > > > > > > 3. Controversial Point > > > > > > Major concern from Mel is that zone concept is abused. ZONE is originally > > > introduced to solve some issues due to H/W addressing limitation. > > > > Yes, very much agreed on that. You basically want to punch holes into > > other zones to guarantee an allocation progress. Marking those wholes > > with special migrate type sounds quite natural but I will have to study > > the current code some more to see whether issues you mention are > > inherently unfixable. This might very well turn out to be the case. > > At a glance, special migratetype sound natural. I also did. However, > it's not natural in implementation POV. Zone consists of the same type > of memory (by definition ?) and MM subsystem is implemented with that > assumption. If difference type of memory shares the same zone, it easily > causes the problem and CMA problems are the such case. Hello, Michal. If you don't have any more question, I will send next version with updated cover-letter. Thanks.
[toc] | [prev] | [next] | [standalone]
| From | Michal Hocko <mhocko@kernel.org> |
|---|---|
| Date | 2017-04-21 09:00 +0200 |
| Message-ID | <tyAHT-2AK-3@gated-at.bofh.it> |
| In reply to | #1627903 |
On Fri 21-04-17 10:35:03, Joonsoo Kim wrote: [...] > Hello, Michal. > > If you don't have any more question, I will send next version with > updated cover-letter. I am sorry but I am bussy as hell this week and didn't get to your email yet. I will try as soon as possible. -- Michal Hocko SUSE Labs
[toc] | [prev] | [next] | [standalone]
| From | Michal Hocko <mhocko@kernel.org> |
|---|---|
| Date | 2017-04-24 15:20 +0200 |
| Message-ID | <tzM4h-7tv-1@gated-at.bofh.it> |
| In reply to | #1624509 |
On Mon 17-04-17 11:02:12, Joonsoo Kim wrote: > On Thu, Apr 13, 2017 at 01:56:15PM +0200, Michal Hocko wrote: > > On Wed 12-04-17 10:35:06, Joonsoo Kim wrote: [...] > > > ZONE_CMA is conceptually the same with ZONE_MOVABLE. There is a software > > > constraint to guarantee the success of future allocation request from > > > the device. If the device requests the specific range of the memory in CMA > > > area at the runtime, page that allocated by MM will be migrated to > > > the other page and it will be returned to the device. To guarantee it, > > > ZONE_CMA only takes the allocation request with GFP_MOVABLE. > > > > The immediate follow up question is. Why cannot we reuse ZONE_MOVABLE > > for that purpose? > > I can make CMA reuses the ZONE_MOVABLE but I don't want it. Reasons > are that > > 1. If ZONE_MOVABLE has two different types of memory, hotpluggable and > CMA, it may need special handling for each type. This would lead to a new > migratetype again (to distinguish them) and easy to be error-prone. I > don't want that case. Hmm, I see your motivation. I believe that we could find a way around this. Anyway, movable zones are quite special and configuring overlapping CMA and hotplug movable regions could be refused. So I am not even sure this is a real problem in practice. > 2. CMA users want to see usage stat separately since CMA often causes > the problems and separate stat would helps to debug it. That could be solved by a per-zone/node counter. Anyway, these reasons should be mentioned as well. Adding a new zone is not for free. For most common configurations where we have ZONE_DMA, ZONE_DMA32, ZONE_NORMAL and ZONE_MOVABLE all the 3 bits are already consumed so a new zone will need a new one AFAICS. [...] > > > Other things are completely the same with other zones. For MM POV, there is > > > no difference in allocation process except that it only takes > > > GFP_MOVABLE request. In reclaim, pages that are allocated by MM will > > > be reclaimed by the same policy of the MM. So, no difference. > > > > OK, so essentially this is yet another "highmem" zone. We already know > > that only GFP_MOVABLE are allowed to fallback to ZONE_CMA but do CMA > > allocations fallback to other zones and punch new holes? In which zone > > order? > > Hmm... I don't understand your question. Could you elaborate it more? Well, my question was about the zone fallback chain. MOVABLE allocation can fallback to lower zones and also to the ZONE_CMA with your patch. If there is a CMA allocation it doesn't fall back to any other zone - in other words no new holes are punched to other zones. Is this correct? > > > This 'no difference' is a strong point of this approach. ZONE_CMA is > > > naturally handled by MM subsystem unlike as before (special handling is > > > required for MIGRATE_CMA). > > > > > > 3. Controversial Point > > > > > > Major concern from Mel is that zone concept is abused. ZONE is originally > > > introduced to solve some issues due to H/W addressing limitation. > > > > Yes, very much agreed on that. You basically want to punch holes into > > other zones to guarantee an allocation progress. Marking those wholes > > with special migrate type sounds quite natural but I will have to study > > the current code some more to see whether issues you mention are > > inherently unfixable. This might very well turn out to be the case. > > At a glance, special migratetype sound natural. I also did. However, > it's not natural in implementation POV. Zone consists of the same type > of memory (by definition ?) and MM subsystem is implemented with that > assumption. If difference type of memory shares the same zone, it easily > causes the problem and CMA problems are the such case. But this is not any different from the highmem vs. lowmem problems we already have, no? I have looked at your example in the cover where you mention utilization and the reclaim problems. With the node reclaim we will have pages from all zones on the same LRU(s). isolate_lru_pages will skip those from ZONE_CMA because their zone_idx is higher than gfp_idx(GFP_KERNEL). The same could be achieved by an explicit check for the pageblock migrate type. So the zone doesn't really help much. Or is there some aspect that I am missing? Another worry I would have with the zone approach is that there is a risk to reintroduce issues we used to have with small zones in the past. Just consider that the CMA will get depleted by CMA users almost completely. Now that zone will not get balanced with only few pages. wakeup_kswapd/pgdat_balanced already has measures to prevent from wake ups but I cannot say I would be sure everything will work smoothly. I have glanced through the cumulative diff and to be honest I am not really sure the result is a great simplification in the end. There is still quite a lot of special casing. It is true that the page allocator path is cleaned up and some CMA specific checks are moved away. This is definitely good to see but I am not convinced that the new zone is really justified. Only very little from the zone infrastructure is used in the end AFAICS. Is there any specific usecase which cannot be solved with the pageblock while it could be with the zone approach? That would be a strong argument to chose one over another. Please do _not_ take this as a NAK from me. At least not at this time. I am still trying to understand all the consequences but my intuition tells me that building on top of highmem like approach will turn out to be problematic in future (as we have already seen with the highmem and movable zones) so this needs a very prudent consideration. -- Michal Hocko SUSE Labs
[toc] | [prev] | [next] | [standalone]
| From | Joonsoo Kim <js1304@gmail.com> |
|---|---|
| Date | 2017-04-12 03:40 +0200 |
| Message-ID | <tvfqh-6rL-13@gated-at.bofh.it> |
| In reply to | #1620863 |
On Tue, Apr 11, 2017 at 12:17:13PM +0900, js1304@gmail.com wrote: > From: Joonsoo Kim <iamjoonsoo.kim@lge.com> > > Changed from v6 > o Rebase on next-20170405 > o Add a fix for lowmem mapping on ARM (last patch) Hello, Russell and Will. In this 7th patchset, I newly added a patch for ARM. Could you review it? Thanks.
[toc] | [prev] | [next] | [standalone]
| From | Bob Liu <liubo95@huawei.com> |
|---|---|
| Date | 2017-04-24 06:10 +0200 |
| Message-ID | <tzDu1-1OW-1@gated-at.bofh.it> |
| In reply to | #1620863 |
On 2017/4/11 11:17, js1304@gmail.com wrote: > From: Joonsoo Kim <iamjoonsoo.kim@lge.com> > > Changed from v6 > o Rebase on next-20170405 > o Add a fix for lowmem mapping on ARM (last patch) > o Re-organize the cover letter > > Changes from v5 > o Rebase on next-20161013 > o Cosmetic change on patch 1 > o Optimize span of ZONE_CMA on multiple node system > > Changes from v4 > o Rebase on next-20160825 > o Add general fix patch for lowmem reserve > o Fix lowmem reserve ratio > o Fix zone span optimizaion per Vlastimil > o Fix pageset initialization > o Change invocation timing on cma_init_reserved_areas() > > Changes from v3 > o Rebase on next-20160805 > o Split first patch per Vlastimil > o Remove useless function parameter per Vlastimil > o Add code comment per Vlastimil > o Add following description on cover-letter > > Changes from v2 > o Rebase on next-20160525 > o No other changes except following description > > Changes from v1 > o Separate some patches which deserve to submit independently > o Modify description to reflect current kernel state > (e.g. high-order watermark problem disappeared by Mel's work) > o Don't increase SECTION_SIZE_BITS to make a room in page flags > (detailed reason is on the patch that adds ZONE_CMA) > o Adjust ZONE_CMA population code > > > Hello, > > This is the 7th version of ZONE_CMA patchset. One patch is added > to fix potential problem on ARM. Other changes are just due to rebase. > > This patchset has long history and got some reviews before. This > cover-letter has the summary and my opinion on those reviews. Content > order is so confusing so I make a simple index. If anyone want to > understand the history properly, please read them by reverse order. > > PART 1. Strong points of the zone approach > PART 2. Summary in LSF/MM 2016 discussion > PART 3. Original motivation of this patchset > > ***** PART 1 ***** > > CMA has many problems and I mentioned them on the bottom of the > cover letter. These problems comes from limitation of CMA memory that > should be always migratable for device usage. I think that introducing > a new zone is the best approach to solve them. Here are the reasons. > > Zone is introduced to solve some issues due to H/W addressing limitation. > MM subsystem is implemented to work efficiently with these zones. > Allocation/reclaim logic in MM consider this limitation very much. > What I did in this patchset is introducing a new zone and extending zone's > concept slightly. New concept is that zone can have not only H/W addressing > limitation but also S/W limitation to guarantee page migration. > This concept is originated from ZONE_MOVABLE and it works well > for a long time. So, ZONE_CMA should not be special at this moment. > > There is a major concern from Mel that ZONE_MOVABLE which has > S/W limitation causes highmem/lowmem problem. Highmem/lowmem problem is > that some of memory cannot be usable for kernel memory due to limitation > of the zone. It causes to break LRU ordering and makes hard to find kernel > usable memory when memory pressure. > > However, important point is that this problem doesn't come from > implementation detail (ZONE_MOVABLE/MIGRATETYPE). Even if we implement it > by MIGRATETYPE instead of by ZONE_MOVABLE, we cannot use that type of > memory for kernel allocation because it isn't migratable. So, it will cause > to break LRU ordering, too. We cannot avoid the problem in any case. > Therefore, we should focus on which solution is better for maintenance > and not intrusive for MM subsystem. > > In this viewpoint, I think that zone approach is better. As mentioned > earlier, MM subsystem already have many infrastructures to deal with > zone's H/W addressing limitation. Adding S/W limitation on zone concept > and adding a new zone doesn't change anything. It will work by itself. > My patchset can remove many hooks related to CMA area management in MM > while solving the problems. More hooks are required to solve the problems > if we choose MIGRATETYPE approach. > Agree, there are already too many hooks and pain to maintain/bugfix. It looks better if choose this ZONE_CMA approach. -- Regards, Bob Liu
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web