[PATCH 09/18] mm: Finish handling MPOL_PREFERRED_MANY

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Now that there is a function to generate the preferred zonelist given a
preferred mask, bindmask, and flags it is possible to support
MPOL_PREFERRED_MANY policy easily in more places.

This patch was developed on top of Dave's original work. When Dave wrote
his patches there was no clean way to implement MPOL_PREFERRED_MANY. Now
that the other bits are in place, this is easy to drop on top.

Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
Cc: Dan Williams <dan.j.williams@xxxxxxxxx>
Cc: Dave Hansen <dave.hansen@xxxxxxxxxxxxxxx>
Cc: Mel Gorman <mgorman@xxxxxxxxxxxxxxxxxxx>
Signed-off-by: Ben Widawsky <ben.widawsky@xxxxxxxxx>
---
 include/linux/mmzone.h |  3 +++
 mm/mempolicy.c         | 20 ++++++++++++++++++--
 mm/page_alloc.c        |  5 ++---
 3 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index c4c37fd12104..6b62ee98bb96 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -1001,6 +1001,9 @@ struct zoneref *__next_zones_zonelist(struct zoneref *z,
 					enum zone_type highest_zoneidx,
 					nodemask_t *nodes);
 
+struct zonelist *preferred_zonelist(gfp_t gfp_mask, const nodemask_t *prefmask,
+				    const nodemask_t *bindmask);
+
 /**
  * next_zones_zonelist - Returns the next zone at or below highest_zoneidx within the allowed nodemask using a cursor within a zonelist as a starting point
  * @z - The cursor used as a starting point for the search
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index bfc4ef2af90d..90bc9c93b1b9 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -1995,7 +1995,6 @@ unsigned int mempolicy_slab_node(void)
 		return node;
 
 	switch (policy->mode) {
-	case MPOL_PREFERRED_MANY:
 	case MPOL_PREFERRED:
 		/*
 		 * handled MPOL_F_LOCAL above
@@ -2020,6 +2019,18 @@ unsigned int mempolicy_slab_node(void)
 		return z->zone ? zone_to_nid(z->zone) : node;
 	}
 
+	case MPOL_PREFERRED_MANY: {
+		struct zoneref *z;
+		struct zonelist *zonelist;
+		enum zone_type highest_zoneidx = gfp_zone(GFP_KERNEL);
+
+		zonelist = preferred_zonelist(GFP_KERNEL,
+					      &policy->v.preferred_nodes, NULL);
+		z = first_zones_zonelist(zonelist, highest_zoneidx,
+					 &policy->v.nodes);
+		return z->zone ? zone_to_nid(z->zone) : node;
+	}
+
 	default:
 		BUG();
 	}
@@ -2585,7 +2596,12 @@ int mpol_misplaced(struct page *page, struct vm_area_struct *vma, unsigned long
 		polnid = zone_to_nid(z->zone);
 		break;
 
-	/* case MPOL_PREFERRED_MANY: */
+	case MPOL_PREFERRED_MANY:
+		z = first_zones_zonelist(preferred_zonelist(GFP_HIGHUSER,
+							    &pol->v.preferred_nodes, NULL),
+					 gfp_zone(GFP_HIGHUSER), &pol->v.preferred_nodes);
+		polnid = zone_to_nid(z->zone);
+		break;
 
 	default:
 		BUG();
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 3cf44b6c31ae..c6f8f112a5d4 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -4861,9 +4861,8 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
  * NB: That zonelist will have *all* zones in the fallback case, and not all of
  * those zones will belong to preferred nodes.
  */
-static struct zonelist *preferred_zonelist(gfp_t gfp_mask,
-					   const nodemask_t *prefmask,
-					   const nodemask_t *bindmask)
+struct zonelist *preferred_zonelist(gfp_t gfp_mask, const nodemask_t *prefmask,
+				    const nodemask_t *bindmask)
 {
 	nodemask_t pref;
 	int nid, local_node = numa_mem_id();
-- 
2.27.0





[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux