diff options
author | Pekka Enberg <penberg@kernel.org> | 2012-10-03 02:56:37 -0400 |
---|---|---|
committer | Pekka Enberg <penberg@kernel.org> | 2012-10-03 02:56:37 -0400 |
commit | f4178cdddd4cb860a17f363fe13264fff03da7f2 (patch) | |
tree | 5ca8dc6bb09bcb2c4b959b60712d7a3f60c7a43f /mm/slab_common.c | |
parent | 023dc70470502f41b285112d4840f35d9075b767 (diff) | |
parent | f28510d30c7f03daa290019fbc57ad8277347614 (diff) |
Merge branch 'slab/common-for-cgroups' into slab/for-linus
Fix up a trivial conflict with NUMA_NO_NODE cleanups.
Conflicts:
mm/slob.c
Signed-off-by: Pekka Enberg <penberg@kernel.org>
Diffstat (limited to 'mm/slab_common.c')
-rw-r--r-- | mm/slab_common.c | 80 |
1 files changed, 76 insertions, 4 deletions
diff --git a/mm/slab_common.c b/mm/slab_common.c index 8cf8b4962d6c..9c217255ac49 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c | |||
@@ -22,6 +22,7 @@ | |||
22 | enum slab_state slab_state; | 22 | enum slab_state slab_state; |
23 | LIST_HEAD(slab_caches); | 23 | LIST_HEAD(slab_caches); |
24 | DEFINE_MUTEX(slab_mutex); | 24 | DEFINE_MUTEX(slab_mutex); |
25 | struct kmem_cache *kmem_cache; | ||
25 | 26 | ||
26 | #ifdef CONFIG_DEBUG_VM | 27 | #ifdef CONFIG_DEBUG_VM |
27 | static int kmem_cache_sanity_check(const char *name, size_t size) | 28 | static int kmem_cache_sanity_check(const char *name, size_t size) |
@@ -98,21 +99,92 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size, size_t align | |||
98 | unsigned long flags, void (*ctor)(void *)) | 99 | unsigned long flags, void (*ctor)(void *)) |
99 | { | 100 | { |
100 | struct kmem_cache *s = NULL; | 101 | struct kmem_cache *s = NULL; |
102 | int err = 0; | ||
101 | 103 | ||
102 | get_online_cpus(); | 104 | get_online_cpus(); |
103 | mutex_lock(&slab_mutex); | 105 | mutex_lock(&slab_mutex); |
104 | if (kmem_cache_sanity_check(name, size) == 0) | 106 | |
105 | s = __kmem_cache_create(name, size, align, flags, ctor); | 107 | if (!kmem_cache_sanity_check(name, size) == 0) |
108 | goto out_locked; | ||
109 | |||
110 | |||
111 | s = __kmem_cache_alias(name, size, align, flags, ctor); | ||
112 | if (s) | ||
113 | goto out_locked; | ||
114 | |||
115 | s = kmem_cache_zalloc(kmem_cache, GFP_KERNEL); | ||
116 | if (s) { | ||
117 | s->object_size = s->size = size; | ||
118 | s->align = align; | ||
119 | s->ctor = ctor; | ||
120 | s->name = kstrdup(name, GFP_KERNEL); | ||
121 | if (!s->name) { | ||
122 | kmem_cache_free(kmem_cache, s); | ||
123 | err = -ENOMEM; | ||
124 | goto out_locked; | ||
125 | } | ||
126 | |||
127 | err = __kmem_cache_create(s, flags); | ||
128 | if (!err) { | ||
129 | |||
130 | s->refcount = 1; | ||
131 | list_add(&s->list, &slab_caches); | ||
132 | |||
133 | } else { | ||
134 | kfree(s->name); | ||
135 | kmem_cache_free(kmem_cache, s); | ||
136 | } | ||
137 | } else | ||
138 | err = -ENOMEM; | ||
139 | |||
140 | out_locked: | ||
106 | mutex_unlock(&slab_mutex); | 141 | mutex_unlock(&slab_mutex); |
107 | put_online_cpus(); | 142 | put_online_cpus(); |
108 | 143 | ||
109 | if (!s && (flags & SLAB_PANIC)) | 144 | if (err) { |
110 | panic("kmem_cache_create: Failed to create slab '%s'\n", name); | 145 | |
146 | if (flags & SLAB_PANIC) | ||
147 | panic("kmem_cache_create: Failed to create slab '%s'. Error %d\n", | ||
148 | name, err); | ||
149 | else { | ||
150 | printk(KERN_WARNING "kmem_cache_create(%s) failed with error %d", | ||
151 | name, err); | ||
152 | dump_stack(); | ||
153 | } | ||
154 | |||
155 | return NULL; | ||
156 | } | ||
111 | 157 | ||
112 | return s; | 158 | return s; |
113 | } | 159 | } |
114 | EXPORT_SYMBOL(kmem_cache_create); | 160 | EXPORT_SYMBOL(kmem_cache_create); |
115 | 161 | ||
162 | void kmem_cache_destroy(struct kmem_cache *s) | ||
163 | { | ||
164 | get_online_cpus(); | ||
165 | mutex_lock(&slab_mutex); | ||
166 | s->refcount--; | ||
167 | if (!s->refcount) { | ||
168 | list_del(&s->list); | ||
169 | |||
170 | if (!__kmem_cache_shutdown(s)) { | ||
171 | if (s->flags & SLAB_DESTROY_BY_RCU) | ||
172 | rcu_barrier(); | ||
173 | |||
174 | kfree(s->name); | ||
175 | kmem_cache_free(kmem_cache, s); | ||
176 | } else { | ||
177 | list_add(&s->list, &slab_caches); | ||
178 | printk(KERN_ERR "kmem_cache_destroy %s: Slab cache still has objects\n", | ||
179 | s->name); | ||
180 | dump_stack(); | ||
181 | } | ||
182 | } | ||
183 | mutex_unlock(&slab_mutex); | ||
184 | put_online_cpus(); | ||
185 | } | ||
186 | EXPORT_SYMBOL(kmem_cache_destroy); | ||
187 | |||
116 | int slab_is_available(void) | 188 | int slab_is_available(void) |
117 | { | 189 | { |
118 | return slab_state >= UP; | 190 | return slab_state >= UP; |