forked from mirrors/linux
		
	mm, sl[aou]b: Move kmem_cache_create mutex handling to common code
Move the mutex handling into the common kmem_cache_create() function. Then we can also move more checks out of SLAB's kmem_cache_create() into the common code. Reviewed-by: Glauber Costa <glommer@parallels.com> Signed-off-by: Christoph Lameter <cl@linux.com> Signed-off-by: Pekka Enberg <penberg@kernel.org>
This commit is contained in:
		
							parent
							
								
									18004c5d40
								
							
						
					
					
						commit
						20cea9683e
					
				
					 3 changed files with 54 additions and 67 deletions
				
			
		
							
								
								
									
										52
									
								
								mm/slab.c
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								mm/slab.c
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -2228,55 +2228,10 @@ __kmem_cache_create (const char *name, size_t size, size_t align,
 | 
			
		|||
	unsigned long flags, void (*ctor)(void *))
 | 
			
		||||
{
 | 
			
		||||
	size_t left_over, slab_size, ralign;
 | 
			
		||||
	struct kmem_cache *cachep = NULL, *pc;
 | 
			
		||||
	struct kmem_cache *cachep = NULL;
 | 
			
		||||
	gfp_t gfp;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Sanity checks... these are all serious usage bugs.
 | 
			
		||||
	 */
 | 
			
		||||
	if (!name || in_interrupt() || (size < BYTES_PER_WORD) ||
 | 
			
		||||
	    size > KMALLOC_MAX_SIZE) {
 | 
			
		||||
		printk(KERN_ERR "%s: Early error in slab %s\n", __func__,
 | 
			
		||||
				name);
 | 
			
		||||
		BUG();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * We use cache_chain_mutex to ensure a consistent view of
 | 
			
		||||
	 * cpu_online_mask as well.  Please see cpuup_callback
 | 
			
		||||
	 */
 | 
			
		||||
	if (slab_is_available()) {
 | 
			
		||||
		get_online_cpus();
 | 
			
		||||
		mutex_lock(&slab_mutex);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	list_for_each_entry(pc, &slab_caches, list) {
 | 
			
		||||
		char tmp;
 | 
			
		||||
		int res;
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * This happens when the module gets unloaded and doesn't
 | 
			
		||||
		 * destroy its slab cache and no-one else reuses the vmalloc
 | 
			
		||||
		 * area of the module.  Print a warning.
 | 
			
		||||
		 */
 | 
			
		||||
		res = probe_kernel_address(pc->name, tmp);
 | 
			
		||||
		if (res) {
 | 
			
		||||
			printk(KERN_ERR
 | 
			
		||||
			       "SLAB: cache with size %d has lost its name\n",
 | 
			
		||||
			       pc->size);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!strcmp(pc->name, name)) {
 | 
			
		||||
			printk(KERN_ERR
 | 
			
		||||
			       "kmem_cache_create: duplicate cache %s\n", name);
 | 
			
		||||
			dump_stack();
 | 
			
		||||
			goto oops;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#if DEBUG
 | 
			
		||||
	WARN_ON(strchr(name, ' '));	/* It confuses parsers */
 | 
			
		||||
#if FORCED_DEBUG
 | 
			
		||||
	/*
 | 
			
		||||
	 * Enable redzoning and last user accounting, except for caches with
 | 
			
		||||
| 
						 | 
				
			
			@ -2495,11 +2450,6 @@ __kmem_cache_create (const char *name, size_t size, size_t align,
 | 
			
		|||
 | 
			
		||||
	/* cache setup completed, link it into the list */
 | 
			
		||||
	list_add(&cachep->list, &slab_caches);
 | 
			
		||||
oops:
 | 
			
		||||
	if (slab_is_available()) {
 | 
			
		||||
		mutex_unlock(&slab_mutex);
 | 
			
		||||
		put_online_cpus();
 | 
			
		||||
	}
 | 
			
		||||
	return cachep;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,7 +11,8 @@
 | 
			
		|||
#include <linux/memory.h>
 | 
			
		||||
#include <linux/compiler.h>
 | 
			
		||||
#include <linux/module.h>
 | 
			
		||||
 | 
			
		||||
#include <linux/cpu.h>
 | 
			
		||||
#include <linux/uaccess.h>
 | 
			
		||||
#include <asm/cacheflush.h>
 | 
			
		||||
#include <asm/tlbflush.h>
 | 
			
		||||
#include <asm/page.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -61,8 +62,46 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size, size_t align
 | 
			
		|||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	get_online_cpus();
 | 
			
		||||
	mutex_lock(&slab_mutex);
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_DEBUG_VM
 | 
			
		||||
	list_for_each_entry(s, &slab_caches, list) {
 | 
			
		||||
		char tmp;
 | 
			
		||||
		int res;
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * This happens when the module gets unloaded and doesn't
 | 
			
		||||
		 * destroy its slab cache and no-one else reuses the vmalloc
 | 
			
		||||
		 * area of the module.  Print a warning.
 | 
			
		||||
		 */
 | 
			
		||||
		res = probe_kernel_address(s->name, tmp);
 | 
			
		||||
		if (res) {
 | 
			
		||||
			printk(KERN_ERR
 | 
			
		||||
			       "Slab cache with size %d has lost its name\n",
 | 
			
		||||
			       s->object_size);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!strcmp(s->name, name)) {
 | 
			
		||||
			printk(KERN_ERR "kmem_cache_create(%s): Cache name"
 | 
			
		||||
				" already exists.\n",
 | 
			
		||||
				name);
 | 
			
		||||
			dump_stack();
 | 
			
		||||
			s = NULL;
 | 
			
		||||
			goto oops;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	WARN_ON(strchr(name, ' '));	/* It confuses parsers */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	s = __kmem_cache_create(name, size, align, flags, ctor);
 | 
			
		||||
 | 
			
		||||
oops:
 | 
			
		||||
	mutex_unlock(&slab_mutex);
 | 
			
		||||
	put_online_cpus();
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_DEBUG_VM
 | 
			
		||||
out:
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										28
									
								
								mm/slub.c
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								mm/slub.c
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -3911,7 +3911,6 @@ struct kmem_cache *__kmem_cache_create(const char *name, size_t size,
 | 
			
		|||
	struct kmem_cache *s;
 | 
			
		||||
	char *n;
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&slab_mutex);
 | 
			
		||||
	s = find_mergeable(size, align, flags, name, ctor);
 | 
			
		||||
	if (s) {
 | 
			
		||||
		s->refcount++;
 | 
			
		||||
| 
						 | 
				
			
			@ -3924,37 +3923,36 @@ struct kmem_cache *__kmem_cache_create(const char *name, size_t size,
 | 
			
		|||
 | 
			
		||||
		if (sysfs_slab_alias(s, name)) {
 | 
			
		||||
			s->refcount--;
 | 
			
		||||
			goto err;
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
		mutex_unlock(&slab_mutex);
 | 
			
		||||
		return s;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	n = kstrdup(name, GFP_KERNEL);
 | 
			
		||||
	if (!n)
 | 
			
		||||
		goto err;
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	s = kmalloc(kmem_size, GFP_KERNEL);
 | 
			
		||||
	if (s) {
 | 
			
		||||
		if (kmem_cache_open(s, n,
 | 
			
		||||
				size, align, flags, ctor)) {
 | 
			
		||||
			int r;
 | 
			
		||||
 | 
			
		||||
			list_add(&s->list, &slab_caches);
 | 
			
		||||
			mutex_unlock(&slab_mutex);
 | 
			
		||||
			if (sysfs_slab_add(s)) {
 | 
			
		||||
				mutex_lock(&slab_mutex);
 | 
			
		||||
				list_del(&s->list);
 | 
			
		||||
				kfree(n);
 | 
			
		||||
				kfree(s);
 | 
			
		||||
				goto err;
 | 
			
		||||
			}
 | 
			
		||||
			return s;
 | 
			
		||||
			r = sysfs_slab_add(s);
 | 
			
		||||
			mutex_lock(&slab_mutex);
 | 
			
		||||
 | 
			
		||||
			if (!r)
 | 
			
		||||
				return s;
 | 
			
		||||
 | 
			
		||||
			list_del(&s->list);
 | 
			
		||||
			kmem_cache_close(s);
 | 
			
		||||
		}
 | 
			
		||||
		kfree(s);
 | 
			
		||||
	}
 | 
			
		||||
	kfree(n);
 | 
			
		||||
err:
 | 
			
		||||
	mutex_unlock(&slab_mutex);
 | 
			
		||||
	return s;
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_SMP
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue