|
@@ -2783,23 +2783,38 @@ int build_detached_freelist(struct kmem_cache *s, size_t size,
|
|
size_t first_skipped_index = 0;
|
|
size_t first_skipped_index = 0;
|
|
int lookahead = 3;
|
|
int lookahead = 3;
|
|
void *object;
|
|
void *object;
|
|
|
|
+ struct page *page;
|
|
|
|
|
|
/* Always re-init detached_freelist */
|
|
/* Always re-init detached_freelist */
|
|
df->page = NULL;
|
|
df->page = NULL;
|
|
|
|
|
|
do {
|
|
do {
|
|
object = p[--size];
|
|
object = p[--size];
|
|
|
|
+ /* Do we need !ZERO_OR_NULL_PTR(object) here? (for kfree) */
|
|
} while (!object && size);
|
|
} while (!object && size);
|
|
|
|
|
|
if (!object)
|
|
if (!object)
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
- /* Support for memcg, compiler can optimize this out */
|
|
|
|
- df->s = cache_from_obj(s, object);
|
|
|
|
|
|
+ page = virt_to_head_page(object);
|
|
|
|
+ if (!s) {
|
|
|
|
+ /* Handle kalloc'ed objects */
|
|
|
|
+ if (unlikely(!PageSlab(page))) {
|
|
|
|
+ BUG_ON(!PageCompound(page));
|
|
|
|
+ kfree_hook(object);
|
|
|
|
+ __free_kmem_pages(page, compound_order(page));
|
|
|
|
+ p[size] = NULL; /* mark object processed */
|
|
|
|
+ return size;
|
|
|
|
+ }
|
|
|
|
+ /* Derive kmem_cache from object */
|
|
|
|
+ df->s = page->slab_cache;
|
|
|
|
+ } else {
|
|
|
|
+ df->s = cache_from_obj(s, object); /* Support for memcg */
|
|
|
|
+ }
|
|
|
|
|
|
/* Start new detached freelist */
|
|
/* Start new detached freelist */
|
|
|
|
+ df->page = page;
|
|
set_freepointer(df->s, object, NULL);
|
|
set_freepointer(df->s, object, NULL);
|
|
- df->page = virt_to_head_page(object);
|
|
|
|
df->tail = object;
|
|
df->tail = object;
|
|
df->freelist = object;
|
|
df->freelist = object;
|
|
p[size] = NULL; /* mark object processed */
|
|
p[size] = NULL; /* mark object processed */
|