Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 344789
b: refs/heads/master
c: 771fb4d
h: refs/heads/master
i:
  344787: a77259b
v: v3
  • Loading branch information
Lee Schermerhorn authored and Mel Gorman committed Dec 11, 2012
1 parent d014763 commit 301bc25
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d3a710337b0590f43fd236d5e6518439afc7410a
refs/heads/master: 771fb4d806a92bf6c988fcfbd286ae40a9374332
8 changes: 8 additions & 0 deletions trunk/include/linux/mempolicy.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ static inline int vma_migratable(struct vm_area_struct *vma)
return 1;
}

extern int mpol_misplaced(struct page *, struct vm_area_struct *, unsigned long);

#else

struct mempolicy {};
Expand Down Expand Up @@ -323,5 +325,11 @@ static inline int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol,
return 0;
}

static inline int mpol_misplaced(struct page *page, struct vm_area_struct *vma,
unsigned long address)
{
return -1; /* no node preference */
}

#endif /* CONFIG_NUMA */
#endif
1 change: 1 addition & 0 deletions trunk/include/uapi/linux/mempolicy.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ enum mpol_rebind_step {
#define MPOL_F_SHARED (1 << 0) /* identify shared policies */
#define MPOL_F_LOCAL (1 << 1) /* preferred local allocation */
#define MPOL_F_REBINDING (1 << 2) /* identify policies in rebinding */
#define MPOL_F_MOF (1 << 3) /* this policy wants migrate on fault */


#endif /* _UAPI_LINUX_MEMPOLICY_H */
76 changes: 76 additions & 0 deletions trunk/mm/mempolicy.c
Original file line number Diff line number Diff line change
Expand Up @@ -2181,6 +2181,82 @@ static void sp_free(struct sp_node *n)
kmem_cache_free(sn_cache, n);
}

/**
* mpol_misplaced - check whether current page node is valid in policy
*
* @page - page to be checked
* @vma - vm area where page mapped
* @addr - virtual address where page mapped
*
* Lookup current policy node id for vma,addr and "compare to" page's
* node id.
*
* Returns:
* -1 - not misplaced, page is in the right node
* node - node id where the page should be
*
* Policy determination "mimics" alloc_page_vma().
* Called from fault path where we know the vma and faulting address.
*/
int mpol_misplaced(struct page *page, struct vm_area_struct *vma, unsigned long addr)
{
struct mempolicy *pol;
struct zone *zone;
int curnid = page_to_nid(page);
unsigned long pgoff;
int polnid = -1;
int ret = -1;

BUG_ON(!vma);

pol = get_vma_policy(current, vma, addr);
if (!(pol->flags & MPOL_F_MOF))
goto out;

switch (pol->mode) {
case MPOL_INTERLEAVE:
BUG_ON(addr >= vma->vm_end);
BUG_ON(addr < vma->vm_start);

pgoff = vma->vm_pgoff;
pgoff += (addr - vma->vm_start) >> PAGE_SHIFT;
polnid = offset_il_node(pol, vma, pgoff);
break;

case MPOL_PREFERRED:
if (pol->flags & MPOL_F_LOCAL)
polnid = numa_node_id();
else
polnid = pol->v.preferred_node;
break;

case MPOL_BIND:
/*
* allows binding to multiple nodes.
* use current page if in policy nodemask,
* else select nearest allowed node, if any.
* If no allowed nodes, use current [!misplaced].
*/
if (node_isset(curnid, pol->v.nodes))
goto out;
(void)first_zones_zonelist(
node_zonelist(numa_node_id(), GFP_HIGHUSER),
gfp_zone(GFP_HIGHUSER),
&pol->v.nodes, &zone);
polnid = zone->node;
break;

default:
BUG();
}
if (curnid != polnid)
ret = polnid;
out:
mpol_cond_put(pol);

return ret;
}

static void sp_delete(struct shared_policy *sp, struct sp_node *n)
{
pr_debug("deleting %lx-l%lx\n", n->start, n->end);
Expand Down

0 comments on commit 301bc25

Please sign in to comment.