diff options
-rw-r--r-- | include/linux/mempolicy.h | 1 | ||||
-rw-r--r-- | mm/mempolicy.c | 30 | ||||
-rw-r--r-- | mm/slab.c | 12 |
3 files changed, 43 insertions, 0 deletions
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h index d6a53ed6ab6c..bbd2221923c3 100644 --- a/include/linux/mempolicy.h +++ b/include/linux/mempolicy.h | |||
@@ -159,6 +159,7 @@ extern void mpol_rebind_mm(struct mm_struct *mm, nodemask_t *new); | |||
159 | extern struct mempolicy default_policy; | 159 | extern struct mempolicy default_policy; |
160 | extern struct zonelist *huge_zonelist(struct vm_area_struct *vma, | 160 | extern struct zonelist *huge_zonelist(struct vm_area_struct *vma, |
161 | unsigned long addr); | 161 | unsigned long addr); |
162 | extern unsigned slab_node(struct mempolicy *policy); | ||
162 | 163 | ||
163 | extern int policy_zone; | 164 | extern int policy_zone; |
164 | 165 | ||
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index a683a66599b1..71430d440822 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
@@ -976,6 +976,36 @@ static unsigned interleave_nodes(struct mempolicy *policy) | |||
976 | return nid; | 976 | return nid; |
977 | } | 977 | } |
978 | 978 | ||
979 | /* | ||
980 | * Depending on the memory policy provide a node from which to allocate the | ||
981 | * next slab entry. | ||
982 | */ | ||
983 | unsigned slab_node(struct mempolicy *policy) | ||
984 | { | ||
985 | if (in_interrupt()) | ||
986 | return numa_node_id(); | ||
987 | |||
988 | switch (policy->policy) { | ||
989 | case MPOL_INTERLEAVE: | ||
990 | return interleave_nodes(policy); | ||
991 | |||
992 | case MPOL_BIND: | ||
993 | /* | ||
994 | * Follow bind policy behavior and start allocation at the | ||
995 | * first node. | ||
996 | */ | ||
997 | return policy->v.zonelist->zones[0]->zone_pgdat->node_id; | ||
998 | |||
999 | case MPOL_PREFERRED: | ||
1000 | if (policy->v.preferred_node >= 0) | ||
1001 | return policy->v.preferred_node; | ||
1002 | /* Fall through */ | ||
1003 | |||
1004 | default: | ||
1005 | return numa_node_id(); | ||
1006 | } | ||
1007 | } | ||
1008 | |||
979 | /* Do static interleaving for a VMA with known offset. */ | 1009 | /* Do static interleaving for a VMA with known offset. */ |
980 | static unsigned offset_il_node(struct mempolicy *pol, | 1010 | static unsigned offset_il_node(struct mempolicy *pol, |
981 | struct vm_area_struct *vma, unsigned long off) | 1011 | struct vm_area_struct *vma, unsigned long off) |
@@ -103,6 +103,7 @@ | |||
103 | #include <linux/rcupdate.h> | 103 | #include <linux/rcupdate.h> |
104 | #include <linux/string.h> | 104 | #include <linux/string.h> |
105 | #include <linux/nodemask.h> | 105 | #include <linux/nodemask.h> |
106 | #include <linux/mempolicy.h> | ||
106 | #include <linux/mutex.h> | 107 | #include <linux/mutex.h> |
107 | 108 | ||
108 | #include <asm/uaccess.h> | 109 | #include <asm/uaccess.h> |
@@ -773,6 +774,8 @@ static struct array_cache *alloc_arraycache(int node, int entries, | |||
773 | } | 774 | } |
774 | 775 | ||
775 | #ifdef CONFIG_NUMA | 776 | #ifdef CONFIG_NUMA |
777 | static void *__cache_alloc_node(kmem_cache_t *, gfp_t, int); | ||
778 | |||
776 | static inline struct array_cache **alloc_alien_cache(int node, int limit) | 779 | static inline struct array_cache **alloc_alien_cache(int node, int limit) |
777 | { | 780 | { |
778 | struct array_cache **ac_ptr; | 781 | struct array_cache **ac_ptr; |
@@ -2570,6 +2573,15 @@ static inline void *____cache_alloc(kmem_cache_t *cachep, gfp_t flags) | |||
2570 | void *objp; | 2573 | void *objp; |
2571 | struct array_cache *ac; | 2574 | struct array_cache *ac; |
2572 | 2575 | ||
2576 | #ifdef CONFIG_NUMA | ||
2577 | if (current->mempolicy) { | ||
2578 | int nid = slab_node(current->mempolicy); | ||
2579 | |||
2580 | if (nid != numa_node_id()) | ||
2581 | return __cache_alloc_node(cachep, flags, nid); | ||
2582 | } | ||
2583 | #endif | ||
2584 | |||
2573 | check_irq_off(); | 2585 | check_irq_off(); |
2574 | ac = ac_data(cachep); | 2586 | ac = ac_data(cachep); |
2575 | if (likely(ac->avail)) { | 2587 | if (likely(ac->avail)) { |