All of lore.kernel.org
 help / color / mirror / Atom feed
diff for duplicates of <20130704042450.GA7132@lge.com>

diff --git a/a/1.txt b/N1/1.txt
index e817269..dabdd8d 100644
--- a/a/1.txt
+++ b/N1/1.txt
@@ -37,3 +37,197 @@ one page allocation is inevitable. Anyway, I will do and test it.
 Thanks.
 
 -------------------------------8<----------------------------
+>From cee05ad3bcf1c5774fabf797b5dc8f78f812ca36 Mon Sep 17 00:00:00 2001
+From: Joonsoo Kim <iamjoonsoo.kim@lge.com>
+Date: Wed, 26 Jun 2013 13:37:57 +0900
+Subject: [PATCH] mm, page_alloc: support multiple pages allocation
+
+This patch introduces multiple pages allocation feature to buddy
+allocator. Currently, there is no ability to allocate multiple
+pages at once, so we should invoke single page allocation logic
+repeatedly. This has some overheads like as function call
+overhead with many arguments and overhead for finding proper
+node and zone.
+
+With this patchset, we can reduce these overheads. Device I/O is
+getting faster rapidly and allocator should catch up this speed.
+This patch help this situation.
+
+In this patch, I introduce new arguments, nr_pages and pages, to
+core function of allocator and try to allocate multiple pages
+in first attempt(fast path). I think that multiple page allocation
+is not valid for slow path, so current implementation consider
+just fast path.
+
+Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
+
+diff --git a/include/linux/gfp.h b/include/linux/gfp.h
+index 0f615eb..8bfa87b 100644
+--- a/include/linux/gfp.h
++++ b/include/linux/gfp.h
+@@ -298,13 +298,15 @@ static inline void arch_alloc_page(struct page *page, int order) { }
+ 
+ struct page *
+ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order,
+-		       struct zonelist *zonelist, nodemask_t *nodemask);
++		       struct zonelist *zonelist, nodemask_t *nodemask,
++		       unsigned long *nr_pages, struct page **pages);
+ 
+ static inline struct page *
+ __alloc_pages(gfp_t gfp_mask, unsigned int order,
+ 		struct zonelist *zonelist)
+ {
+-	return __alloc_pages_nodemask(gfp_mask, order, zonelist, NULL);
++	return __alloc_pages_nodemask(gfp_mask, order,
++				zonelist, NULL, NULL, NULL);
+ }
+ 
+ static inline struct page *alloc_pages_node(int nid, gfp_t gfp_mask,
+diff --git a/mm/mempolicy.c b/mm/mempolicy.c
+index 7431001..b17e48c 100644
+--- a/mm/mempolicy.c
++++ b/mm/mempolicy.c
+@@ -2004,7 +2004,8 @@ retry_cpuset:
+ 	}
+ 	page = __alloc_pages_nodemask(gfp, order,
+ 				      policy_zonelist(gfp, pol, node),
+-				      policy_nodemask(gfp, pol));
++				      policy_nodemask(gfp, pol),
++				      NULL, NULL);
+ 	if (unlikely(mpol_needs_cond_ref(pol)))
+ 		__mpol_put(pol);
+ 	if (unlikely(!put_mems_allowed(cpuset_mems_cookie) && !page))
+@@ -2052,7 +2053,8 @@ retry_cpuset:
+ 	else
+ 		page = __alloc_pages_nodemask(gfp, order,
+ 				policy_zonelist(gfp, pol, numa_node_id()),
+-				policy_nodemask(gfp, pol));
++				policy_nodemask(gfp, pol),
++				NULL, NULL);
+ 
+ 	if (unlikely(!put_mems_allowed(cpuset_mems_cookie) && !page))
+ 		goto retry_cpuset;
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index c3edb62..0ba9f63 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -1846,7 +1846,8 @@ static inline void init_zone_allows_reclaim(int nid)
+ static struct page *
+ get_page_from_freelist(gfp_t gfp_mask, nodemask_t *nodemask, unsigned int order,
+ 		struct zonelist *zonelist, int high_zoneidx, int alloc_flags,
+-		struct zone *preferred_zone, int migratetype)
++		struct zone *preferred_zone, int migratetype,
++		unsigned long *nr_pages, struct page **pages)
+ {
+ 	struct zoneref *z;
+ 	struct page *page = NULL;
+@@ -1968,8 +1969,33 @@ zonelist_scan:
+ try_this_zone:
+ 		page = buffered_rmqueue(preferred_zone, zone, order,
+ 						gfp_mask, migratetype);
+-		if (page)
++		if (page) {
++			unsigned long mark;
++			unsigned long count;
++			unsigned long nr;
++
++			if (likely(!nr_pages))
++				break;
++
++			count = 0;
++			pages[count++] = page;
++			mark = zone->watermark[alloc_flags & ALLOC_WMARK_MASK];
++			nr = *nr_pages;
++			while (count < nr) {
++				if (!zone_watermark_ok(zone, order, mark,
++					classzone_idx, alloc_flags))
++					break;
++				page = buffered_rmqueue(preferred_zone, zone,
++						order, gfp_mask, migratetype);
++				if (!page)
++					break;
++				pages[count++] = page;
++			}
++			*nr_pages = count;
++			page = pages[0];
+ 			break;
++		}
++
+ this_zone_full:
+ 		if (IS_ENABLED(CONFIG_NUMA))
+ 			zlc_mark_zone_full(zonelist, z);
+@@ -2125,7 +2151,8 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order,
+ 	page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, nodemask,
+ 		order, zonelist, high_zoneidx,
+ 		ALLOC_WMARK_HIGH|ALLOC_CPUSET,
+-		preferred_zone, migratetype);
++		preferred_zone, migratetype,
++		NULL, NULL);
+ 	if (page)
+ 		goto out;
+ 
+@@ -2188,7 +2215,8 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,
+ 		page = get_page_from_freelist(gfp_mask, nodemask,
+ 				order, zonelist, high_zoneidx,
+ 				alloc_flags & ~ALLOC_NO_WATERMARKS,
+-				preferred_zone, migratetype);
++				preferred_zone, migratetype,
++				NULL, NULL);
+ 		if (page) {
+ 			preferred_zone->compact_blockskip_flush = false;
+ 			preferred_zone->compact_considered = 0;
+@@ -2282,7 +2310,8 @@ retry:
+ 	page = get_page_from_freelist(gfp_mask, nodemask, order,
+ 					zonelist, high_zoneidx,
+ 					alloc_flags & ~ALLOC_NO_WATERMARKS,
+-					preferred_zone, migratetype);
++					preferred_zone, migratetype,
++					NULL, NULL);
+ 
+ 	/*
+ 	 * If an allocation failed after direct reclaim, it could be because
+@@ -2312,7 +2341,8 @@ __alloc_pages_high_priority(gfp_t gfp_mask, unsigned int order,
+ 	do {
+ 		page = get_page_from_freelist(gfp_mask, nodemask, order,
+ 			zonelist, high_zoneidx, ALLOC_NO_WATERMARKS,
+-			preferred_zone, migratetype);
++			preferred_zone, migratetype,
++			NULL, NULL);
+ 
+ 		if (!page && gfp_mask & __GFP_NOFAIL)
+ 			wait_iff_congested(preferred_zone, BLK_RW_ASYNC, HZ/50);
+@@ -2449,7 +2479,8 @@ rebalance:
+ 	/* This is the last chance, in general, before the goto nopage. */
+ 	page = get_page_from_freelist(gfp_mask, nodemask, order, zonelist,
+ 			high_zoneidx, alloc_flags & ~ALLOC_NO_WATERMARKS,
+-			preferred_zone, migratetype);
++			preferred_zone, migratetype,
++			NULL, NULL);
+ 	if (page)
+ 		goto got_pg;
+ 
+@@ -2598,7 +2629,8 @@ got_pg:
+  */
+ struct page *
+ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order,
+-			struct zonelist *zonelist, nodemask_t *nodemask)
++			struct zonelist *zonelist, nodemask_t *nodemask,
++			unsigned long *nr_pages, struct page **pages)
+ {
+ 	enum zone_type high_zoneidx = gfp_zone(gfp_mask);
+ 	struct zone *preferred_zone;
+@@ -2647,9 +2679,11 @@ retry_cpuset:
+ 		alloc_flags |= ALLOC_CMA;
+ #endif
+ 	/* First allocation attempt */
++	/* We only try to allocate nr_pages in first attempt */
+ 	page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, nodemask, order,
+ 			zonelist, high_zoneidx, alloc_flags,
+-			preferred_zone, migratetype);
++			preferred_zone, migratetype,
++			nr_pages, pages);
+ 	if (unlikely(!page)) {
+ 		/*
+ 		 * Runtime PM, block IO and its error handling path
+-- 
+1.7.9.5
diff --git a/a/content_digest b/N1/content_digest
index d5b8ea3..77e6b97 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -59,6 +59,200 @@
  "\n"
  "Thanks.\n"
  "\n"
- -------------------------------8<----------------------------
+ "-------------------------------8<----------------------------\n"
+ ">From cee05ad3bcf1c5774fabf797b5dc8f78f812ca36 Mon Sep 17 00:00:00 2001\n"
+ "From: Joonsoo Kim <iamjoonsoo.kim@lge.com>\n"
+ "Date: Wed, 26 Jun 2013 13:37:57 +0900\n"
+ "Subject: [PATCH] mm, page_alloc: support multiple pages allocation\n"
+ "\n"
+ "This patch introduces multiple pages allocation feature to buddy\n"
+ "allocator. Currently, there is no ability to allocate multiple\n"
+ "pages at once, so we should invoke single page allocation logic\n"
+ "repeatedly. This has some overheads like as function call\n"
+ "overhead with many arguments and overhead for finding proper\n"
+ "node and zone.\n"
+ "\n"
+ "With this patchset, we can reduce these overheads. Device I/O is\n"
+ "getting faster rapidly and allocator should catch up this speed.\n"
+ "This patch help this situation.\n"
+ "\n"
+ "In this patch, I introduce new arguments, nr_pages and pages, to\n"
+ "core function of allocator and try to allocate multiple pages\n"
+ "in first attempt(fast path). I think that multiple page allocation\n"
+ "is not valid for slow path, so current implementation consider\n"
+ "just fast path.\n"
+ "\n"
+ "Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>\n"
+ "\n"
+ "diff --git a/include/linux/gfp.h b/include/linux/gfp.h\n"
+ "index 0f615eb..8bfa87b 100644\n"
+ "--- a/include/linux/gfp.h\n"
+ "+++ b/include/linux/gfp.h\n"
+ "@@ -298,13 +298,15 @@ static inline void arch_alloc_page(struct page *page, int order) { }\n"
+ " \n"
+ " struct page *\n"
+ " __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order,\n"
+ "-\t\t       struct zonelist *zonelist, nodemask_t *nodemask);\n"
+ "+\t\t       struct zonelist *zonelist, nodemask_t *nodemask,\n"
+ "+\t\t       unsigned long *nr_pages, struct page **pages);\n"
+ " \n"
+ " static inline struct page *\n"
+ " __alloc_pages(gfp_t gfp_mask, unsigned int order,\n"
+ " \t\tstruct zonelist *zonelist)\n"
+ " {\n"
+ "-\treturn __alloc_pages_nodemask(gfp_mask, order, zonelist, NULL);\n"
+ "+\treturn __alloc_pages_nodemask(gfp_mask, order,\n"
+ "+\t\t\t\tzonelist, NULL, NULL, NULL);\n"
+ " }\n"
+ " \n"
+ " static inline struct page *alloc_pages_node(int nid, gfp_t gfp_mask,\n"
+ "diff --git a/mm/mempolicy.c b/mm/mempolicy.c\n"
+ "index 7431001..b17e48c 100644\n"
+ "--- a/mm/mempolicy.c\n"
+ "+++ b/mm/mempolicy.c\n"
+ "@@ -2004,7 +2004,8 @@ retry_cpuset:\n"
+ " \t}\n"
+ " \tpage = __alloc_pages_nodemask(gfp, order,\n"
+ " \t\t\t\t      policy_zonelist(gfp, pol, node),\n"
+ "-\t\t\t\t      policy_nodemask(gfp, pol));\n"
+ "+\t\t\t\t      policy_nodemask(gfp, pol),\n"
+ "+\t\t\t\t      NULL, NULL);\n"
+ " \tif (unlikely(mpol_needs_cond_ref(pol)))\n"
+ " \t\t__mpol_put(pol);\n"
+ " \tif (unlikely(!put_mems_allowed(cpuset_mems_cookie) && !page))\n"
+ "@@ -2052,7 +2053,8 @@ retry_cpuset:\n"
+ " \telse\n"
+ " \t\tpage = __alloc_pages_nodemask(gfp, order,\n"
+ " \t\t\t\tpolicy_zonelist(gfp, pol, numa_node_id()),\n"
+ "-\t\t\t\tpolicy_nodemask(gfp, pol));\n"
+ "+\t\t\t\tpolicy_nodemask(gfp, pol),\n"
+ "+\t\t\t\tNULL, NULL);\n"
+ " \n"
+ " \tif (unlikely(!put_mems_allowed(cpuset_mems_cookie) && !page))\n"
+ " \t\tgoto retry_cpuset;\n"
+ "diff --git a/mm/page_alloc.c b/mm/page_alloc.c\n"
+ "index c3edb62..0ba9f63 100644\n"
+ "--- a/mm/page_alloc.c\n"
+ "+++ b/mm/page_alloc.c\n"
+ "@@ -1846,7 +1846,8 @@ static inline void init_zone_allows_reclaim(int nid)\n"
+ " static struct page *\n"
+ " get_page_from_freelist(gfp_t gfp_mask, nodemask_t *nodemask, unsigned int order,\n"
+ " \t\tstruct zonelist *zonelist, int high_zoneidx, int alloc_flags,\n"
+ "-\t\tstruct zone *preferred_zone, int migratetype)\n"
+ "+\t\tstruct zone *preferred_zone, int migratetype,\n"
+ "+\t\tunsigned long *nr_pages, struct page **pages)\n"
+ " {\n"
+ " \tstruct zoneref *z;\n"
+ " \tstruct page *page = NULL;\n"
+ "@@ -1968,8 +1969,33 @@ zonelist_scan:\n"
+ " try_this_zone:\n"
+ " \t\tpage = buffered_rmqueue(preferred_zone, zone, order,\n"
+ " \t\t\t\t\t\tgfp_mask, migratetype);\n"
+ "-\t\tif (page)\n"
+ "+\t\tif (page) {\n"
+ "+\t\t\tunsigned long mark;\n"
+ "+\t\t\tunsigned long count;\n"
+ "+\t\t\tunsigned long nr;\n"
+ "+\n"
+ "+\t\t\tif (likely(!nr_pages))\n"
+ "+\t\t\t\tbreak;\n"
+ "+\n"
+ "+\t\t\tcount = 0;\n"
+ "+\t\t\tpages[count++] = page;\n"
+ "+\t\t\tmark = zone->watermark[alloc_flags & ALLOC_WMARK_MASK];\n"
+ "+\t\t\tnr = *nr_pages;\n"
+ "+\t\t\twhile (count < nr) {\n"
+ "+\t\t\t\tif (!zone_watermark_ok(zone, order, mark,\n"
+ "+\t\t\t\t\tclasszone_idx, alloc_flags))\n"
+ "+\t\t\t\t\tbreak;\n"
+ "+\t\t\t\tpage = buffered_rmqueue(preferred_zone, zone,\n"
+ "+\t\t\t\t\t\torder, gfp_mask, migratetype);\n"
+ "+\t\t\t\tif (!page)\n"
+ "+\t\t\t\t\tbreak;\n"
+ "+\t\t\t\tpages[count++] = page;\n"
+ "+\t\t\t}\n"
+ "+\t\t\t*nr_pages = count;\n"
+ "+\t\t\tpage = pages[0];\n"
+ " \t\t\tbreak;\n"
+ "+\t\t}\n"
+ "+\n"
+ " this_zone_full:\n"
+ " \t\tif (IS_ENABLED(CONFIG_NUMA))\n"
+ " \t\t\tzlc_mark_zone_full(zonelist, z);\n"
+ "@@ -2125,7 +2151,8 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order,\n"
+ " \tpage = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, nodemask,\n"
+ " \t\torder, zonelist, high_zoneidx,\n"
+ " \t\tALLOC_WMARK_HIGH|ALLOC_CPUSET,\n"
+ "-\t\tpreferred_zone, migratetype);\n"
+ "+\t\tpreferred_zone, migratetype,\n"
+ "+\t\tNULL, NULL);\n"
+ " \tif (page)\n"
+ " \t\tgoto out;\n"
+ " \n"
+ "@@ -2188,7 +2215,8 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,\n"
+ " \t\tpage = get_page_from_freelist(gfp_mask, nodemask,\n"
+ " \t\t\t\torder, zonelist, high_zoneidx,\n"
+ " \t\t\t\talloc_flags & ~ALLOC_NO_WATERMARKS,\n"
+ "-\t\t\t\tpreferred_zone, migratetype);\n"
+ "+\t\t\t\tpreferred_zone, migratetype,\n"
+ "+\t\t\t\tNULL, NULL);\n"
+ " \t\tif (page) {\n"
+ " \t\t\tpreferred_zone->compact_blockskip_flush = false;\n"
+ " \t\t\tpreferred_zone->compact_considered = 0;\n"
+ "@@ -2282,7 +2310,8 @@ retry:\n"
+ " \tpage = get_page_from_freelist(gfp_mask, nodemask, order,\n"
+ " \t\t\t\t\tzonelist, high_zoneidx,\n"
+ " \t\t\t\t\talloc_flags & ~ALLOC_NO_WATERMARKS,\n"
+ "-\t\t\t\t\tpreferred_zone, migratetype);\n"
+ "+\t\t\t\t\tpreferred_zone, migratetype,\n"
+ "+\t\t\t\t\tNULL, NULL);\n"
+ " \n"
+ " \t/*\n"
+ " \t * If an allocation failed after direct reclaim, it could be because\n"
+ "@@ -2312,7 +2341,8 @@ __alloc_pages_high_priority(gfp_t gfp_mask, unsigned int order,\n"
+ " \tdo {\n"
+ " \t\tpage = get_page_from_freelist(gfp_mask, nodemask, order,\n"
+ " \t\t\tzonelist, high_zoneidx, ALLOC_NO_WATERMARKS,\n"
+ "-\t\t\tpreferred_zone, migratetype);\n"
+ "+\t\t\tpreferred_zone, migratetype,\n"
+ "+\t\t\tNULL, NULL);\n"
+ " \n"
+ " \t\tif (!page && gfp_mask & __GFP_NOFAIL)\n"
+ " \t\t\twait_iff_congested(preferred_zone, BLK_RW_ASYNC, HZ/50);\n"
+ "@@ -2449,7 +2479,8 @@ rebalance:\n"
+ " \t/* This is the last chance, in general, before the goto nopage. */\n"
+ " \tpage = get_page_from_freelist(gfp_mask, nodemask, order, zonelist,\n"
+ " \t\t\thigh_zoneidx, alloc_flags & ~ALLOC_NO_WATERMARKS,\n"
+ "-\t\t\tpreferred_zone, migratetype);\n"
+ "+\t\t\tpreferred_zone, migratetype,\n"
+ "+\t\t\tNULL, NULL);\n"
+ " \tif (page)\n"
+ " \t\tgoto got_pg;\n"
+ " \n"
+ "@@ -2598,7 +2629,8 @@ got_pg:\n"
+ "  */\n"
+ " struct page *\n"
+ " __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order,\n"
+ "-\t\t\tstruct zonelist *zonelist, nodemask_t *nodemask)\n"
+ "+\t\t\tstruct zonelist *zonelist, nodemask_t *nodemask,\n"
+ "+\t\t\tunsigned long *nr_pages, struct page **pages)\n"
+ " {\n"
+ " \tenum zone_type high_zoneidx = gfp_zone(gfp_mask);\n"
+ " \tstruct zone *preferred_zone;\n"
+ "@@ -2647,9 +2679,11 @@ retry_cpuset:\n"
+ " \t\talloc_flags |= ALLOC_CMA;\n"
+ " #endif\n"
+ " \t/* First allocation attempt */\n"
+ "+\t/* We only try to allocate nr_pages in first attempt */\n"
+ " \tpage = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, nodemask, order,\n"
+ " \t\t\tzonelist, high_zoneidx, alloc_flags,\n"
+ "-\t\t\tpreferred_zone, migratetype);\n"
+ "+\t\t\tpreferred_zone, migratetype,\n"
+ "+\t\t\tnr_pages, pages);\n"
+ " \tif (unlikely(!page)) {\n"
+ " \t\t/*\n"
+ " \t\t * Runtime PM, block IO and its error handling path\n"
+ "-- \n"
+ 1.7.9.5
 
-6f1ddb85c9f4679ee6a2610f8d763e07f521e61ae9262caa99d38a4bcf694991
+5ea96d22e4a56f8b8b74d2bf324f037cceaac4fa816e895706ee7af02cbdcd7d

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.