diff options
Diffstat (limited to 'mm/slab.c')
-rw-r--r-- | mm/slab.c | 136 |
1 files changed, 78 insertions, 58 deletions
@@ -604,6 +604,26 @@ static struct kmem_cache cache_cache = { | |||
604 | 604 | ||
605 | #define BAD_ALIEN_MAGIC 0x01020304ul | 605 | #define BAD_ALIEN_MAGIC 0x01020304ul |
606 | 606 | ||
607 | /* | ||
608 | * chicken and egg problem: delay the per-cpu array allocation | ||
609 | * until the general caches are up. | ||
610 | */ | ||
611 | static enum { | ||
612 | NONE, | ||
613 | PARTIAL_AC, | ||
614 | PARTIAL_L3, | ||
615 | EARLY, | ||
616 | FULL | ||
617 | } g_cpucache_up; | ||
618 | |||
619 | /* | ||
620 | * used by boot code to determine if it can use slab based allocator | ||
621 | */ | ||
622 | int slab_is_available(void) | ||
623 | { | ||
624 | return g_cpucache_up >= EARLY; | ||
625 | } | ||
626 | |||
607 | #ifdef CONFIG_LOCKDEP | 627 | #ifdef CONFIG_LOCKDEP |
608 | 628 | ||
609 | /* | 629 | /* |
@@ -620,40 +640,52 @@ static struct kmem_cache cache_cache = { | |||
620 | static struct lock_class_key on_slab_l3_key; | 640 | static struct lock_class_key on_slab_l3_key; |
621 | static struct lock_class_key on_slab_alc_key; | 641 | static struct lock_class_key on_slab_alc_key; |
622 | 642 | ||
623 | static inline void init_lock_keys(void) | 643 | static void init_node_lock_keys(int q) |
624 | |||
625 | { | 644 | { |
626 | int q; | ||
627 | struct cache_sizes *s = malloc_sizes; | 645 | struct cache_sizes *s = malloc_sizes; |
628 | 646 | ||
629 | while (s->cs_size != ULONG_MAX) { | 647 | if (g_cpucache_up != FULL) |
630 | for_each_node(q) { | 648 | return; |
631 | struct array_cache **alc; | 649 | |
632 | int r; | 650 | for (s = malloc_sizes; s->cs_size != ULONG_MAX; s++) { |
633 | struct kmem_list3 *l3 = s->cs_cachep->nodelists[q]; | 651 | struct array_cache **alc; |
634 | if (!l3 || OFF_SLAB(s->cs_cachep)) | 652 | struct kmem_list3 *l3; |
635 | continue; | 653 | int r; |
636 | lockdep_set_class(&l3->list_lock, &on_slab_l3_key); | 654 | |
637 | alc = l3->alien; | 655 | l3 = s->cs_cachep->nodelists[q]; |
638 | /* | 656 | if (!l3 || OFF_SLAB(s->cs_cachep)) |
639 | * FIXME: This check for BAD_ALIEN_MAGIC | 657 | return; |
640 | * should go away when common slab code is taught to | 658 | lockdep_set_class(&l3->list_lock, &on_slab_l3_key); |
641 | * work even without alien caches. | 659 | alc = l3->alien; |
642 | * Currently, non NUMA code returns BAD_ALIEN_MAGIC | 660 | /* |
643 | * for alloc_alien_cache, | 661 | * FIXME: This check for BAD_ALIEN_MAGIC |
644 | */ | 662 | * should go away when common slab code is taught to |
645 | if (!alc || (unsigned long)alc == BAD_ALIEN_MAGIC) | 663 | * work even without alien caches. |
646 | continue; | 664 | * Currently, non NUMA code returns BAD_ALIEN_MAGIC |
647 | for_each_node(r) { | 665 | * for alloc_alien_cache, |
648 | if (alc[r]) | 666 | */ |
649 | lockdep_set_class(&alc[r]->lock, | 667 | if (!alc || (unsigned long)alc == BAD_ALIEN_MAGIC) |
650 | &on_slab_alc_key); | 668 | return; |
651 | } | 669 | for_each_node(r) { |
670 | if (alc[r]) | ||
671 | lockdep_set_class(&alc[r]->lock, | ||
672 | &on_slab_alc_key); | ||
652 | } | 673 | } |
653 | s++; | ||
654 | } | 674 | } |
655 | } | 675 | } |
676 | |||
677 | static inline void init_lock_keys(void) | ||
678 | { | ||
679 | int node; | ||
680 | |||
681 | for_each_node(node) | ||
682 | init_node_lock_keys(node); | ||
683 | } | ||
656 | #else | 684 | #else |
685 | static void init_node_lock_keys(int q) | ||
686 | { | ||
687 | } | ||
688 | |||
657 | static inline void init_lock_keys(void) | 689 | static inline void init_lock_keys(void) |
658 | { | 690 | { |
659 | } | 691 | } |
@@ -665,27 +697,7 @@ static inline void init_lock_keys(void) | |||
665 | static DEFINE_MUTEX(cache_chain_mutex); | 697 | static DEFINE_MUTEX(cache_chain_mutex); |
666 | static struct list_head cache_chain; | 698 | static struct list_head cache_chain; |
667 | 699 | ||
668 | /* | 700 | static DEFINE_PER_CPU(struct delayed_work, slab_reap_work); |
669 | * chicken and egg problem: delay the per-cpu array allocation | ||
670 | * until the general caches are up. | ||
671 | */ | ||
672 | static enum { | ||
673 | NONE, | ||
674 | PARTIAL_AC, | ||
675 | PARTIAL_L3, | ||
676 | EARLY, | ||
677 | FULL | ||
678 | } g_cpucache_up; | ||
679 | |||
680 | /* | ||
681 | * used by boot code to determine if it can use slab based allocator | ||
682 | */ | ||
683 | int slab_is_available(void) | ||
684 | { | ||
685 | return g_cpucache_up >= EARLY; | ||
686 | } | ||
687 | |||
688 | static DEFINE_PER_CPU(struct delayed_work, reap_work); | ||
689 | 701 | ||
690 | static inline struct array_cache *cpu_cache_get(struct kmem_cache *cachep) | 702 | static inline struct array_cache *cpu_cache_get(struct kmem_cache *cachep) |
691 | { | 703 | { |
@@ -826,7 +838,7 @@ __setup("noaliencache", noaliencache_setup); | |||
826 | * objects freed on different nodes from which they were allocated) and the | 838 | * objects freed on different nodes from which they were allocated) and the |
827 | * flushing of remote pcps by calling drain_node_pages. | 839 | * flushing of remote pcps by calling drain_node_pages. |
828 | */ | 840 | */ |
829 | static DEFINE_PER_CPU(unsigned long, reap_node); | 841 | static DEFINE_PER_CPU(unsigned long, slab_reap_node); |
830 | 842 | ||
831 | static void init_reap_node(int cpu) | 843 | static void init_reap_node(int cpu) |
832 | { | 844 | { |
@@ -836,17 +848,17 @@ static void init_reap_node(int cpu) | |||
836 | if (node == MAX_NUMNODES) | 848 | if (node == MAX_NUMNODES) |
837 | node = first_node(node_online_map); | 849 | node = first_node(node_online_map); |
838 | 850 | ||
839 | per_cpu(reap_node, cpu) = node; | 851 | per_cpu(slab_reap_node, cpu) = node; |
840 | } | 852 | } |
841 | 853 | ||
842 | static void next_reap_node(void) | 854 | static void next_reap_node(void) |
843 | { | 855 | { |
844 | int node = __get_cpu_var(reap_node); | 856 | int node = __get_cpu_var(slab_reap_node); |
845 | 857 | ||
846 | node = next_node(node, node_online_map); | 858 | node = next_node(node, node_online_map); |
847 | if (unlikely(node >= MAX_NUMNODES)) | 859 | if (unlikely(node >= MAX_NUMNODES)) |
848 | node = first_node(node_online_map); | 860 | node = first_node(node_online_map); |
849 | __get_cpu_var(reap_node) = node; | 861 | __get_cpu_var(slab_reap_node) = node; |
850 | } | 862 | } |
851 | 863 | ||
852 | #else | 864 | #else |
@@ -863,7 +875,7 @@ static void next_reap_node(void) | |||
863 | */ | 875 | */ |
864 | static void __cpuinit start_cpu_timer(int cpu) | 876 | static void __cpuinit start_cpu_timer(int cpu) |
865 | { | 877 | { |
866 | struct delayed_work *reap_work = &per_cpu(reap_work, cpu); | 878 | struct delayed_work *reap_work = &per_cpu(slab_reap_work, cpu); |
867 | 879 | ||
868 | /* | 880 | /* |
869 | * When this gets called from do_initcalls via cpucache_init(), | 881 | * When this gets called from do_initcalls via cpucache_init(), |
@@ -1027,7 +1039,7 @@ static void __drain_alien_cache(struct kmem_cache *cachep, | |||
1027 | */ | 1039 | */ |
1028 | static void reap_alien(struct kmem_cache *cachep, struct kmem_list3 *l3) | 1040 | static void reap_alien(struct kmem_cache *cachep, struct kmem_list3 *l3) |
1029 | { | 1041 | { |
1030 | int node = __get_cpu_var(reap_node); | 1042 | int node = __get_cpu_var(slab_reap_node); |
1031 | 1043 | ||
1032 | if (l3->alien) { | 1044 | if (l3->alien) { |
1033 | struct array_cache *ac = l3->alien[node]; | 1045 | struct array_cache *ac = l3->alien[node]; |
@@ -1254,6 +1266,8 @@ static int __cpuinit cpuup_prepare(long cpu) | |||
1254 | kfree(shared); | 1266 | kfree(shared); |
1255 | free_alien_cache(alien); | 1267 | free_alien_cache(alien); |
1256 | } | 1268 | } |
1269 | init_node_lock_keys(node); | ||
1270 | |||
1257 | return 0; | 1271 | return 0; |
1258 | bad: | 1272 | bad: |
1259 | cpuup_canceled(cpu); | 1273 | cpuup_canceled(cpu); |
@@ -1286,9 +1300,9 @@ static int __cpuinit cpuup_callback(struct notifier_block *nfb, | |||
1286 | * anything expensive but will only modify reap_work | 1300 | * anything expensive but will only modify reap_work |
1287 | * and reschedule the timer. | 1301 | * and reschedule the timer. |
1288 | */ | 1302 | */ |
1289 | cancel_rearming_delayed_work(&per_cpu(reap_work, cpu)); | 1303 | cancel_rearming_delayed_work(&per_cpu(slab_reap_work, cpu)); |
1290 | /* Now the cache_reaper is guaranteed to be not running. */ | 1304 | /* Now the cache_reaper is guaranteed to be not running. */ |
1291 | per_cpu(reap_work, cpu).work.func = NULL; | 1305 | per_cpu(slab_reap_work, cpu).work.func = NULL; |
1292 | break; | 1306 | break; |
1293 | case CPU_DOWN_FAILED: | 1307 | case CPU_DOWN_FAILED: |
1294 | case CPU_DOWN_FAILED_FROZEN: | 1308 | case CPU_DOWN_FAILED_FROZEN: |
@@ -3103,13 +3117,19 @@ static inline void *____cache_alloc(struct kmem_cache *cachep, gfp_t flags) | |||
3103 | } else { | 3117 | } else { |
3104 | STATS_INC_ALLOCMISS(cachep); | 3118 | STATS_INC_ALLOCMISS(cachep); |
3105 | objp = cache_alloc_refill(cachep, flags); | 3119 | objp = cache_alloc_refill(cachep, flags); |
3120 | /* | ||
3121 | * the 'ac' may be updated by cache_alloc_refill(), | ||
3122 | * and kmemleak_erase() requires its correct value. | ||
3123 | */ | ||
3124 | ac = cpu_cache_get(cachep); | ||
3106 | } | 3125 | } |
3107 | /* | 3126 | /* |
3108 | * To avoid a false negative, if an object that is in one of the | 3127 | * To avoid a false negative, if an object that is in one of the |
3109 | * per-CPU caches is leaked, we need to make sure kmemleak doesn't | 3128 | * per-CPU caches is leaked, we need to make sure kmemleak doesn't |
3110 | * treat the array pointers as a reference to the object. | 3129 | * treat the array pointers as a reference to the object. |
3111 | */ | 3130 | */ |
3112 | kmemleak_erase(&ac->entry[ac->avail]); | 3131 | if (objp) |
3132 | kmemleak_erase(&ac->entry[ac->avail]); | ||
3113 | return objp; | 3133 | return objp; |
3114 | } | 3134 | } |
3115 | 3135 | ||
@@ -3306,7 +3326,7 @@ __cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid, | |||
3306 | cache_alloc_debugcheck_before(cachep, flags); | 3326 | cache_alloc_debugcheck_before(cachep, flags); |
3307 | local_irq_save(save_flags); | 3327 | local_irq_save(save_flags); |
3308 | 3328 | ||
3309 | if (unlikely(nodeid == -1)) | 3329 | if (nodeid == -1) |
3310 | nodeid = numa_node_id(); | 3330 | nodeid = numa_node_id(); |
3311 | 3331 | ||
3312 | if (unlikely(!cachep->nodelists[nodeid])) { | 3332 | if (unlikely(!cachep->nodelists[nodeid])) { |