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.