All of lore.kernel.org
 help / color / mirror / Atom feed
diff for duplicates of <20120907022434.GG16231@bbox>

diff --git a/a/1.txt b/N1/1.txt
index ab153d2..45f52a2 100644
--- a/a/1.txt
+++ b/N1/1.txt
@@ -160,3 +160,150 @@ It's different with my point.
 My intention is to free mapped clean pages as well as not-mapped's one.
 
 How about this?
+
+>From 0f6986e943e55929b4d7b0220a1c24a6bae1a24d Mon Sep 17 00:00:00 2001
+From: Minchan Kim <minchan@kernel.org>
+Date: Fri, 7 Sep 2012 11:20:48 +0900
+Subject: [PATCH] mm: cma: Discard clean pages during contiguous allocation
+ instead of migration
+
+This patch introudes MIGRATE_DISCARD mode in migration.
+It drops *clean cache pages* instead of migration so that
+migration latency could be reduced by avoiding (memcpy + page remapping).
+It's useful for CMA because latency of migration is very important rather
+than eviction of background processes's workingset. In addition, it needs
+less free pages for migration targets so it could avoid memory reclaiming
+to get free pages, which is another factor increase latency.
+
+Cc: Marek Szyprowski <m.szyprowski@samsung.com>
+Cc: Michal Nazarewicz <mina86@mina86.com>
+Cc: Rik van Riel <riel@redhat.com>
+Signed-off-by: Mel Gorman <mgorman@suse.de>
+Signed-off-by: Minchan Kim <minchan@kernel.org>
+---
+ mm/internal.h   |    2 ++
+ mm/page_alloc.c |    2 ++
+ mm/vmscan.c     |   42 ++++++++++++++++++++++++++++++++++++------
+ 3 files changed, 40 insertions(+), 6 deletions(-)
+
+diff --git a/mm/internal.h b/mm/internal.h
+index 3314f79..be09a7e 100644
+--- a/mm/internal.h
++++ b/mm/internal.h
+@@ -355,3 +355,5 @@ extern unsigned long vm_mmap_pgoff(struct file *, unsigned long,
+         unsigned long, unsigned long);
+ 
+ extern void set_pageblock_order(void);
++unsigned long reclaim_clean_pages_from_list(struct zone *zone,
++				struct list_head *page_list);
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index ba3100a..bf35e59 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -5668,6 +5668,8 @@ static int __alloc_contig_migrate_range(unsigned long start, unsigned long end)
+ 			break;
+ 		}
+ 
++		reclaim_clean_pages_from_list(&cc.migratepages, cc.zone);
++
+ 		ret = migrate_pages(&cc.migratepages,
+ 				    __alloc_contig_migrate_alloc,
+ 				    0, false, MIGRATE_SYNC);
+diff --git a/mm/vmscan.c b/mm/vmscan.c
+index 8d01243..525355e 100644
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -674,8 +674,10 @@ static enum page_references page_check_references(struct page *page,
+ static unsigned long shrink_page_list(struct list_head *page_list,
+ 				      struct zone *zone,
+ 				      struct scan_control *sc,
++				      enum ttu_flags ttu_flags,
+ 				      unsigned long *ret_nr_dirty,
+-				      unsigned long *ret_nr_writeback)
++				      unsigned long *ret_nr_writeback,
++				      bool force_reclaim)
+ {
+ 	LIST_HEAD(ret_pages);
+ 	LIST_HEAD(free_pages);
+@@ -689,10 +691,10 @@ static unsigned long shrink_page_list(struct list_head *page_list,
+ 
+ 	mem_cgroup_uncharge_start();
+ 	while (!list_empty(page_list)) {
+-		enum page_references references;
+ 		struct address_space *mapping;
+ 		struct page *page;
+ 		int may_enter_fs;
++		enum page_references references = PAGEREF_RECLAIM;
+ 
+ 		cond_resched();
+ 
+@@ -758,7 +760,9 @@ static unsigned long shrink_page_list(struct list_head *page_list,
+ 			wait_on_page_writeback(page);
+ 		}
+ 
+-		references = page_check_references(page, sc);
++		if (!force_reclaim)
++			references = page_check_references(page, sc);
++
+ 		switch (references) {
+ 		case PAGEREF_ACTIVATE:
+ 			goto activate_locked;
+@@ -788,7 +792,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
+ 		 * processes. Try to unmap it here.
+ 		 */
+ 		if (page_mapped(page) && mapping) {
+-			switch (try_to_unmap(page, TTU_UNMAP)) {
++			switch (try_to_unmap(page, ttu_flags)) {
+ 			case SWAP_FAIL:
+ 				goto activate_locked;
+ 			case SWAP_AGAIN:
+@@ -960,6 +964,32 @@ keep:
+ 	return nr_reclaimed;
+ }
+ 
++unsigned long reclaim_clean_pages_from_list(struct zone *zone,
++					struct list_head *page_list)
++{
++	struct scan_control sc = {
++		.gfp_mask = GFP_KERNEL,
++		.priority = DEF_PRIORITY,
++		.may_unmap = 1,
++	};
++	unsigned long ret, dummy1, dummy2;
++	struct page *page, *next;
++	LIST_HEAD(clean_pages);
++
++	list_for_each_entry_safe(page, next, page_list, lru) {
++		if (page_is_file_cache(page) && !PageDirty(page)) {
++			ClearPageActive(page);
++			list_move(&page->lru, &clean_pages);
++		}
++	}
++
++	ret = shrink_page_list(&clean_pages, zone, &sc,
++				TTU_UNMAP|TTU_IGNORE_ACCESS,
++				&dummy1, &dummy2, true);
++	list_splice(&clean_pages, page_list);
++	return ret;
++}
++
+ /*
+  * Attempt to remove the specified page from its LRU.  Only take this page
+  * if it is of the appropriate PageActive status.  Pages which are being
+@@ -1278,8 +1308,8 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
+ 	if (nr_taken == 0)
+ 		return 0;
+ 
+-	nr_reclaimed = shrink_page_list(&page_list, zone, sc,
+-						&nr_dirty, &nr_writeback);
++	nr_reclaimed = shrink_page_list(&page_list, zone, sc, TTU_UNMAP,
++					&nr_dirty, &nr_writeback, false);
+ 
+ 	spin_lock_irq(&zone->lru_lock);
+ 
+-- 
+1.7.9.5
+
+-- 
+Kind regards,
+Minchan Kim
diff --git a/a/content_digest b/N1/content_digest
index 15ce0e1..720906c 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -178,6 +178,153 @@
  "It's different with my point.\n"
  "My intention is to free mapped clean pages as well as not-mapped's one.\n"
  "\n"
- How about this?
+ "How about this?\n"
+ "\n"
+ ">From 0f6986e943e55929b4d7b0220a1c24a6bae1a24d Mon Sep 17 00:00:00 2001\n"
+ "From: Minchan Kim <minchan@kernel.org>\n"
+ "Date: Fri, 7 Sep 2012 11:20:48 +0900\n"
+ "Subject: [PATCH] mm: cma: Discard clean pages during contiguous allocation\n"
+ " instead of migration\n"
+ "\n"
+ "This patch introudes MIGRATE_DISCARD mode in migration.\n"
+ "It drops *clean cache pages* instead of migration so that\n"
+ "migration latency could be reduced by avoiding (memcpy + page remapping).\n"
+ "It's useful for CMA because latency of migration is very important rather\n"
+ "than eviction of background processes's workingset. In addition, it needs\n"
+ "less free pages for migration targets so it could avoid memory reclaiming\n"
+ "to get free pages, which is another factor increase latency.\n"
+ "\n"
+ "Cc: Marek Szyprowski <m.szyprowski@samsung.com>\n"
+ "Cc: Michal Nazarewicz <mina86@mina86.com>\n"
+ "Cc: Rik van Riel <riel@redhat.com>\n"
+ "Signed-off-by: Mel Gorman <mgorman@suse.de>\n"
+ "Signed-off-by: Minchan Kim <minchan@kernel.org>\n"
+ "---\n"
+ " mm/internal.h   |    2 ++\n"
+ " mm/page_alloc.c |    2 ++\n"
+ " mm/vmscan.c     |   42 ++++++++++++++++++++++++++++++++++++------\n"
+ " 3 files changed, 40 insertions(+), 6 deletions(-)\n"
+ "\n"
+ "diff --git a/mm/internal.h b/mm/internal.h\n"
+ "index 3314f79..be09a7e 100644\n"
+ "--- a/mm/internal.h\n"
+ "+++ b/mm/internal.h\n"
+ "@@ -355,3 +355,5 @@ extern unsigned long vm_mmap_pgoff(struct file *, unsigned long,\n"
+ "         unsigned long, unsigned long);\n"
+ " \n"
+ " extern void set_pageblock_order(void);\n"
+ "+unsigned long reclaim_clean_pages_from_list(struct zone *zone,\n"
+ "+\t\t\t\tstruct list_head *page_list);\n"
+ "diff --git a/mm/page_alloc.c b/mm/page_alloc.c\n"
+ "index ba3100a..bf35e59 100644\n"
+ "--- a/mm/page_alloc.c\n"
+ "+++ b/mm/page_alloc.c\n"
+ "@@ -5668,6 +5668,8 @@ static int __alloc_contig_migrate_range(unsigned long start, unsigned long end)\n"
+ " \t\t\tbreak;\n"
+ " \t\t}\n"
+ " \n"
+ "+\t\treclaim_clean_pages_from_list(&cc.migratepages, cc.zone);\n"
+ "+\n"
+ " \t\tret = migrate_pages(&cc.migratepages,\n"
+ " \t\t\t\t    __alloc_contig_migrate_alloc,\n"
+ " \t\t\t\t    0, false, MIGRATE_SYNC);\n"
+ "diff --git a/mm/vmscan.c b/mm/vmscan.c\n"
+ "index 8d01243..525355e 100644\n"
+ "--- a/mm/vmscan.c\n"
+ "+++ b/mm/vmscan.c\n"
+ "@@ -674,8 +674,10 @@ static enum page_references page_check_references(struct page *page,\n"
+ " static unsigned long shrink_page_list(struct list_head *page_list,\n"
+ " \t\t\t\t      struct zone *zone,\n"
+ " \t\t\t\t      struct scan_control *sc,\n"
+ "+\t\t\t\t      enum ttu_flags ttu_flags,\n"
+ " \t\t\t\t      unsigned long *ret_nr_dirty,\n"
+ "-\t\t\t\t      unsigned long *ret_nr_writeback)\n"
+ "+\t\t\t\t      unsigned long *ret_nr_writeback,\n"
+ "+\t\t\t\t      bool force_reclaim)\n"
+ " {\n"
+ " \tLIST_HEAD(ret_pages);\n"
+ " \tLIST_HEAD(free_pages);\n"
+ "@@ -689,10 +691,10 @@ static unsigned long shrink_page_list(struct list_head *page_list,\n"
+ " \n"
+ " \tmem_cgroup_uncharge_start();\n"
+ " \twhile (!list_empty(page_list)) {\n"
+ "-\t\tenum page_references references;\n"
+ " \t\tstruct address_space *mapping;\n"
+ " \t\tstruct page *page;\n"
+ " \t\tint may_enter_fs;\n"
+ "+\t\tenum page_references references = PAGEREF_RECLAIM;\n"
+ " \n"
+ " \t\tcond_resched();\n"
+ " \n"
+ "@@ -758,7 +760,9 @@ static unsigned long shrink_page_list(struct list_head *page_list,\n"
+ " \t\t\twait_on_page_writeback(page);\n"
+ " \t\t}\n"
+ " \n"
+ "-\t\treferences = page_check_references(page, sc);\n"
+ "+\t\tif (!force_reclaim)\n"
+ "+\t\t\treferences = page_check_references(page, sc);\n"
+ "+\n"
+ " \t\tswitch (references) {\n"
+ " \t\tcase PAGEREF_ACTIVATE:\n"
+ " \t\t\tgoto activate_locked;\n"
+ "@@ -788,7 +792,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,\n"
+ " \t\t * processes. Try to unmap it here.\n"
+ " \t\t */\n"
+ " \t\tif (page_mapped(page) && mapping) {\n"
+ "-\t\t\tswitch (try_to_unmap(page, TTU_UNMAP)) {\n"
+ "+\t\t\tswitch (try_to_unmap(page, ttu_flags)) {\n"
+ " \t\t\tcase SWAP_FAIL:\n"
+ " \t\t\t\tgoto activate_locked;\n"
+ " \t\t\tcase SWAP_AGAIN:\n"
+ "@@ -960,6 +964,32 @@ keep:\n"
+ " \treturn nr_reclaimed;\n"
+ " }\n"
+ " \n"
+ "+unsigned long reclaim_clean_pages_from_list(struct zone *zone,\n"
+ "+\t\t\t\t\tstruct list_head *page_list)\n"
+ "+{\n"
+ "+\tstruct scan_control sc = {\n"
+ "+\t\t.gfp_mask = GFP_KERNEL,\n"
+ "+\t\t.priority = DEF_PRIORITY,\n"
+ "+\t\t.may_unmap = 1,\n"
+ "+\t};\n"
+ "+\tunsigned long ret, dummy1, dummy2;\n"
+ "+\tstruct page *page, *next;\n"
+ "+\tLIST_HEAD(clean_pages);\n"
+ "+\n"
+ "+\tlist_for_each_entry_safe(page, next, page_list, lru) {\n"
+ "+\t\tif (page_is_file_cache(page) && !PageDirty(page)) {\n"
+ "+\t\t\tClearPageActive(page);\n"
+ "+\t\t\tlist_move(&page->lru, &clean_pages);\n"
+ "+\t\t}\n"
+ "+\t}\n"
+ "+\n"
+ "+\tret = shrink_page_list(&clean_pages, zone, &sc,\n"
+ "+\t\t\t\tTTU_UNMAP|TTU_IGNORE_ACCESS,\n"
+ "+\t\t\t\t&dummy1, &dummy2, true);\n"
+ "+\tlist_splice(&clean_pages, page_list);\n"
+ "+\treturn ret;\n"
+ "+}\n"
+ "+\n"
+ " /*\n"
+ "  * Attempt to remove the specified page from its LRU.  Only take this page\n"
+ "  * if it is of the appropriate PageActive status.  Pages which are being\n"
+ "@@ -1278,8 +1308,8 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,\n"
+ " \tif (nr_taken == 0)\n"
+ " \t\treturn 0;\n"
+ " \n"
+ "-\tnr_reclaimed = shrink_page_list(&page_list, zone, sc,\n"
+ "-\t\t\t\t\t\t&nr_dirty, &nr_writeback);\n"
+ "+\tnr_reclaimed = shrink_page_list(&page_list, zone, sc, TTU_UNMAP,\n"
+ "+\t\t\t\t\t&nr_dirty, &nr_writeback, false);\n"
+ " \n"
+ " \tspin_lock_irq(&zone->lru_lock);\n"
+ " \n"
+ "-- \n"
+ "1.7.9.5\n"
+ "\n"
+ "-- \n"
+ "Kind regards,\n"
+ Minchan Kim
 
-62bd9b8fc9513fbb853aec3c6ac2ff7aba6d18b5959e8dc2ef3217f009ddbe31
+c1eb5e4dbe97cd9fd99669c10f9866c031058c8d5e11d4449710e39d9dba2f19

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.