aboutsummaryrefslogtreecommitdiffstats
path: root/mm/mempolicy.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/mempolicy.c')
-rw-r--r--mm/mempolicy.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 72f402cc9c9a..45c51ac63443 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -785,6 +785,34 @@ static unsigned offset_il_node(struct mempolicy *pol,
785 return nid; 785 return nid;
786} 786}
787 787
788/* Determine a node number for interleave */
789static inline unsigned interleave_nid(struct mempolicy *pol,
790 struct vm_area_struct *vma, unsigned long addr, int shift)
791{
792 if (vma) {
793 unsigned long off;
794
795 off = vma->vm_pgoff;
796 off += (addr - vma->vm_start) >> shift;
797 return offset_il_node(pol, vma, off);
798 } else
799 return interleave_nodes(pol);
800}
801
802/* Return a zonelist suitable for a huge page allocation. */
803struct zonelist *huge_zonelist(struct vm_area_struct *vma, unsigned long addr)
804{
805 struct mempolicy *pol = get_vma_policy(current, vma, addr);
806
807 if (pol->policy == MPOL_INTERLEAVE) {
808 unsigned nid;
809
810 nid = interleave_nid(pol, vma, addr, HPAGE_SHIFT);
811 return NODE_DATA(nid)->node_zonelists + gfp_zone(GFP_HIGHUSER);
812 }
813 return zonelist_policy(GFP_HIGHUSER, pol);
814}
815
788/* Allocate a page in interleaved policy. 816/* Allocate a page in interleaved policy.
789 Own path because it needs to do special accounting. */ 817 Own path because it needs to do special accounting. */
790static struct page *alloc_page_interleave(gfp_t gfp, unsigned order, 818static struct page *alloc_page_interleave(gfp_t gfp, unsigned order,
@@ -833,15 +861,8 @@ alloc_page_vma(gfp_t gfp, struct vm_area_struct *vma, unsigned long addr)
833 861
834 if (unlikely(pol->policy == MPOL_INTERLEAVE)) { 862 if (unlikely(pol->policy == MPOL_INTERLEAVE)) {
835 unsigned nid; 863 unsigned nid;
836 if (vma) { 864
837 unsigned long off; 865 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); 866 return alloc_page_interleave(gfp, 0, nid);
846 } 867 }
847 return __alloc_pages(gfp, 0, zonelist_policy(gfp, pol)); 868 return __alloc_pages(gfp, 0, zonelist_policy(gfp, pol));