Skip to content

Commit 4590685

Browse files
Christoph Lameterpenberg
authored andcommitted
mm/sl[aou]b: Common alignment code
Extract the code to do object alignment from the allocators. Do the alignment calculations in slab_common so that the __kmem_cache_create functions of the allocators do not have to deal with alignment. Signed-off-by: Christoph Lameter <cl@linux.com> Signed-off-by: Pekka Enberg <penberg@kernel.org>
1 parent 2f9baa9 commit 4590685

File tree

5 files changed

+34
-69
lines changed

5 files changed

+34
-69
lines changed

mm/slab.c

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2337,22 +2337,6 @@ __kmem_cache_create (struct kmem_cache *cachep, unsigned long flags)
23372337
size &= ~(BYTES_PER_WORD - 1);
23382338
}
23392339

2340-
/* calculate the final buffer alignment: */
2341-
2342-
/* 1) arch recommendation: can be overridden for debug */
2343-
if (flags & SLAB_HWCACHE_ALIGN) {
2344-
/*
2345-
* Default alignment: as specified by the arch code. Except if
2346-
* an object is really small, then squeeze multiple objects into
2347-
* one cacheline.
2348-
*/
2349-
ralign = cache_line_size();
2350-
while (size <= ralign / 2)
2351-
ralign /= 2;
2352-
} else {
2353-
ralign = BYTES_PER_WORD;
2354-
}
2355-
23562340
/*
23572341
* Redzoning and user store require word alignment or possibly larger.
23582342
* Note this will be overridden by architecture or caller mandated
@@ -2369,10 +2353,6 @@ __kmem_cache_create (struct kmem_cache *cachep, unsigned long flags)
23692353
size &= ~(REDZONE_ALIGN - 1);
23702354
}
23712355

2372-
/* 2) arch mandated alignment */
2373-
if (ralign < ARCH_SLAB_MINALIGN) {
2374-
ralign = ARCH_SLAB_MINALIGN;
2375-
}
23762356
/* 3) caller mandated alignment */
23772357
if (ralign < cachep->align) {
23782358
ralign = cachep->align;

mm/slab.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ extern struct list_head slab_caches;
3232
/* The slab cache that manages slab cache information */
3333
extern struct kmem_cache *kmem_cache;
3434

35+
unsigned long calculate_alignment(unsigned long flags,
36+
unsigned long align, unsigned long size);
37+
3538
/* Functions provided by the slab allocators */
3639
extern int __kmem_cache_create(struct kmem_cache *, unsigned long flags);
3740

mm/slab_common.c

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,34 @@ static inline int kmem_cache_sanity_check(const char *name, size_t size)
7272
}
7373
#endif
7474

75+
/*
76+
* Figure out what the alignment of the objects will be given a set of
77+
* flags, a user specified alignment and the size of the objects.
78+
*/
79+
unsigned long calculate_alignment(unsigned long flags,
80+
unsigned long align, unsigned long size)
81+
{
82+
/*
83+
* If the user wants hardware cache aligned objects then follow that
84+
* suggestion if the object is sufficiently large.
85+
*
86+
* The hardware cache alignment cannot override the specified
87+
* alignment though. If that is greater then use it.
88+
*/
89+
if (flags & SLAB_HWCACHE_ALIGN) {
90+
unsigned long ralign = cache_line_size();
91+
while (size <= ralign / 2)
92+
ralign /= 2;
93+
align = max(align, ralign);
94+
}
95+
96+
if (align < ARCH_SLAB_MINALIGN)
97+
align = ARCH_SLAB_MINALIGN;
98+
99+
return ALIGN(align, sizeof(void *));
100+
}
101+
102+
75103
/*
76104
* kmem_cache_create - Create a cache.
77105
* @name: A string which is used in /proc/slabinfo to identify this cache.
@@ -124,7 +152,7 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size, size_t align
124152
s = kmem_cache_zalloc(kmem_cache, GFP_KERNEL);
125153
if (s) {
126154
s->object_size = s->size = size;
127-
s->align = align;
155+
s->align = calculate_alignment(flags, align, size);
128156
s->ctor = ctor;
129157
s->name = kstrdup(name, GFP_KERNEL);
130158
if (!s->name) {
@@ -211,7 +239,7 @@ void __init create_boot_cache(struct kmem_cache *s, const char *name, size_t siz
211239

212240
s->name = name;
213241
s->size = s->object_size = size;
214-
s->align = ARCH_KMALLOC_MINALIGN;
242+
s->align = calculate_alignment(flags, ARCH_KMALLOC_MINALIGN, size);
215243
err = __kmem_cache_create(s, flags);
216244

217245
if (err)

mm/slob.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ static inline void clear_slob_page_free(struct page *sp)
123123

124124
#define SLOB_UNIT sizeof(slob_t)
125125
#define SLOB_UNITS(size) (((size) + SLOB_UNIT - 1)/SLOB_UNIT)
126-
#define SLOB_ALIGN L1_CACHE_BYTES
127126

128127
/*
129128
* struct slob_rcu is inserted at the tail of allocated slob blocks, which
@@ -527,20 +526,11 @@ EXPORT_SYMBOL(ksize);
527526

528527
int __kmem_cache_create(struct kmem_cache *c, unsigned long flags)
529528
{
530-
size_t align = c->size;
531-
532529
if (flags & SLAB_DESTROY_BY_RCU) {
533530
/* leave room for rcu footer at the end of object */
534531
c->size += sizeof(struct slob_rcu);
535532
}
536533
c->flags = flags;
537-
/* ignore alignment unless it's forced */
538-
c->align = (flags & SLAB_HWCACHE_ALIGN) ? SLOB_ALIGN : 0;
539-
if (c->align < ARCH_SLAB_MINALIGN)
540-
c->align = ARCH_SLAB_MINALIGN;
541-
if (c->align < align)
542-
c->align = align;
543-
544534
return 0;
545535
}
546536

mm/slub.c

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2760,32 +2760,6 @@ static inline int calculate_order(int size, int reserved)
27602760
return -ENOSYS;
27612761
}
27622762

2763-
/*
2764-
* Figure out what the alignment of the objects will be.
2765-
*/
2766-
static unsigned long calculate_alignment(unsigned long flags,
2767-
unsigned long align, unsigned long size)
2768-
{
2769-
/*
2770-
* If the user wants hardware cache aligned objects then follow that
2771-
* suggestion if the object is sufficiently large.
2772-
*
2773-
* The hardware cache alignment cannot override the specified
2774-
* alignment though. If that is greater then use it.
2775-
*/
2776-
if (flags & SLAB_HWCACHE_ALIGN) {
2777-
unsigned long ralign = cache_line_size();
2778-
while (size <= ralign / 2)
2779-
ralign /= 2;
2780-
align = max(align, ralign);
2781-
}
2782-
2783-
if (align < ARCH_SLAB_MINALIGN)
2784-
align = ARCH_SLAB_MINALIGN;
2785-
2786-
return ALIGN(align, sizeof(void *));
2787-
}
2788-
27892763
static void
27902764
init_kmem_cache_node(struct kmem_cache_node *n)
27912765
{
@@ -2919,7 +2893,6 @@ static int calculate_sizes(struct kmem_cache *s, int forced_order)
29192893
{
29202894
unsigned long flags = s->flags;
29212895
unsigned long size = s->object_size;
2922-
unsigned long align = s->align;
29232896
int order;
29242897

29252898
/*
@@ -2990,20 +2963,12 @@ static int calculate_sizes(struct kmem_cache *s, int forced_order)
29902963
size += sizeof(void *);
29912964
#endif
29922965

2993-
/*
2994-
* Determine the alignment based on various parameters that the
2995-
* user specified and the dynamic determination of cache line size
2996-
* on bootup.
2997-
*/
2998-
align = calculate_alignment(flags, align, s->object_size);
2999-
s->align = align;
3000-
30012966
/*
30022967
* SLUB stores one object immediately after another beginning from
30032968
* offset 0. In order to align the objects we have to simply size
30042969
* each object to conform to the alignment.
30052970
*/
3006-
size = ALIGN(size, align);
2971+
size = ALIGN(size, s->align);
30072972
s->size = size;
30082973
if (forced_order >= 0)
30092974
order = forced_order;
@@ -3032,7 +2997,6 @@ static int calculate_sizes(struct kmem_cache *s, int forced_order)
30322997
s->max = s->oo;
30332998

30342999
return !!oo_objects(s->oo);
3035-
30363000
}
30373001

30383002
static int kmem_cache_open(struct kmem_cache *s, unsigned long flags)

0 commit comments

Comments
 (0)