aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-12 12:52:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-12 12:52:30 -0400
commit6d21491838a2a9f22843c7530b118596ee9f4d77 (patch)
tree9dcd7a4009d219092c391454efc3dd29b23f52d7
parentc9b8af00ff71f86ff3d092cc60ca673e1d0eae5b (diff)
parent8429db5c6336083594036c30f49401405d536911 (diff)
Merge branch 'topic/slab/earlyboot-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/penberg/slab-2.6
* 'topic/slab/earlyboot-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/penberg/slab-2.6: slab: setup cpu caches later on when interrupts are enabled slab,slub: don't enable interrupts during early boot slab: fix gfp flag in setup_cpu_cache() x86: make zap_low_mapping could be used early irq: slab alloc for default irq_affinity memcg: fix page_cgroup fatal error in FLATMEM
-rw-r--r--arch/x86/include/asm/tlbflush.h2
-rw-r--r--arch/x86/kernel/smpboot.c2
-rw-r--r--arch/x86/mm/init_32.c10
-rw-r--r--include/linux/gfp.h3
-rw-r--r--include/linux/page_cgroup.h18
-rw-r--r--include/linux/slab.h2
-rw-r--r--include/linux/slob_def.h5
-rw-r--r--include/linux/slub_def.h2
-rw-r--r--init/main.c6
-rw-r--r--kernel/irq/handle.c2
-rw-r--r--mm/page_cgroup.c29
-rw-r--r--mm/slab.c41
-rw-r--r--mm/slub.c16
13 files changed, 101 insertions, 37 deletions
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index a5ecc9c33e92..7f3eba08e7de 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -172,6 +172,6 @@ static inline void flush_tlb_kernel_range(unsigned long start,
172 flush_tlb_all(); 172 flush_tlb_all();
173} 173}
174 174
175extern void zap_low_mappings(void); 175extern void zap_low_mappings(bool early);
176 176
177#endif /* _ASM_X86_TLBFLUSH_H */ 177#endif /* _ASM_X86_TLBFLUSH_H */
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 7c80007ea5f7..2fecda69ee64 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -873,7 +873,7 @@ int __cpuinit native_cpu_up(unsigned int cpu)
873 873
874 err = do_boot_cpu(apicid, cpu); 874 err = do_boot_cpu(apicid, cpu);
875 875
876 zap_low_mappings(); 876 zap_low_mappings(false);
877 low_mappings = 0; 877 low_mappings = 0;
878#else 878#else
879 err = do_boot_cpu(apicid, cpu); 879 err = do_boot_cpu(apicid, cpu);
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 949708d7a481..9ff3c0816d15 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -564,7 +564,7 @@ static inline void save_pg_dir(void)
564} 564}
565#endif /* !CONFIG_ACPI_SLEEP */ 565#endif /* !CONFIG_ACPI_SLEEP */
566 566
567void zap_low_mappings(void) 567void zap_low_mappings(bool early)
568{ 568{
569 int i; 569 int i;
570 570
@@ -581,7 +581,11 @@ void zap_low_mappings(void)
581 set_pgd(swapper_pg_dir+i, __pgd(0)); 581 set_pgd(swapper_pg_dir+i, __pgd(0));
582#endif 582#endif
583 } 583 }
584 flush_tlb_all(); 584
585 if (early)
586 __flush_tlb();
587 else
588 flush_tlb_all();
585} 589}
586 590
587pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP); 591pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP);
@@ -956,7 +960,7 @@ void __init mem_init(void)
956 test_wp_bit(); 960 test_wp_bit();
957 961
958 save_pg_dir(); 962 save_pg_dir();
959 zap_low_mappings(); 963 zap_low_mappings(true);
960} 964}
961 965
962#ifdef CONFIG_MEMORY_HOTPLUG 966#ifdef CONFIG_MEMORY_HOTPLUG
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 0bbc15f54536..3760e7c5de02 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -85,6 +85,9 @@ struct vm_area_struct;
85 __GFP_NOWARN|__GFP_REPEAT|__GFP_NOFAIL|\ 85 __GFP_NOWARN|__GFP_REPEAT|__GFP_NOFAIL|\
86 __GFP_NORETRY|__GFP_NOMEMALLOC) 86 __GFP_NORETRY|__GFP_NOMEMALLOC)
87 87
88/* Control slab gfp mask during early boot */
89#define SLAB_GFP_BOOT_MASK __GFP_BITS_MASK & ~(__GFP_WAIT|__GFP_IO|__GFP_FS)
90
88/* Control allocation constraints */ 91/* Control allocation constraints */
89#define GFP_CONSTRAINT_MASK (__GFP_HARDWALL|__GFP_THISNODE) 92#define GFP_CONSTRAINT_MASK (__GFP_HARDWALL|__GFP_THISNODE)
90 93
diff --git a/include/linux/page_cgroup.h b/include/linux/page_cgroup.h
index 7339c7bf7331..13f126c89ae8 100644
--- a/include/linux/page_cgroup.h
+++ b/include/linux/page_cgroup.h
@@ -18,7 +18,19 @@ struct page_cgroup {
18}; 18};
19 19
20void __meminit pgdat_page_cgroup_init(struct pglist_data *pgdat); 20void __meminit pgdat_page_cgroup_init(struct pglist_data *pgdat);
21void __init page_cgroup_init(void); 21
22#ifdef CONFIG_SPARSEMEM
23static inline void __init page_cgroup_init_flatmem(void)
24{
25}
26extern void __init page_cgroup_init(void);
27#else
28void __init page_cgroup_init_flatmem(void);
29static inline void __init page_cgroup_init(void)
30{
31}
32#endif
33
22struct page_cgroup *lookup_page_cgroup(struct page *page); 34struct page_cgroup *lookup_page_cgroup(struct page *page);
23 35
24enum { 36enum {
@@ -87,6 +99,10 @@ static inline void page_cgroup_init(void)
87{ 99{
88} 100}
89 101
102static inline void __init page_cgroup_init_flatmem(void)
103{
104}
105
90#endif 106#endif
91 107
92#ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP 108#ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 48803064cedf..219b8fb4651d 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -319,4 +319,6 @@ static inline void *kzalloc_node(size_t size, gfp_t flags, int node)
319 return kmalloc_node(size, flags | __GFP_ZERO, node); 319 return kmalloc_node(size, flags | __GFP_ZERO, node);
320} 320}
321 321
322void __init kmem_cache_init_late(void);
323
322#endif /* _LINUX_SLAB_H */ 324#endif /* _LINUX_SLAB_H */
diff --git a/include/linux/slob_def.h b/include/linux/slob_def.h
index 0ec00b39d006..bb5368df4be8 100644
--- a/include/linux/slob_def.h
+++ b/include/linux/slob_def.h
@@ -34,4 +34,9 @@ static __always_inline void *__kmalloc(size_t size, gfp_t flags)
34 return kmalloc(size, flags); 34 return kmalloc(size, flags);
35} 35}
36 36
37static inline void kmem_cache_init_late(void)
38{
39 /* Nothing to do */
40}
41
37#endif /* __LINUX_SLOB_DEF_H */ 42#endif /* __LINUX_SLOB_DEF_H */
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
index be5d40c43bd2..4dcbc2c71491 100644
--- a/include/linux/slub_def.h
+++ b/include/linux/slub_def.h
@@ -302,4 +302,6 @@ static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
302} 302}
303#endif 303#endif
304 304
305void __init kmem_cache_init_late(void);
306
305#endif /* _LINUX_SLUB_DEF_H */ 307#endif /* _LINUX_SLUB_DEF_H */
diff --git a/init/main.c b/init/main.c
index 5616661eac01..f6204f712e7c 100644
--- a/init/main.c
+++ b/init/main.c
@@ -539,6 +539,11 @@ void __init __weak thread_info_cache_init(void)
539 */ 539 */
540static void __init mm_init(void) 540static void __init mm_init(void)
541{ 541{
542 /*
543 * page_cgroup requires countinous pages as memmap
544 * and it's bigger than MAX_ORDER unless SPARSEMEM.
545 */
546 page_cgroup_init_flatmem();
542 mem_init(); 547 mem_init();
543 kmem_cache_init(); 548 kmem_cache_init();
544 vmalloc_init(); 549 vmalloc_init();
@@ -635,6 +640,7 @@ asmlinkage void __init start_kernel(void)
635 "enabled early\n"); 640 "enabled early\n");
636 early_boot_irqs_on(); 641 early_boot_irqs_on();
637 local_irq_enable(); 642 local_irq_enable();
643 kmem_cache_init_late();
638 644
639 /* 645 /*
640 * HACK ALERT! This is early. We're enabling the console before 646 * HACK ALERT! This is early. We're enabling the console before
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 104578541230..065205bdd920 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -45,7 +45,7 @@ void handle_bad_irq(unsigned int irq, struct irq_desc *desc)
45#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS) 45#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS)
46static void __init init_irq_default_affinity(void) 46static void __init init_irq_default_affinity(void)
47{ 47{
48 alloc_bootmem_cpumask_var(&irq_default_affinity); 48 alloc_cpumask_var(&irq_default_affinity, GFP_NOWAIT);
49 cpumask_setall(irq_default_affinity); 49 cpumask_setall(irq_default_affinity);
50} 50}
51#else 51#else
diff --git a/mm/page_cgroup.c b/mm/page_cgroup.c
index 3dd4a909a1de..11a8a10a3909 100644
--- a/mm/page_cgroup.c
+++ b/mm/page_cgroup.c
@@ -47,8 +47,6 @@ static int __init alloc_node_page_cgroup(int nid)
47 struct page_cgroup *base, *pc; 47 struct page_cgroup *base, *pc;
48 unsigned long table_size; 48 unsigned long table_size;
49 unsigned long start_pfn, nr_pages, index; 49 unsigned long start_pfn, nr_pages, index;
50 struct page *page;
51 unsigned int order;
52 50
53 start_pfn = NODE_DATA(nid)->node_start_pfn; 51 start_pfn = NODE_DATA(nid)->node_start_pfn;
54 nr_pages = NODE_DATA(nid)->node_spanned_pages; 52 nr_pages = NODE_DATA(nid)->node_spanned_pages;
@@ -57,13 +55,11 @@ static int __init alloc_node_page_cgroup(int nid)
57 return 0; 55 return 0;
58 56
59 table_size = sizeof(struct page_cgroup) * nr_pages; 57 table_size = sizeof(struct page_cgroup) * nr_pages;
60 order = get_order(table_size); 58
61 page = alloc_pages_node(nid, GFP_NOWAIT | __GFP_ZERO, order); 59 base = __alloc_bootmem_node_nopanic(NODE_DATA(nid),
62 if (!page) 60 table_size, PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
63 page = alloc_pages_node(-1, GFP_NOWAIT | __GFP_ZERO, order); 61 if (!base)
64 if (!page)
65 return -ENOMEM; 62 return -ENOMEM;
66 base = page_address(page);
67 for (index = 0; index < nr_pages; index++) { 63 for (index = 0; index < nr_pages; index++) {
68 pc = base + index; 64 pc = base + index;
69 __init_page_cgroup(pc, start_pfn + index); 65 __init_page_cgroup(pc, start_pfn + index);
@@ -73,7 +69,7 @@ static int __init alloc_node_page_cgroup(int nid)
73 return 0; 69 return 0;
74} 70}
75 71
76void __init page_cgroup_init(void) 72void __init page_cgroup_init_flatmem(void)
77{ 73{
78 74
79 int nid, fail; 75 int nid, fail;
@@ -117,16 +113,11 @@ static int __init_refok init_section_page_cgroup(unsigned long pfn)
117 if (!section->page_cgroup) { 113 if (!section->page_cgroup) {
118 nid = page_to_nid(pfn_to_page(pfn)); 114 nid = page_to_nid(pfn_to_page(pfn));
119 table_size = sizeof(struct page_cgroup) * PAGES_PER_SECTION; 115 table_size = sizeof(struct page_cgroup) * PAGES_PER_SECTION;
120 if (slab_is_available()) { 116 VM_BUG_ON(!slab_is_available());
121 base = kmalloc_node(table_size, 117 base = kmalloc_node(table_size,
122 GFP_KERNEL | __GFP_NOWARN, nid); 118 GFP_KERNEL | __GFP_NOWARN, nid);
123 if (!base) 119 if (!base)
124 base = vmalloc_node(table_size, nid); 120 base = vmalloc_node(table_size, nid);
125 } else {
126 base = __alloc_bootmem_node_nopanic(NODE_DATA(nid),
127 table_size,
128 PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
129 }
130 } else { 121 } else {
131 /* 122 /*
132 * We don't have to allocate page_cgroup again, but 123 * We don't have to allocate page_cgroup again, but
diff --git a/mm/slab.c b/mm/slab.c
index f46b65d124e5..18e3164de09a 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -304,6 +304,12 @@ struct kmem_list3 {
304}; 304};
305 305
306/* 306/*
307 * The slab allocator is initialized with interrupts disabled. Therefore, make
308 * sure early boot allocations don't accidentally enable interrupts.
309 */
310static gfp_t slab_gfp_mask __read_mostly = SLAB_GFP_BOOT_MASK;
311
312/*
307 * Need this for bootstrapping a per node allocator. 313 * Need this for bootstrapping a per node allocator.
308 */ 314 */
309#define NUM_INIT_LISTS (3 * MAX_NUMNODES) 315#define NUM_INIT_LISTS (3 * MAX_NUMNODES)
@@ -753,6 +759,7 @@ static enum {
753 NONE, 759 NONE,
754 PARTIAL_AC, 760 PARTIAL_AC,
755 PARTIAL_L3, 761 PARTIAL_L3,
762 EARLY,
756 FULL 763 FULL
757} g_cpucache_up; 764} g_cpucache_up;
758 765
@@ -761,7 +768,7 @@ static enum {
761 */ 768 */
762int slab_is_available(void) 769int slab_is_available(void)
763{ 770{
764 return g_cpucache_up == FULL; 771 return g_cpucache_up >= EARLY;
765} 772}
766 773
767static DEFINE_PER_CPU(struct delayed_work, reap_work); 774static DEFINE_PER_CPU(struct delayed_work, reap_work);
@@ -1625,19 +1632,27 @@ void __init kmem_cache_init(void)
1625 } 1632 }
1626 } 1633 }
1627 1634
1628 /* 6) resize the head arrays to their final sizes */ 1635 g_cpucache_up = EARLY;
1629 {
1630 struct kmem_cache *cachep;
1631 mutex_lock(&cache_chain_mutex);
1632 list_for_each_entry(cachep, &cache_chain, next)
1633 if (enable_cpucache(cachep, GFP_NOWAIT))
1634 BUG();
1635 mutex_unlock(&cache_chain_mutex);
1636 }
1637 1636
1638 /* Annotate slab for lockdep -- annotate the malloc caches */ 1637 /* Annotate slab for lockdep -- annotate the malloc caches */
1639 init_lock_keys(); 1638 init_lock_keys();
1639}
1640
1641void __init kmem_cache_init_late(void)
1642{
1643 struct kmem_cache *cachep;
1644
1645 /*
1646 * Interrupts are enabled now so all GFP allocations are safe.
1647 */
1648 slab_gfp_mask = __GFP_BITS_MASK;
1640 1649
1650 /* 6) resize the head arrays to their final sizes */
1651 mutex_lock(&cache_chain_mutex);
1652 list_for_each_entry(cachep, &cache_chain, next)
1653 if (enable_cpucache(cachep, GFP_NOWAIT))
1654 BUG();
1655 mutex_unlock(&cache_chain_mutex);
1641 1656
1642 /* Done! */ 1657 /* Done! */
1643 g_cpucache_up = FULL; 1658 g_cpucache_up = FULL;
@@ -2102,7 +2117,7 @@ static int __init_refok setup_cpu_cache(struct kmem_cache *cachep, gfp_t gfp)
2102 for_each_online_node(node) { 2117 for_each_online_node(node) {
2103 cachep->nodelists[node] = 2118 cachep->nodelists[node] =
2104 kmalloc_node(sizeof(struct kmem_list3), 2119 kmalloc_node(sizeof(struct kmem_list3),
2105 GFP_KERNEL, node); 2120 gfp, node);
2106 BUG_ON(!cachep->nodelists[node]); 2121 BUG_ON(!cachep->nodelists[node]);
2107 kmem_list3_init(cachep->nodelists[node]); 2122 kmem_list3_init(cachep->nodelists[node]);
2108 } 2123 }
@@ -3354,6 +3369,8 @@ __cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid,
3354 unsigned long save_flags; 3369 unsigned long save_flags;
3355 void *ptr; 3370 void *ptr;
3356 3371
3372 flags &= slab_gfp_mask;
3373
3357 lockdep_trace_alloc(flags); 3374 lockdep_trace_alloc(flags);
3358 3375
3359 if (slab_should_failslab(cachep, flags)) 3376 if (slab_should_failslab(cachep, flags))
@@ -3434,6 +3451,8 @@ __cache_alloc(struct kmem_cache *cachep, gfp_t flags, void *caller)
3434 unsigned long save_flags; 3451 unsigned long save_flags;
3435 void *objp; 3452 void *objp;
3436 3453
3454 flags &= slab_gfp_mask;
3455
3437 lockdep_trace_alloc(flags); 3456 lockdep_trace_alloc(flags);
3438 3457
3439 if (slab_should_failslab(cachep, flags)) 3458 if (slab_should_failslab(cachep, flags))
diff --git a/mm/slub.c b/mm/slub.c
index 3964d3ce4c15..30354bfeb43d 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -178,6 +178,12 @@ static enum {
178 SYSFS /* Sysfs up */ 178 SYSFS /* Sysfs up */
179} slab_state = DOWN; 179} slab_state = DOWN;
180 180
181/*
182 * The slab allocator is initialized with interrupts disabled. Therefore, make
183 * sure early boot allocations don't accidentally enable interrupts.
184 */
185static gfp_t slab_gfp_mask __read_mostly = SLAB_GFP_BOOT_MASK;
186
181/* A list of all slab caches on the system */ 187/* A list of all slab caches on the system */
182static DECLARE_RWSEM(slub_lock); 188static DECLARE_RWSEM(slub_lock);
183static LIST_HEAD(slab_caches); 189static LIST_HEAD(slab_caches);
@@ -1595,6 +1601,8 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
1595 unsigned long flags; 1601 unsigned long flags;
1596 unsigned int objsize; 1602 unsigned int objsize;
1597 1603
1604 gfpflags &= slab_gfp_mask;
1605
1598 lockdep_trace_alloc(gfpflags); 1606 lockdep_trace_alloc(gfpflags);
1599 might_sleep_if(gfpflags & __GFP_WAIT); 1607 might_sleep_if(gfpflags & __GFP_WAIT);
1600 1608
@@ -3104,6 +3112,14 @@ void __init kmem_cache_init(void)
3104 nr_cpu_ids, nr_node_ids); 3112 nr_cpu_ids, nr_node_ids);
3105} 3113}
3106 3114
3115void __init kmem_cache_init_late(void)
3116{
3117 /*
3118 * Interrupts are enabled now so all GFP allocations are safe.
3119 */
3120 slab_gfp_mask = __GFP_BITS_MASK;
3121}
3122
3107/* 3123/*
3108 * Find a mergeable slab cache 3124 * Find a mergeable slab cache
3109 */ 3125 */