Re: [PATCH 05/11] mm: mmzone: MIGRATE_CMA migration type added

2012-01-10 Thread Mel Gorman
On Thu, Dec 29, 2011 at 01:39:06PM +0100, Marek Szyprowski wrote:
 From: Michal Nazarewicz min...@mina86.com
 
 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 (to some degree) 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 for allocating big chunks (eg. 10MiB)
 of physically contiguous memory.  Once driver requests
 contiguous memory, pages from MIGRATE_CMA pageblocks may be
 migrated away to create a contiguous block.
 
 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.
 
 Signed-off-by: Michal Nazarewicz min...@mina86.com
 [m.szyprowski: removed CONFIG_CMA_MIGRATE_TYPE]
 Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
 Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
 ---
  include/linux/mmzone.h |   41 
  include/linux/page-isolation.h |3 ++
  mm/Kconfig |2 +-
  mm/compaction.c|   11 +--
  mm/page_alloc.c|   68 ++-
  mm/vmstat.c|1 +
  6 files changed, 99 insertions(+), 27 deletions(-)
 
 diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
 index 188cb2f..e38b85d 100644
 --- a/include/linux/mmzone.h
 +++ b/include/linux/mmzone.h
 @@ -35,13 +35,35 @@
   */
  #define PAGE_ALLOC_COSTLY_ORDER 3
  
 -#define MIGRATE_UNMOVABLE 0
 -#define MIGRATE_RECLAIMABLE   1
 -#define MIGRATE_MOVABLE   2
 -#define MIGRATE_PCPTYPES  3 /* the number of types on the pcp lists */
 -#define MIGRATE_RESERVE   3
 -#define MIGRATE_ISOLATE   4 /* can't allocate from here */
 -#define MIGRATE_TYPES 5
 +enum {
 + MIGRATE_UNMOVABLE,
 + MIGRATE_RECLAIMABLE,
 + MIGRATE_MOVABLE,
 + MIGRATE_PCPTYPES,   /* the number of types on the pcp lists */
 + MIGRATE_RESERVE = MIGRATE_PCPTYPES,
 + /*
 +  * 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,
 + MIGRATE_ISOLATE,/* can't allocate from here */
 + MIGRATE_TYPES
 +};

MIGRATE_CMA is being added whether or not CONFIG_CMA is set. This
increases the size of the pageblock bitmap and where that is just 1 bit
per pageblock in the system, it may be noticable on large machines.

 +
 +#ifdef CONFIG_CMA
 +#  define is_migrate_cma(migratetype) unlikely((migratetype) == MIGRATE_CMA)
 +#else
 +#  define is_migrate_cma(migratetype) false
 +#endif
  

Use static inlines.

  #define for_each_migratetype_order(order, type) \
   for (order = 0; order  MAX_ORDER; order++) \
 @@ -54,6 +76,11 @@ static inline int get_pageblock_migratetype(struct page 
 *page)
   return get_pageblock_flags_group(page, PB_migrate, PB_migrate_end);
  }
  
 +static inline bool is_pageblock_cma(struct page *page)
 +{
 + return is_migrate_cma(get_pageblock_migratetype(page));
 +}
 +

This allows additional calls to get_pageblock_migratetype() even if
CONFIG_CMA is not set.

  struct free_area {
   struct list_headfree_list[MIGRATE_TYPES];
   unsigned long   nr_free;
 diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
 index d305080..af650db 100644
 --- a/include/linux/page-isolation.h
 +++ b/include/linux/page-isolation.h
 @@ -37,4 +37,7 @@ extern void unset_migratetype_isolate(struct page *page);
  int alloc_contig_range(unsigned long start, unsigned long end);
  void free_contig_range(unsigned long pfn, unsigned nr_pages);
  
 +/* CMA stuff */
 +extern void init_cma_reserved_pageblock(struct page *page);
 +
  #endif
 diff --git a/mm/Kconfig b/mm/Kconfig
 index 011b110..e080cac 100644
 --- a/mm/Kconfig
 +++ b/mm/Kconfig
 @@ -192,7 +192,7 @@ config COMPACTION
  config MIGRATION
   bool Page migration
   def_bool y
 - depends on NUMA || ARCH_ENABLE_MEMORY_HOTREMOVE || COMPACTION
 + depends on NUMA || ARCH_ENABLE_MEMORY_HOTREMOVE || COMPACTION || CMA
   help
 Allows the migration of the physical location of pages of processes
 while the virtual addresses are not changed. This is useful in
 diff --git 

Re: [PATCH 05/11] mm: mmzone: MIGRATE_CMA migration type added

2012-01-10 Thread Michal Nazarewicz

On Tue, 10 Jan 2012 15:38:36 +0100, Mel Gorman m...@csn.ul.ie wrote:


On Thu, Dec 29, 2011 at 01:39:06PM +0100, Marek Szyprowski wrote:

From: Michal Nazarewicz min...@mina86.com



@@ -35,13 +35,35 @@
  */
 #define PAGE_ALLOC_COSTLY_ORDER 3

-#define MIGRATE_UNMOVABLE 0
-#define MIGRATE_RECLAIMABLE   1
-#define MIGRATE_MOVABLE   2
-#define MIGRATE_PCPTYPES  3 /* the number of types on the pcp lists */
-#define MIGRATE_RESERVE   3
-#define MIGRATE_ISOLATE   4 /* can't allocate from here */
-#define MIGRATE_TYPES 5
+enum {
+   MIGRATE_UNMOVABLE,
+   MIGRATE_RECLAIMABLE,
+   MIGRATE_MOVABLE,
+   MIGRATE_PCPTYPES,   /* the number of types on the pcp lists */
+   MIGRATE_RESERVE = MIGRATE_PCPTYPES,
+   /*
+* 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,
+   MIGRATE_ISOLATE,/* can't allocate from here */
+   MIGRATE_TYPES
+};


MIGRATE_CMA is being added whether or not CONFIG_CMA is set. This
increases the size of the pageblock bitmap and where that is just 1 bit
per pageblock in the system, it may be noticable on large machines.


Wasn't aware of that, will do.  In fact, in earlier versions in was done this 
way,
but resulted in more #ifdefs.




+
+#ifdef CONFIG_CMA
+#  define is_migrate_cma(migratetype) unlikely((migratetype) == MIGRATE_CMA)
+#else
+#  define is_migrate_cma(migratetype) false
+#endif



Use static inlines.


I decide to use #define for the sake of situations like
is_migrate_cma(get_pageblock_migratetype(page)).  With a static inline it will 
have
to read pageblock's migrate type even if !CONFIG_CMA.  A macro gets rid of this
operation all together.


 #define for_each_migratetype_order(order, type) \
for (order = 0; order  MAX_ORDER; order++) \
@@ -54,6 +76,11 @@ static inline int get_pageblock_migratetype(struct page 
*page)
return get_pageblock_flags_group(page, PB_migrate, PB_migrate_end);
 }

+static inline bool is_pageblock_cma(struct page *page)
+{
+   return is_migrate_cma(get_pageblock_migratetype(page));
+}
+


This allows additional calls to get_pageblock_migratetype() even if
CONFIG_CMA is not set.


 struct free_area {
struct list_headfree_list[MIGRATE_TYPES];
unsigned long   nr_free;
diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
index d305080..af650db 100644
--- a/include/linux/page-isolation.h
+++ b/include/linux/page-isolation.h
@@ -37,4 +37,7 @@ extern void unset_migratetype_isolate(struct page *page);
 int alloc_contig_range(unsigned long start, unsigned long end);
 void free_contig_range(unsigned long pfn, unsigned nr_pages);

+/* CMA stuff */
+extern void init_cma_reserved_pageblock(struct page *page);
+
 #endif
diff --git a/mm/Kconfig b/mm/Kconfig
index 011b110..e080cac 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -192,7 +192,7 @@ config COMPACTION
 config MIGRATION
bool Page migration
def_bool y
-   depends on NUMA || ARCH_ENABLE_MEMORY_HOTREMOVE || COMPACTION
+   depends on NUMA || ARCH_ENABLE_MEMORY_HOTREMOVE || COMPACTION || CMA
help
  Allows the migration of the physical location of pages of processes
  while the virtual addresses are not changed. This is useful in
diff --git a/mm/compaction.c b/mm/compaction.c
index 8733441..46783b4 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -21,6 +21,11 @@
 #define CREATE_TRACE_POINTS
 #include trace/events/compaction.h

+static inline bool is_migrate_cma_or_movable(int migratetype)
+{
+   return is_migrate_cma(migratetype) || migratetype == MIGRATE_MOVABLE;
+}
+


That is not a name that helps any. migrate_async_suitable() would be
marginally better.


 /**
  * isolate_freepages_range() - isolate free pages, must hold zone-lock.
  * @zone:  Zone pages are in.
@@ -213,7 +218,7 @@ isolate_migratepages_range(struct zone *zone, struct 
compact_control *cc,
 */
pageblock_nr = low_pfn  pageblock_order;
if (!cc-sync  last_pageblock_nr != pageblock_nr 
-   get_pageblock_migratetype(page) != 
MIGRATE_MOVABLE) {
+   is_migrate_cma_or_movable(get_pageblock_migratetype(page))) 
{
low_pfn += pageblock_nr_pages;
low_pfn = ALIGN(low_pfn, pageblock_nr_pages) - 1;
   

[PATCH 05/11] mm: mmzone: MIGRATE_CMA migration type added

2011-12-29 Thread Marek Szyprowski
From: Michal Nazarewicz min...@mina86.com

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 (to some degree) 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 for allocating big chunks (eg. 10MiB)
of physically contiguous memory.  Once driver requests
contiguous memory, pages from MIGRATE_CMA pageblocks may be
migrated away to create a contiguous block.

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.

Signed-off-by: Michal Nazarewicz min...@mina86.com
[m.szyprowski: removed CONFIG_CMA_MIGRATE_TYPE]
Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
---
 include/linux/mmzone.h |   41 
 include/linux/page-isolation.h |3 ++
 mm/Kconfig |2 +-
 mm/compaction.c|   11 +--
 mm/page_alloc.c|   68 ++-
 mm/vmstat.c|1 +
 6 files changed, 99 insertions(+), 27 deletions(-)

diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 188cb2f..e38b85d 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -35,13 +35,35 @@
  */
 #define PAGE_ALLOC_COSTLY_ORDER 3
 
-#define MIGRATE_UNMOVABLE 0
-#define MIGRATE_RECLAIMABLE   1
-#define MIGRATE_MOVABLE   2
-#define MIGRATE_PCPTYPES  3 /* the number of types on the pcp lists */
-#define MIGRATE_RESERVE   3
-#define MIGRATE_ISOLATE   4 /* can't allocate from here */
-#define MIGRATE_TYPES 5
+enum {
+   MIGRATE_UNMOVABLE,
+   MIGRATE_RECLAIMABLE,
+   MIGRATE_MOVABLE,
+   MIGRATE_PCPTYPES,   /* the number of types on the pcp lists */
+   MIGRATE_RESERVE = MIGRATE_PCPTYPES,
+   /*
+* 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,
+   MIGRATE_ISOLATE,/* can't allocate from here */
+   MIGRATE_TYPES
+};
+
+#ifdef CONFIG_CMA
+#  define is_migrate_cma(migratetype) unlikely((migratetype) == MIGRATE_CMA)
+#else
+#  define is_migrate_cma(migratetype) false
+#endif
 
 #define for_each_migratetype_order(order, type) \
for (order = 0; order  MAX_ORDER; order++) \
@@ -54,6 +76,11 @@ static inline int get_pageblock_migratetype(struct page 
*page)
return get_pageblock_flags_group(page, PB_migrate, PB_migrate_end);
 }
 
+static inline bool is_pageblock_cma(struct page *page)
+{
+   return is_migrate_cma(get_pageblock_migratetype(page));
+}
+
 struct free_area {
struct list_headfree_list[MIGRATE_TYPES];
unsigned long   nr_free;
diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
index d305080..af650db 100644
--- a/include/linux/page-isolation.h
+++ b/include/linux/page-isolation.h
@@ -37,4 +37,7 @@ extern void unset_migratetype_isolate(struct page *page);
 int alloc_contig_range(unsigned long start, unsigned long end);
 void free_contig_range(unsigned long pfn, unsigned nr_pages);
 
+/* CMA stuff */
+extern void init_cma_reserved_pageblock(struct page *page);
+
 #endif
diff --git a/mm/Kconfig b/mm/Kconfig
index 011b110..e080cac 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -192,7 +192,7 @@ config COMPACTION
 config MIGRATION
bool Page migration
def_bool y
-   depends on NUMA || ARCH_ENABLE_MEMORY_HOTREMOVE || COMPACTION
+   depends on NUMA || ARCH_ENABLE_MEMORY_HOTREMOVE || COMPACTION || CMA
help
  Allows the migration of the physical location of pages of processes
  while the virtual addresses are not changed. This is useful in
diff --git a/mm/compaction.c b/mm/compaction.c
index 8733441..46783b4 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -21,6 +21,11 @@
 #define CREATE_TRACE_POINTS
 #include trace/events/compaction.h
 
+static inline bool is_migrate_cma_or_movable(int migratetype)
+{
+   return is_migrate_cma(migratetype) || migratetype == MIGRATE_MOVABLE;
+}
+
 /**
  * isolate_freepages_range() - isolate free pages, must hold zone-lock.
  * @zone:  Zone pages are