mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	slab: make kmem_cache_create() work with 32-bit sizes
struct kmem_cache::size and ::align were always 32-bit. Out of curiosity I created 4GB kmem_cache, it oopsed with division by 0. kmem_cache_create(1UL<<32+1) created 1-byte cache as expected. size_t doesn't work and never did. Link: http://lkml.kernel.org/r/20180305200730.15812-6-adobriyan@gmail.com Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Cc: Christoph Lameter <cl@linux.com> Cc: Pekka Enberg <penberg@kernel.org> Cc: David Rientjes <rientjes@google.com> Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
		
							parent
							
								
									361d575e5c
								
							
						
					
					
						commit
						f4957d5bd0
					
				
					 5 changed files with 19 additions and 17 deletions
				
			
		| 
						 | 
				
			
			@ -137,11 +137,12 @@ bool slab_is_available(void);
 | 
			
		|||
 | 
			
		||||
extern bool usercopy_fallback;
 | 
			
		||||
 | 
			
		||||
struct kmem_cache *kmem_cache_create(const char *name, size_t size,
 | 
			
		||||
			size_t align, slab_flags_t flags,
 | 
			
		||||
struct kmem_cache *kmem_cache_create(const char *name, unsigned int size,
 | 
			
		||||
			unsigned int align, slab_flags_t flags,
 | 
			
		||||
			void (*ctor)(void *));
 | 
			
		||||
struct kmem_cache *kmem_cache_create_usercopy(const char *name,
 | 
			
		||||
			size_t size, size_t align, slab_flags_t flags,
 | 
			
		||||
			unsigned int size, unsigned int align,
 | 
			
		||||
			slab_flags_t flags,
 | 
			
		||||
			size_t useroffset, size_t usersize,
 | 
			
		||||
			void (*ctor)(void *));
 | 
			
		||||
void kmem_cache_destroy(struct kmem_cache *);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1877,7 +1877,7 @@ slab_flags_t kmem_cache_flags(unsigned long object_size,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
struct kmem_cache *
 | 
			
		||||
__kmem_cache_alias(const char *name, size_t size, size_t align,
 | 
			
		||||
__kmem_cache_alias(const char *name, unsigned int size, unsigned int align,
 | 
			
		||||
		   slab_flags_t flags, void (*ctor)(void *))
 | 
			
		||||
{
 | 
			
		||||
	struct kmem_cache *cachep;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -101,11 +101,11 @@ extern void create_boot_cache(struct kmem_cache *, const char *name,
 | 
			
		|||
			unsigned int useroffset, unsigned int usersize);
 | 
			
		||||
 | 
			
		||||
int slab_unmergeable(struct kmem_cache *s);
 | 
			
		||||
struct kmem_cache *find_mergeable(size_t size, size_t align,
 | 
			
		||||
struct kmem_cache *find_mergeable(unsigned size, unsigned align,
 | 
			
		||||
		slab_flags_t flags, const char *name, void (*ctor)(void *));
 | 
			
		||||
#ifndef CONFIG_SLOB
 | 
			
		||||
struct kmem_cache *
 | 
			
		||||
__kmem_cache_alias(const char *name, size_t size, size_t align,
 | 
			
		||||
__kmem_cache_alias(const char *name, unsigned int size, unsigned int align,
 | 
			
		||||
		   slab_flags_t flags, void (*ctor)(void *));
 | 
			
		||||
 | 
			
		||||
slab_flags_t kmem_cache_flags(unsigned long object_size,
 | 
			
		||||
| 
						 | 
				
			
			@ -113,7 +113,7 @@ slab_flags_t kmem_cache_flags(unsigned long object_size,
 | 
			
		|||
	void (*ctor)(void *));
 | 
			
		||||
#else
 | 
			
		||||
static inline struct kmem_cache *
 | 
			
		||||
__kmem_cache_alias(const char *name, size_t size, size_t align,
 | 
			
		||||
__kmem_cache_alias(const char *name, unsigned int size, unsigned int align,
 | 
			
		||||
		   slab_flags_t flags, void (*ctor)(void *))
 | 
			
		||||
{ return NULL; }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,7 +82,7 @@ unsigned int kmem_cache_size(struct kmem_cache *s)
 | 
			
		|||
EXPORT_SYMBOL(kmem_cache_size);
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_DEBUG_VM
 | 
			
		||||
static int kmem_cache_sanity_check(const char *name, size_t size)
 | 
			
		||||
static int kmem_cache_sanity_check(const char *name, unsigned int size)
 | 
			
		||||
{
 | 
			
		||||
	struct kmem_cache *s = NULL;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -113,7 +113,7 @@ static int kmem_cache_sanity_check(const char *name, size_t size)
 | 
			
		|||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
static inline int kmem_cache_sanity_check(const char *name, size_t size)
 | 
			
		||||
static inline int kmem_cache_sanity_check(const char *name, unsigned int size)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -280,8 +280,8 @@ static inline void memcg_unlink_cache(struct kmem_cache *s)
 | 
			
		|||
 * Figure out what the alignment of the objects will be given a set of
 | 
			
		||||
 * flags, a user specified alignment and the size of the objects.
 | 
			
		||||
 */
 | 
			
		||||
static unsigned long calculate_alignment(slab_flags_t flags,
 | 
			
		||||
		unsigned long align, unsigned long size)
 | 
			
		||||
static unsigned int calculate_alignment(slab_flags_t flags,
 | 
			
		||||
		unsigned int align, unsigned int size)
 | 
			
		||||
{
 | 
			
		||||
	/*
 | 
			
		||||
	 * If the user wants hardware cache aligned objects then follow that
 | 
			
		||||
| 
						 | 
				
			
			@ -291,7 +291,7 @@ static unsigned long calculate_alignment(slab_flags_t flags,
 | 
			
		|||
	 * alignment though. If that is greater then use it.
 | 
			
		||||
	 */
 | 
			
		||||
	if (flags & SLAB_HWCACHE_ALIGN) {
 | 
			
		||||
		unsigned long ralign;
 | 
			
		||||
		unsigned int ralign;
 | 
			
		||||
 | 
			
		||||
		ralign = cache_line_size();
 | 
			
		||||
		while (size <= ralign / 2)
 | 
			
		||||
| 
						 | 
				
			
			@ -331,7 +331,7 @@ int slab_unmergeable(struct kmem_cache *s)
 | 
			
		|||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct kmem_cache *find_mergeable(size_t size, size_t align,
 | 
			
		||||
struct kmem_cache *find_mergeable(unsigned int size, unsigned int align,
 | 
			
		||||
		slab_flags_t flags, const char *name, void (*ctor)(void *))
 | 
			
		||||
{
 | 
			
		||||
	struct kmem_cache *s;
 | 
			
		||||
| 
						 | 
				
			
			@ -379,7 +379,7 @@ struct kmem_cache *find_mergeable(size_t size, size_t align,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static struct kmem_cache *create_cache(const char *name,
 | 
			
		||||
		size_t object_size, size_t size, size_t align,
 | 
			
		||||
		unsigned int object_size, unsigned int size, unsigned int align,
 | 
			
		||||
		slab_flags_t flags, size_t useroffset,
 | 
			
		||||
		size_t usersize, void (*ctor)(void *),
 | 
			
		||||
		struct mem_cgroup *memcg, struct kmem_cache *root_cache)
 | 
			
		||||
| 
						 | 
				
			
			@ -452,7 +452,8 @@ static struct kmem_cache *create_cache(const char *name,
 | 
			
		|||
 * as davem.
 | 
			
		||||
 */
 | 
			
		||||
struct kmem_cache *
 | 
			
		||||
kmem_cache_create_usercopy(const char *name, size_t size, size_t align,
 | 
			
		||||
kmem_cache_create_usercopy(const char *name,
 | 
			
		||||
		  unsigned int size, unsigned int align,
 | 
			
		||||
		  slab_flags_t flags, size_t useroffset, size_t usersize,
 | 
			
		||||
		  void (*ctor)(void *))
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -532,7 +533,7 @@ kmem_cache_create_usercopy(const char *name, size_t size, size_t align,
 | 
			
		|||
EXPORT_SYMBOL(kmem_cache_create_usercopy);
 | 
			
		||||
 | 
			
		||||
struct kmem_cache *
 | 
			
		||||
kmem_cache_create(const char *name, size_t size, size_t align,
 | 
			
		||||
kmem_cache_create(const char *name, unsigned int size, unsigned int align,
 | 
			
		||||
		slab_flags_t flags, void (*ctor)(void *))
 | 
			
		||||
{
 | 
			
		||||
	return kmem_cache_create_usercopy(name, size, align, flags, 0, 0,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4242,7 +4242,7 @@ void __init kmem_cache_init_late(void)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
struct kmem_cache *
 | 
			
		||||
__kmem_cache_alias(const char *name, size_t size, size_t align,
 | 
			
		||||
__kmem_cache_alias(const char *name, unsigned int size, unsigned int align,
 | 
			
		||||
		   slab_flags_t flags, void (*ctor)(void *))
 | 
			
		||||
{
 | 
			
		||||
	struct kmem_cache *s, *c;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue