sos-code-article6.75/sos/kmem_slab.h

207 lines
7.7 KiB
C

/* Copyright (C) 2000 Thomas Petazzoni
Copyright (C) 2004 David Decotigny
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA.
*/
#ifndef _SOS_KMEM_SLAB_H_
#define _SOS_KMEM_SLAB_H_
/**
* @file kmem_slab.h
*
* Kernel Memory Allocator based on Bonwick's slab llocator (Solaris
* 2.4, Linux 2.4). This allocator achieves good memory utilization
* ratio (memory effectively used / memory requested) ie limited
* fragmentation, while elegantly handling cache-effect considerations
* (TLB locality through the notion of "cache" of slabs, and the
* dcache utilization through the notion of cache colouring to
* decrease the conflicts in the dcache for accesses to different data
* in the same cache).
*
* This allocator relies on the range allocator (kmem_vmm.h) to
* allocate the slabs, which itself relies on the slab allocator to
* allocate its "range" data structures, thus leading to a
* chicken-and-egg problem. We solve this problem by introducing the
* notion of "min_free_objs" for the slab caches, in order for the cache
* of ranges to always have enough ranges in reserve to complete the
* range allocation before being urged to allocate a new slab of
* ranges, which would require the allocation of a new range.
*
* Compared to Bonwick's recommendations, we don't handle ctor/dtor
* routines on the objects, so that we can alter the objects once they
* are set free. Thus, the list of free object is stored in the free
* objects themselves, not alongside the objects (this also implies that
* the SOS_KSLAB_CREATE_MAP flag below is meaningless). We also don't
* implement the cache colouring (trivial to add, but we omit it for
* readability reasons), and the only alignment constraint we respect
* is that allocated objects are aligned on a 4B boundary: for other
* alignment constraints, the user must integrate them in the
* "object_size" parameter to "sos_kmem_cache_create()".
*
* References :
* - J. Bonwick's paper, "The slab allocator: An object-caching kernel
* memory allocator", In USENIX Summer 1994 Technical Conference
* - The bible, aka "Unix internals : the new frontiers" (section
* 12.10), Uresh Vahalia, Prentice Hall 1996, ISBN 0131019082
* - "The Linux slab allocator", B. Fitzgibbons,
* http://www.cc.gatech.edu/people/home/bradf/cs7001/proj2/
* - The Kos, http://kos.enix.org/
*/
#include <sos/types.h>
#include <sos/errno.h>
/** Opaque data structure that defines a Cache of slabs */
struct sos_kslab_cache;
/** Opaque data structure that defines a slab. Exported only to
kmem_vmm.h */
struct sos_kslab;
#include "kmem_vmm.h"
/** The maximum allowed pages for each slab */
#define MAX_PAGES_PER_SLAB 32 /* 128 kB */
/**
* Initialize the slab cache of slab caches, and prepare the cache of
* kmem_range for kmem_vmm.
*
* @param kernel_core_base The virtual address of the first byte used
* by the kernel code/data
*
* @param kernel_core_top The virtual address of the first byte after
* the kernel code/data.
*
* @param sizeof_struct_range the size of the objects (aka "struct
* sos_kmem_vmm_ranges") to be allocated in the cache of ranges
*
* @param first_struct_slab_of_caches (output value) the virtual
* address of the first slab structure that gets allocated for the
* cache of caches. The function actually manually allocate the first
* slab of the cache of caches because of a chicken-and-egg thing. The
* address of the slab is used by the kmem_vmm_setup routine to
* finalize the allocation of the slab, in order for it to behave like
* a real slab afterwards.
*
* @param first_slab_of_caches_base (output value) the virtual address
* of the slab associated to the slab structure.
*
* @param first_slab_of_caches_nb_pages (output value) the number of
* (virtual) pages used by the first slab of the cache of caches.
*
* @param first_struct_slab_of_ranges (output value) the virtual address
* of the first slab that gets allocated for the cache of ranges. Same
* explanation as above.
*
* @param first_slab_of_ranges_base (output value) the virtual address
* of the slab associated to the slab structure.
*
* @param first_slab_of_ranges_nb_pages (output value) the number of
* (virtual) pages used by the first slab of the cache of ranges.
*
* @return the cache of kmem_range immediatly usable
*/
struct sos_kslab_cache *
sos_kmem_cache_subsystem_setup_prepare(sos_vaddr_t kernel_core_base,
sos_vaddr_t kernel_core_top,
sos_size_t sizeof_struct_range,
/* results */
struct sos_kslab **first_struct_slab_of_caches,
sos_vaddr_t *first_slab_of_caches_base,
sos_count_t *first_slab_of_caches_nb_pages,
struct sos_kslab **first_struct_slab_of_ranges,
sos_vaddr_t *first_slab_of_ranges_base,
sos_count_t *first_slab_of_ranges_nb_pages);
/**
* Update the configuration of the cache subsystem once the vmm
* subsystem has been fully initialized
*/
sos_ret_t
sos_kmem_cache_subsystem_setup_commit(struct sos_kslab *first_struct_slab_of_caches,
struct sos_kmem_range *first_range_of_caches,
struct sos_kslab *first_struct_slab_of_ranges,
struct sos_kmem_range *first_range_of_ranges);
/*
* Flags for sos_kmem_cache_create()
*/
/** The slabs should be initially mapped in physical memory */
#define SOS_KSLAB_CREATE_MAP (1<<0)
/** The object should always be set to zero at allocation (implies
SOS_KSLAB_CREATE_MAP) */
#define SOS_KSLAB_CREATE_ZERO (1<<1)
/**
* @note this function MAY block (involved allocations are not atomic)
* @param name must remain valid during the whole cache's life
* (shallow copy) !
* @param cache_flags An or-ed combination of the SOS_KSLAB_CREATE_* flags
*/
struct sos_kslab_cache *
sos_kmem_cache_create(const char* name,
sos_size_t object_size,
sos_count_t pages_per_slab,
sos_count_t min_free_objects,
sos_ui32_t cache_flags);
sos_ret_t sos_kmem_cache_destroy(struct sos_kslab_cache *kslab_cache);
/*
* Flags for sos_kmem_cache_alloc()
*/
/** Allocation should either succeed or fail, without blocking */
#define SOS_KSLAB_ALLOC_ATOMIC (1<<0)
/**
* Allocate an object from the given cache.
*
* @param alloc_flags An or-ed combination of the SOS_KSLAB_ALLOC_* flags
*/
sos_vaddr_t sos_kmem_cache_alloc(struct sos_kslab_cache *kslab_cache,
sos_ui32_t alloc_flags);
/**
* Free an object (assumed to be already allocated and not already
* free) at the given virtual address.
*/
sos_ret_t sos_kmem_cache_free(sos_vaddr_t vaddr);
/*
* Function reserved to kmem_vmm.c. Does almost everything
* sos_kmem_cache_free() does, except it does not call
* sos_kmem_vmm_del_range() if it needs to. This is aimed at avoiding
* large recursion when a range is freed with
* sos_kmem_vmm_del_range().
*
* @param the_range The range structure to free
*
* @return NULL when the range containing 'the_range' still contains
* other ranges, or the address of the range which owned 'the_range'
* if it becomes empty.
*/
struct sos_kmem_range *
sos_kmem_cache_release_struct_range(struct sos_kmem_range *the_range);
#endif /* _SOS_KMEM_SLAB_H_ */