aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/slub_def.h6
-rw-r--r--mm/slub.c202
2 files changed, 49 insertions, 159 deletions
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
index 1e14beb23f9b..17ebe0f89bf3 100644
--- a/include/linux/slub_def.h
+++ b/include/linux/slub_def.h
@@ -69,6 +69,7 @@ struct kmem_cache_order_objects {
69 * Slab cache management. 69 * Slab cache management.
70 */ 70 */
71struct kmem_cache { 71struct kmem_cache {
72 struct kmem_cache_cpu *cpu_slab;
72 /* Used for retriving partial slabs etc */ 73 /* Used for retriving partial slabs etc */
73 unsigned long flags; 74 unsigned long flags;
74 int size; /* The size of an object including meta data */ 75 int size; /* The size of an object including meta data */
@@ -104,11 +105,6 @@ struct kmem_cache {
104 int remote_node_defrag_ratio; 105 int remote_node_defrag_ratio;
105 struct kmem_cache_node *node[MAX_NUMNODES]; 106 struct kmem_cache_node *node[MAX_NUMNODES];
106#endif 107#endif
107#ifdef CONFIG_SMP
108 struct kmem_cache_cpu *cpu_slab[NR_CPUS];
109#else
110 struct kmem_cache_cpu cpu_slab;
111#endif
112}; 108};
113 109
114/* 110/*
diff --git a/mm/slub.c b/mm/slub.c
index 8d71aaf888d7..d6c9ecf629d5 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -242,15 +242,6 @@ static inline struct kmem_cache_node *get_node(struct kmem_cache *s, int node)
242#endif 242#endif
243} 243}
244 244
245static inline struct kmem_cache_cpu *get_cpu_slab(struct kmem_cache *s, int cpu)
246{
247#ifdef CONFIG_SMP
248 return s->cpu_slab[cpu];
249#else
250 return &s->cpu_slab;
251#endif
252}
253
254/* Verify that a pointer has an address that is valid within a slab page */ 245/* Verify that a pointer has an address that is valid within a slab page */
255static inline int check_valid_pointer(struct kmem_cache *s, 246static inline int check_valid_pointer(struct kmem_cache *s,
256 struct page *page, const void *object) 247 struct page *page, const void *object)
@@ -1124,7 +1115,7 @@ static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node)
1124 if (!page) 1115 if (!page)
1125 return NULL; 1116 return NULL;
1126 1117
1127 stat(get_cpu_slab(s, raw_smp_processor_id()), ORDER_FALLBACK); 1118 stat(this_cpu_ptr(s->cpu_slab), ORDER_FALLBACK);
1128 } 1119 }
1129 1120
1130 if (kmemcheck_enabled 1121 if (kmemcheck_enabled
@@ -1422,7 +1413,7 @@ static struct page *get_partial(struct kmem_cache *s, gfp_t flags, int node)
1422static void unfreeze_slab(struct kmem_cache *s, struct page *page, int tail) 1413static void unfreeze_slab(struct kmem_cache *s, struct page *page, int tail)
1423{ 1414{
1424 struct kmem_cache_node *n = get_node(s, page_to_nid(page)); 1415 struct kmem_cache_node *n = get_node(s, page_to_nid(page));
1425 struct kmem_cache_cpu *c = get_cpu_slab(s, smp_processor_id()); 1416 struct kmem_cache_cpu *c = this_cpu_ptr(s->cpu_slab);
1426 1417
1427 __ClearPageSlubFrozen(page); 1418 __ClearPageSlubFrozen(page);
1428 if (page->inuse) { 1419 if (page->inuse) {
@@ -1454,7 +1445,7 @@ static void unfreeze_slab(struct kmem_cache *s, struct page *page, int tail)
1454 slab_unlock(page); 1445 slab_unlock(page);
1455 } else { 1446 } else {
1456 slab_unlock(page); 1447 slab_unlock(page);
1457 stat(get_cpu_slab(s, raw_smp_processor_id()), FREE_SLAB); 1448 stat(__this_cpu_ptr(s->cpu_slab), FREE_SLAB);
1458 discard_slab(s, page); 1449 discard_slab(s, page);
1459 } 1450 }
1460 } 1451 }
@@ -1507,7 +1498,7 @@ static inline void flush_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
1507 */ 1498 */
1508static inline void __flush_cpu_slab(struct kmem_cache *s, int cpu) 1499static inline void __flush_cpu_slab(struct kmem_cache *s, int cpu)
1509{ 1500{
1510 struct kmem_cache_cpu *c = get_cpu_slab(s, cpu); 1501 struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab, cpu);
1511 1502
1512 if (likely(c && c->page)) 1503 if (likely(c && c->page))
1513 flush_slab(s, c); 1504 flush_slab(s, c);
@@ -1673,7 +1664,7 @@ new_slab:
1673 local_irq_disable(); 1664 local_irq_disable();
1674 1665
1675 if (new) { 1666 if (new) {
1676 c = get_cpu_slab(s, smp_processor_id()); 1667 c = __this_cpu_ptr(s->cpu_slab);
1677 stat(c, ALLOC_SLAB); 1668 stat(c, ALLOC_SLAB);
1678 if (c->page) 1669 if (c->page)
1679 flush_slab(s, c); 1670 flush_slab(s, c);
@@ -1711,7 +1702,7 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
1711 void **object; 1702 void **object;
1712 struct kmem_cache_cpu *c; 1703 struct kmem_cache_cpu *c;
1713 unsigned long flags; 1704 unsigned long flags;
1714 unsigned int objsize; 1705 unsigned long objsize;
1715 1706
1716 gfpflags &= gfp_allowed_mask; 1707 gfpflags &= gfp_allowed_mask;
1717 1708
@@ -1722,14 +1713,14 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
1722 return NULL; 1713 return NULL;
1723 1714
1724 local_irq_save(flags); 1715 local_irq_save(flags);
1725 c = get_cpu_slab(s, smp_processor_id()); 1716 c = __this_cpu_ptr(s->cpu_slab);
1717 object = c->freelist;
1726 objsize = c->objsize; 1718 objsize = c->objsize;
1727 if (unlikely(!c->freelist || !node_match(c, node))) 1719 if (unlikely(!object || !node_match(c, node)))
1728 1720
1729 object = __slab_alloc(s, gfpflags, node, addr, c); 1721 object = __slab_alloc(s, gfpflags, node, addr, c);
1730 1722
1731 else { 1723 else {
1732 object = c->freelist;
1733 c->freelist = object[c->offset]; 1724 c->freelist = object[c->offset];
1734 stat(c, ALLOC_FASTPATH); 1725 stat(c, ALLOC_FASTPATH);
1735 } 1726 }
@@ -1800,7 +1791,7 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
1800 void **object = (void *)x; 1791 void **object = (void *)x;
1801 struct kmem_cache_cpu *c; 1792 struct kmem_cache_cpu *c;
1802 1793
1803 c = get_cpu_slab(s, raw_smp_processor_id()); 1794 c = __this_cpu_ptr(s->cpu_slab);
1804 stat(c, FREE_SLOWPATH); 1795 stat(c, FREE_SLOWPATH);
1805 slab_lock(page); 1796 slab_lock(page);
1806 1797
@@ -1872,7 +1863,7 @@ static __always_inline void slab_free(struct kmem_cache *s,
1872 1863
1873 kmemleak_free_recursive(x, s->flags); 1864 kmemleak_free_recursive(x, s->flags);
1874 local_irq_save(flags); 1865 local_irq_save(flags);
1875 c = get_cpu_slab(s, smp_processor_id()); 1866 c = __this_cpu_ptr(s->cpu_slab);
1876 kmemcheck_slab_free(s, object, c->objsize); 1867 kmemcheck_slab_free(s, object, c->objsize);
1877 debug_check_no_locks_freed(object, c->objsize); 1868 debug_check_no_locks_freed(object, c->objsize);
1878 if (!(s->flags & SLAB_DEBUG_OBJECTS)) 1869 if (!(s->flags & SLAB_DEBUG_OBJECTS))
@@ -2095,130 +2086,28 @@ init_kmem_cache_node(struct kmem_cache_node *n, struct kmem_cache *s)
2095#endif 2086#endif
2096} 2087}
2097 2088
2098#ifdef CONFIG_SMP 2089static DEFINE_PER_CPU(struct kmem_cache_cpu, kmalloc_percpu[SLUB_PAGE_SHIFT]);
2099/*
2100 * Per cpu array for per cpu structures.
2101 *
2102 * The per cpu array places all kmem_cache_cpu structures from one processor
2103 * close together meaning that it becomes possible that multiple per cpu
2104 * structures are contained in one cacheline. This may be particularly
2105 * beneficial for the kmalloc caches.
2106 *
2107 * A desktop system typically has around 60-80 slabs. With 100 here we are
2108 * likely able to get per cpu structures for all caches from the array defined
2109 * here. We must be able to cover all kmalloc caches during bootstrap.
2110 *
2111 * If the per cpu array is exhausted then fall back to kmalloc
2112 * of individual cachelines. No sharing is possible then.
2113 */
2114#define NR_KMEM_CACHE_CPU 100
2115
2116static DEFINE_PER_CPU(struct kmem_cache_cpu [NR_KMEM_CACHE_CPU],
2117 kmem_cache_cpu);
2118
2119static DEFINE_PER_CPU(struct kmem_cache_cpu *, kmem_cache_cpu_free);
2120static DECLARE_BITMAP(kmem_cach_cpu_free_init_once, CONFIG_NR_CPUS);
2121
2122static struct kmem_cache_cpu *alloc_kmem_cache_cpu(struct kmem_cache *s,
2123 int cpu, gfp_t flags)
2124{
2125 struct kmem_cache_cpu *c = per_cpu(kmem_cache_cpu_free, cpu);
2126
2127 if (c)
2128 per_cpu(kmem_cache_cpu_free, cpu) =
2129 (void *)c->freelist;
2130 else {
2131 /* Table overflow: So allocate ourselves */
2132 c = kmalloc_node(
2133 ALIGN(sizeof(struct kmem_cache_cpu), cache_line_size()),
2134 flags, cpu_to_node(cpu));
2135 if (!c)