Clean up some comments in slab, and use round_up function instead of a custom one.
This commit is contained in:
+10
-16
@@ -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
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user