aboutsummaryrefslogtreecommitdiffstats
path: root/mm/mempolicy.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/mempolicy.c')
-rw-r--r--mm/mempolicy.c102
1 files changed, 33 insertions, 69 deletions
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 72f402cc9c9a..0f1d2b8a952b 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -93,7 +93,7 @@ static kmem_cache_t *sn_cache;
93 93
94/* Highest zone. An specific allocation for a zone below that is not 94/* Highest zone. An specific allocation for a zone below that is not
95 policied. */ 95 policied. */
96static int policy_zone; 96int policy_zone = ZONE_DMA;
97 97
98struct mempolicy default_policy = { 98struct mempolicy default_policy = {
99 .refcnt = ATOMIC_INIT(1), /* never free it */ 99 .refcnt = ATOMIC_INIT(1), /* never free it */
@@ -131,17 +131,8 @@ static struct zonelist *bind_zonelist(nodemask_t *nodes)
131 if (!zl) 131 if (!zl)
132 return NULL; 132 return NULL;
133 num = 0; 133 num = 0;
134 for_each_node_mask(nd, *nodes) { 134 for_each_node_mask(nd, *nodes)
135 int k; 135 zl->zones[num++] = &NODE_DATA(nd)->node_zones[policy_zone];
136 for (k = MAX_NR_ZONES-1; k >= 0; k--) {
137 struct zone *z = &NODE_DATA(nd)->node_zones[k];
138 if (!z->present_pages)
139 continue;
140 zl->zones[num++] = z;
141 if (k > policy_zone)
142 policy_zone = k;
143 }
144 }
145 zl->zones[num] = NULL; 136 zl->zones[num] = NULL;
146 return zl; 137 return zl;
147} 138}
@@ -785,6 +776,34 @@ static unsigned offset_il_node(struct mempolicy *pol,
785 return nid; 776 return nid;
786} 777}
787 778
779/* Determine a node number for interleave */
780static inline unsigned interleave_nid(struct mempolicy *pol,
781 struct vm_area_struct *vma, unsigned long addr, int shift)
782{
783 if (vma) {
784 unsigned long off;
785
786 off = vma->vm_pgoff;
787 off += (addr - vma->vm_start) >> shift;
788 return offset_il_node(pol, vma, off);
789 } else
790 return interleave_nodes(pol);
791}
792
793/* Return a zonelist suitable for a huge page allocation. */
794struct zonelist *huge_zonelist(struct vm_area_struct *vma, unsigned long addr)
795{
796 struct mempolicy *pol = get_vma_policy(current, vma, addr);
797
798 if (pol->policy == MPOL_INTERLEAVE) {
799 unsigned nid;
800
801 nid = interleave_nid(pol, vma, addr, HPAGE_SHIFT);
802 return NODE_DATA(nid)->node_zonelists + gfp_zone(GFP_HIGHUSER);
803 }
804 return zonelist_policy(GFP_HIGHUSER, pol);
805}
806
788/* Allocate a page in interleaved policy. 807/* Allocate a page in interleaved policy.
789 Own path because it needs to do special accounting. */ 808 Own path because it needs to do special accounting. */
790static struct page *alloc_page_interleave(gfp_t gfp, unsigned order, 809static struct page *alloc_page_interleave(gfp_t gfp, unsigned order,
@@ -833,15 +852,8 @@ alloc_page_vma(gfp_t gfp, struct vm_area_struct *vma, unsigned long addr)
833 852
834 if (unlikely(pol->policy == MPOL_INTERLEAVE)) { 853 if (unlikely(pol->policy == MPOL_INTERLEAVE)) {
835 unsigned nid; 854 unsigned nid;
836 if (vma) { 855
837 unsigned long off; 856 nid = interleave_nid(pol, vma, addr, PAGE_SHIFT);
838 off = vma->vm_pgoff;
839 off += (addr - vma->vm_start) >> PAGE_SHIFT;
840 nid = offset_il_node(pol, vma, off);
841 } else {
842 /* fall back to process interleaving */
843 nid = interleave_nodes(pol);
844 }
845 return alloc_page_interleave(gfp, 0, nid); 857 return alloc_page_interleave(gfp, 0, nid);
846 } 858 }
847 return __alloc_pages(gfp, 0, zonelist_policy(gfp, pol)); 859 return __alloc_pages(gfp, 0, zonelist_policy(gfp, pol));
@@ -940,54 +952,6 @@ void __mpol_free(struct mempolicy *p)
940} 952}
941 953
942/* 954/*
943 * Hugetlb policy. Same as above, just works with node numbers instead of
944 * zonelists.
945 */
946
947/* Find first node suitable for an allocation */
948int mpol_first_node(struct vm_area_struct *vma, unsigned long addr)
949{
950 struct mempolicy *pol = get_vma_policy(current, vma, addr);
951
952 switch (pol->policy) {
953 case MPOL_DEFAULT:
954 return numa_node_id();
955 case MPOL_BIND:
956 return pol->v.zonelist->zones[0]->zone_pgdat->node_id;
957 case MPOL_INTERLEAVE:
958 return interleave_nodes(pol);
959 case MPOL_PREFERRED:
960 return pol->v.preferred_node >= 0 ?
961 pol->v.preferred_node : numa_node_id();
962 }
963 BUG();
964 return 0;
965}
966
967/* Find secondary valid nodes for an allocation */
968int mpol_node_valid(int nid, struct vm_area_struct *vma, unsigned long addr)
969{
970 struct mempolicy *pol = get_vma_policy(current, vma, addr);
971
972 switch (pol->policy) {
973 case MPOL_PREFERRED:
974 case MPOL_DEFAULT:
975 case MPOL_INTERLEAVE:
976 return 1;
977 case MPOL_BIND: {
978 struct zone **z;
979 for (z = pol->v.zonelist->zones; *z; z++)
980 if ((*z)->zone_pgdat->node_id == nid)
981 return 1;
982 return 0;
983 }
984 default:
985 BUG();
986 return 0;
987 }
988}
989
990/*
991 * Shared memory backing store policy support. 955 * Shared memory backing store policy support.
992 * 956 *
993 * Remember policies even when nobody has shared memory mapped. 957 * Remember policies even when nobody has shared memory mapped.