|
@@ -200,11 +200,6 @@ static inline void ClearSlabDebug(struct page *page)
|
|
|
#define ARCH_SLAB_MINALIGN __alignof__(unsigned long long)
|
|
|
#endif
|
|
|
|
|
|
-/*
|
|
|
- * The page->inuse field is 16 bit thus we have this limitation
|
|
|
- */
|
|
|
-#define MAX_OBJECTS_PER_SLAB 65535
|
|
|
-
|
|
|
/* Internal SLUB flags */
|
|
|
#define __OBJECT_POISON 0x80000000 /* Poison object */
|
|
|
#define __SYSFS_ADD_DEFERRED 0x40000000 /* Not yet visible via sysfs */
|
|
@@ -729,11 +724,6 @@ static int check_slab(struct kmem_cache *s, struct page *page)
|
|
|
slab_err(s, page, "Not a valid slab page");
|
|
|
return 0;
|
|
|
}
|
|
|
- if (page->offset * sizeof(void *) != s->offset) {
|
|
|
- slab_err(s, page, "Corrupted offset %lu",
|
|
|
- (unsigned long)(page->offset * sizeof(void *)));
|
|
|
- return 0;
|
|
|
- }
|
|
|
if (page->inuse > s->objects) {
|
|
|
slab_err(s, page, "inuse %u > max %u",
|
|
|
s->name, page->inuse, s->objects);
|
|
@@ -872,8 +862,6 @@ bad:
|
|
|
slab_fix(s, "Marking all objects used");
|
|
|
page->inuse = s->objects;
|
|
|
page->freelist = NULL;
|
|
|
- /* Fix up fields that may be corrupted */
|
|
|
- page->offset = s->offset / sizeof(void *);
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
@@ -1104,7 +1092,6 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
|
|
|
n = get_node(s, page_to_nid(page));
|
|
|
if (n)
|
|
|
atomic_long_inc(&n->nr_slabs);
|
|
|
- page->offset = s->offset / sizeof(void *);
|
|
|
page->slab = s;
|
|
|
page->flags |= 1 << PG_slab;
|
|
|
if (s->flags & (SLAB_DEBUG_FREE | SLAB_RED_ZONE | SLAB_POISON |
|
|
@@ -1398,10 +1385,10 @@ static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
|
|
|
|
|
|
/* Retrieve object from cpu_freelist */
|
|
|
object = c->freelist;
|
|
|
- c->freelist = c->freelist[page->offset];
|
|
|
+ c->freelist = c->freelist[c->offset];
|
|
|
|
|
|
/* And put onto the regular freelist */
|
|
|
- object[page->offset] = page->freelist;
|
|
|
+ object[c->offset] = page->freelist;
|
|
|
page->freelist = object;
|
|
|
page->inuse--;
|
|
|
}
|
|
@@ -1497,7 +1484,7 @@ load_freelist:
|
|
|
goto debug;
|
|
|
|
|
|
object = c->page->freelist;
|
|
|
- c->freelist = object[c->page->offset];
|
|
|
+ c->freelist = object[c->offset];
|
|
|
c->page->inuse = s->objects;
|
|
|
c->page->freelist = NULL;
|
|
|
c->node = page_to_nid(c->page);
|
|
@@ -1549,7 +1536,7 @@ debug:
|
|
|
goto another_slab;
|
|
|
|
|
|
c->page->inuse++;
|
|
|
- c->page->freelist = object[c->page->offset];
|
|
|
+ c->page->freelist = object[c->offset];
|
|
|
slab_unlock(c->page);
|
|
|
return object;
|
|
|
}
|
|
@@ -1580,7 +1567,7 @@ static void __always_inline *slab_alloc(struct kmem_cache *s,
|
|
|
|
|
|
else {
|
|
|
object = c->freelist;
|
|
|
- c->freelist = object[c->page->offset];
|
|
|
+ c->freelist = object[c->offset];
|
|
|
}
|
|
|
local_irq_restore(flags);
|
|
|
|
|
@@ -1613,7 +1600,7 @@ EXPORT_SYMBOL(kmem_cache_alloc_node);
|
|
|
* handling required then we can return immediately.
|
|
|
*/
|
|
|
static void __slab_free(struct kmem_cache *s, struct page *page,
|
|
|
- void *x, void *addr)
|
|
|
+ void *x, void *addr, unsigned int offset)
|
|
|
{
|
|
|
void *prior;
|
|
|
void **object = (void *)x;
|
|
@@ -1623,7 +1610,7 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
|
|
|
if (unlikely(SlabDebug(page)))
|
|
|
goto debug;
|
|
|
checks_ok:
|
|
|
- prior = object[page->offset] = page->freelist;
|
|
|
+ prior = object[offset] = page->freelist;
|
|
|
page->freelist = object;
|
|
|
page->inuse--;
|
|
|
|
|
@@ -1684,10 +1671,10 @@ static void __always_inline slab_free(struct kmem_cache *s,
|
|
|
debug_check_no_locks_freed(object, s->objsize);
|
|
|
c = get_cpu_slab(s, smp_processor_id());
|
|
|
if (likely(page == c->page && !SlabDebug(page))) {
|
|
|
- object[page->offset] = c->freelist;
|
|
|
+ object[c->offset] = c->freelist;
|
|
|
c->freelist = object;
|
|
|
} else
|
|
|
- __slab_free(s, page, x, addr);
|
|
|
+ __slab_free(s, page, x, addr, c->offset);
|
|
|
|
|
|
local_irq_restore(flags);
|
|
|
}
|
|
@@ -1774,14 +1761,6 @@ static inline int slab_order(int size, int min_objects,
|
|
|
int rem;
|
|
|
int min_order = slub_min_order;
|
|
|
|
|
|
- /*
|
|
|
- * If we would create too many object per slab then reduce
|
|
|
- * the slab order even if it goes below slub_min_order.
|
|
|
- */
|
|
|
- while (min_order > 0 &&
|
|
|
- (PAGE_SIZE << min_order) >= MAX_OBJECTS_PER_SLAB * size)
|
|
|
- min_order--;
|
|
|
-
|
|
|
for (order = max(min_order,
|
|
|
fls(min_objects * size - 1) - PAGE_SHIFT);
|
|
|
order <= max_order; order++) {
|
|
@@ -1796,9 +1775,6 @@ static inline int slab_order(int size, int min_objects,
|
|
|
if (rem <= slab_size / fract_leftover)
|
|
|
break;
|
|
|
|
|
|
- /* If the next size is too high then exit now */
|
|
|
- if (slab_size * 2 >= MAX_OBJECTS_PER_SLAB * size)
|
|
|
- break;
|
|
|
}
|
|
|
|
|
|
return order;
|
|
@@ -1878,6 +1854,7 @@ static void init_kmem_cache_cpu(struct kmem_cache *s,
|
|
|
{
|
|
|
c->page = NULL;
|
|
|
c->freelist = NULL;
|
|
|
+ c->offset = s->offset / sizeof(void *);
|
|
|
c->node = 0;
|
|
|
}
|
|
|
|
|
@@ -2110,14 +2087,7 @@ static int calculate_sizes(struct kmem_cache *s)
|
|
|
*/
|
|
|
s->objects = (PAGE_SIZE << s->order) / size;
|
|
|
|
|
|
- /*
|
|
|
- * Verify that the number of objects is within permitted limits.
|
|
|
- * The page->inuse field is only 16 bit wide! So we cannot have
|
|
|
- * more than 64k objects per slab.
|
|
|
- */
|
|
|
- if (!s->objects || s->objects > MAX_OBJECTS_PER_SLAB)
|
|
|
- return 0;
|
|
|
- return 1;
|
|
|
+ return !!s->objects;
|
|
|
|
|
|
}
|
|
|
|