Clean up some comments in slab, and use round_up function instead of a custom one.

This commit is contained in:
Enrico Fraccaroli (Galfurian)
2023-06-27 11:13:54 -04:00
parent b7c82d7333
commit 4e35a1682f
2 changed files with 39 additions and 43 deletions
+10 -16
View File
@@ -12,21 +12,15 @@
/// @brief Type for slab flags. /// @brief Type for slab flags.
typedef unsigned int slab_flags_t; typedef unsigned int slab_flags_t;
typedef void (*kmem_fun_t)(void *);
/// Create a new cache. /// Create a new cache.
#define KMEM_CREATE(objtype) kmem_cache_create(#objtype, \ #define KMEM_CREATE(objtype) \
sizeof(objtype), \ kmem_cache_create(#objtype, sizeof(objtype), alignof(objtype), GFP_KERNEL, NULL, NULL)
alignof(objtype), \
GFP_KERNEL, \
NULL, \
NULL)
/// Creates a new cache and allows to specify the constructor. /// Creates a new cache and allows to specify the constructor.
#define KMEM_CREATE_CTOR(objtype, ctor) kmem_cache_create(#objtype, \ #define KMEM_CREATE_CTOR(objtype, ctor) \
sizeof(objtype), \ kmem_cache_create(#objtype, sizeof(objtype), alignof(objtype), GFP_KERNEL, (kmem_fun_t)(ctor), NULL)
alignof(objtype), \
GFP_KERNEL, \
((void (*)(void *))(ctor)), \
NULL)
/// @brief Stores the information of a cache. /// @brief Stores the information of a cache.
typedef struct kmem_cache_t { typedef struct kmem_cache_t {
@@ -49,9 +43,9 @@ typedef struct kmem_cache_t {
/// The order for getting free pages. /// The order for getting free pages.
unsigned int gfp_order; unsigned int gfp_order;
/// Constructor for the elements. /// Constructor for the elements.
void (*ctor)(void *); kmem_fun_t ctor;
/// Destructor for the elements. /// Destructor for the elements.
void (*dtor)(void *); kmem_fun_t dtor;
/// Handler for the full slabs list. /// Handler for the full slabs list.
list_head slabs_full; list_head slabs_full;
/// Handler for the partial slabs list. /// Handler for the partial slabs list.
@@ -76,8 +70,8 @@ kmem_cache_t *kmem_cache_create(
unsigned int size, unsigned int size,
unsigned int align, unsigned int align,
slab_flags_t flags, slab_flags_t flags,
void (*ctor)(void *), kmem_fun_t ctor,
void (*dtor)(void *)); kmem_fun_t dtor);
/// @brief Deletes the given cache. /// @brief Deletes the given cache.
/// @param cachep Pointer to the cache. /// @param cachep Pointer to the cache.
+29 -27
View File
@@ -38,45 +38,39 @@ static kmem_cache_t *malloc_blocks[MAX_KMALLOC_CACHE_ORDER];
static int __alloc_slab_page(kmem_cache_t *cachep, gfp_t flags) static int __alloc_slab_page(kmem_cache_t *cachep, gfp_t flags)
{ {
// ALlocate the required number of pages.
page_t *page = _alloc_pages(flags, cachep->gfp_order); page_t *page = _alloc_pages(flags, cachep->gfp_order);
if (!page) { if (!page) {
pr_crit("Failed to allocate a new page from slab.\n"); pr_crit("Failed to allocate a new page from slab.\n");
return -1; return -1;
} }
// Initialize the lists.
list_head_init(&page->slabs); list_head_init(&page->slabs);
list_head_init(&page->slab_freelist);
// Save in the root page the kmem_cache_t pointer, // Save in the root page the kmem_cache_t pointer, to allow freeing
// to allow freeing arbitrary pointers // arbitrary pointers.
page[0].container.slab_cache = cachep; page[0].container.slab_cache = cachep;
// Update slab main pages of all child pages, to allow reconstructing which
// Update slab main pages of all child pages, to allow // page handles a specified address
// reconstructing which page handles a specified address
for (unsigned int i = 1; i < (1U << cachep->gfp_order); i++) { for (unsigned int i = 1; i < (1U << cachep->gfp_order); i++) {
page[i].container.slab_main_page = page; page[i].container.slab_main_page = page;
} }
// Compute the slab size.
unsigned int slab_size = PAGE_SIZE * (1U << cachep->gfp_order); unsigned int slab_size = PAGE_SIZE * (1U << cachep->gfp_order);
// Update the page objects counters.
// Update the page objects counters
page->slab_objcnt = slab_size / cachep->size; page->slab_objcnt = slab_size / cachep->size;
page->slab_objfree = page->slab_objcnt; page->slab_objfree = page->slab_objcnt;
// Get the page address.
unsigned int pg_addr = get_lowmem_address_from_page(page); unsigned int pg_addr = get_lowmem_address_from_page(page);
list_head_init(&page->slab_freelist);
// Build the objects structures // Build the objects structures
for (unsigned int i = 0; i < page->slab_objcnt; i++) { for (unsigned int i = 0; i < page->slab_objcnt; i++) {
kmem_obj *obj = KMEM_OBJ(cachep, pg_addr + cachep->size * i); kmem_obj *obj = KMEM_OBJ(cachep, pg_addr + cachep->size * i);
list_head_insert_after(&obj->objlist, &page->slab_freelist); list_head_insert_after(&obj->objlist, &page->slab_freelist);
} }
// Add the page to the slab list and update the counters // Add the page to the slab list and update the counters
list_head_insert_after(&page->slabs, &cachep->slabs_free); list_head_insert_after(&page->slabs, &cachep->slabs_free);
cachep->total_num += page->slab_objcnt; cachep->total_num += page->slab_objcnt;
cachep->free_num += page->slab_objcnt; cachep->free_num += page->slab_objcnt;
return 0; return 0;
} }
@@ -90,26 +84,28 @@ static void __kmem_cache_refill(kmem_cache_t *cachep, unsigned int free_num, gfp
} }
} }
static unsigned int __find_next_alignment(unsigned int size, unsigned int align)
{
return (size / align + (size % align ? 1 : 0)) * align;
}
static void __compute_size_and_order(kmem_cache_t *cachep) static void __compute_size_and_order(kmem_cache_t *cachep)
{ {
// Align the whole object to the required padding // Align the whole object to the required padding.
cachep->size = __find_next_alignment( cachep->size = round_up(
max(cachep->object_size, KMEM_OBJ_OVERHEAD), max(cachep->object_size, KMEM_OBJ_OVERHEAD),
max(8, cachep->align)); max(8, cachep->align));
// Compute the gfp order // Compute the gfp order
unsigned int size = __find_next_alignment(cachep->size, PAGE_SIZE) / PAGE_SIZE; unsigned int size = round_up(cachep->size, PAGE_SIZE) / PAGE_SIZE;
while ((size /= 2) > 0) { while ((size /= 2) > 0) {
cachep->gfp_order++; cachep->gfp_order++;
} }
} }
static void __kmem_cache_create(kmem_cache_t *cachep, const char *name, unsigned int size, unsigned int align, slab_flags_t flags, void (*ctor)(void *), void (*dtor)(void *), unsigned int start_count) static void __kmem_cache_create(
kmem_cache_t *cachep,
const char *name,
unsigned int size,
unsigned int align,
slab_flags_t flags,
kmem_fun_t ctor,
kmem_fun_t dtor,
unsigned int start_count)
{ {
pr_info("Creating new cache `%s` with objects of size `%d`.\n", name, size); pr_info("Creating new cache `%s` with objects of size `%d`.\n", name, size);
@@ -194,7 +190,13 @@ void kmem_cache_init()
} }
} }
kmem_cache_t *kmem_cache_create(const char *name, unsigned int size, unsigned int align, slab_flags_t flags, void (*ctor)(void *), void (*dtor)(void *)) kmem_cache_t *kmem_cache_create(
const char *name,
unsigned int size,
unsigned int align,
slab_flags_t flags,
kmem_fun_t ctor,
kmem_fun_t dtor)
{ {
kmem_cache_t *cachep = (kmem_cache_t *)kmem_cache_alloc(&kmem_cache, GFP_KERNEL); kmem_cache_t *cachep = (kmem_cache_t *)kmem_cache_alloc(&kmem_cache, GFP_KERNEL);
if (!cachep) if (!cachep)