diff options
| -rw-r--r-- | include/linux/slub_def.h | 6 | ||||
| -rw-r--r-- | mm/slub.c | 202 |
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 | */ |
| 71 | struct kmem_cache { | 71 | struct 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 | /* |
| @@ -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 | ||
| 245 | static 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 */ |
| 255 | static inline int check_valid_pointer(struct kmem_cache *s, | 246 | static 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) | |||
| 1422 | static void unfreeze_slab(struct kmem_cache *s, struct page *page, int tail) | 1413 | static 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 | */ |
| 1508 | static inline void __flush_cpu_slab(struct kmem_cache *s, int cpu) | 1499 | static 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 | 2089 | static 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 | |||
| 2116 | static DEFINE_PER_CPU(struct kmem_cache_cpu [NR_KMEM_CACHE_CPU], | ||
| 2117 | kmem_cache_cpu); | ||
| 2118 | |||
| 2119 | static DEFINE_PER_CPU(struct kmem_cache_cpu *, kmem_cache_cpu_free); | ||
| 2120 | static DECLARE_BITMAP(kmem_cach_cpu_free_init_once, CONFIG_NR_CPUS); | ||
| 2121 | |||
| 2122 | static 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) | ||
