cache/slab: when CACHE_DURING_BOOT is specified, use vm_allocate_early to obtain pages for slabs, and create the associated areas on post bootup.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20913 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Hugo Santos
2007-04-29 22:58:46 +00:00
parent 39af445966
commit 698b6d7195
3 changed files with 73 additions and 6 deletions
+2 -1
View File
@@ -32,7 +32,8 @@ addr_t vm_allocate_early(kernel_args *args, size_t virtualSize,
size_t physicalSize, uint32 attributes);
void slab_init(addr_t initialBase, size_t initialSize);
void slab_init(struct kernel_args *args, addr_t initialBase,
size_t initialSize);
void slab_init_post_sem();
// to protect code regions with interrupts turned on
+70 -4
View File
@@ -72,6 +72,10 @@ struct object_cache : DoublyLinkedListLinkImpl<object_cache> {
object_cache_destructor destructor;
object_cache_reclaimer reclaimer;
status_t (*allocate_pages)(object_cache *cache, void **pages,
uint32 flags);
void (*free_pages)(object_cache *cache, void *pages);
object_depot depot;
virtual slab *CreateSlab(uint32 flags) = 0;
@@ -156,6 +160,7 @@ static ObjectCacheList sObjectCaches;
static benaphore sObjectCacheListLock;
static uint8 *sInitialBegin, *sInitialLimit, *sInitialPointer;
static kernel_args *sKernelArgs;
static status_t object_cache_reserve_internal(object_cache *cache,
@@ -258,7 +263,7 @@ benaphore_boot_init(benaphore *lock, const char *name, uint32 flags)
static status_t
allocate_pages(object_cache *cache, void **pages, uint32 flags)
area_allocate_pages(object_cache *cache, void **pages, uint32 flags)
{
TRACE_CACHE(cache, "allocate pages (%lu, 0x0%lx)", cache->slab_size, flags);
@@ -283,7 +288,7 @@ allocate_pages(object_cache *cache, void **pages, uint32 flags)
static void
free_pages(object_cache *cache, void *pages)
area_free_pages(object_cache *cache, void *pages)
{
area_id id = area_for(pages);
@@ -298,6 +303,24 @@ free_pages(object_cache *cache, void *pages)
}
static status_t
early_allocate_pages(object_cache *cache, void **pages, uint32 flags)
{
addr_t base = vm_allocate_early(sKernelArgs, cache->slab_size,
cache->slab_size, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
*pages = (void *)base;
return B_OK;
}
static void
early_free_pages(object_cache *cache, void *pages)
{
panic("memory pressure on bootup?");
}
static void
object_cache_low_memory(void *_self, int32 level)
{
@@ -409,6 +432,14 @@ object_cache_init(object_cache *cache, const char *name, size_t objectSize,
cache->destructor = destructor;
cache->reclaimer = reclaimer;
if (cache->flags & CACHE_DURING_BOOT) {
cache->allocate_pages = early_allocate_pages;
cache->free_pages = early_free_pages;
} else {
cache->allocate_pages = area_allocate_pages;
cache->free_pages = area_free_pages;
}
register_low_memory_handler(object_cache_low_memory, cache, 0);
BenaphoreLocker _(sObjectCacheListLock);
@@ -432,6 +463,36 @@ object_cache_init_locks(object_cache *cache)
}
static void
object_cache_commit_slab(object_cache *cache, slab *slab)
{
void *pages = (void *)ROUNDOWN((addr_t)slab->pages, B_PAGE_SIZE);
if (create_area(cache->name, &pages, B_EXACT_ADDRESS, cache->slab_size,
B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA) < B_OK)
panic("failed to create_area()");
}
static void
object_cache_commit_pre_pages(object_cache *cache)
{
SlabList::Iterator it = cache->full.GetIterator();
while (it.HasNext())
object_cache_commit_slab(cache, it.Next());
it = cache->partial.GetIterator();
while (it.HasNext())
object_cache_commit_slab(cache, it.Next());
it = cache->empty.GetIterator();
while (it.HasNext())
object_cache_commit_slab(cache, it.Next());
cache->allocate_pages = area_allocate_pages;
cache->free_pages = area_free_pages;
}
static void
delete_cache(object_cache *cache)
{
@@ -1202,12 +1263,14 @@ dump_cache_info(int argc, char *argv[])
void
slab_init(addr_t initialBase, size_t initialSize)
slab_init(kernel_args *args, addr_t initialBase, size_t initialSize)
{
sInitialBegin = (uint8 *)initialBase;
sInitialLimit = sInitialBegin + initialSize;
sInitialPointer = sInitialBegin;
sKernelArgs = args;
new (&sObjectCaches) ObjectCacheList();
block_allocator_init_boot();
@@ -1228,8 +1291,11 @@ slab_init_post_sem()
ObjectCacheList::Iterator it = sObjectCaches.GetIterator();
while (it.HasNext()) {
if (object_cache_init_locks(it.Next()) < B_OK)
object_cache *cache = it.Next();
if (object_cache_init_locks(cache) < B_OK)
panic("slab_init: failed to create sems");
if (cache->allocate_pages == early_allocate_pages)
object_cache_commit_pre_pages(cache);
}
block_allocator_init_rest();
+1 -1
View File
@@ -2894,7 +2894,7 @@ vm_init(kernel_args *args)
size_t slabInitialSize = 2 * B_PAGE_SIZE;
addr_t slabInitialBase = vm_allocate_early(args, slabInitialSize,
slabInitialSize, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
slab_init(slabInitialBase, slabInitialSize);
slab_init(args, slabInitialBase, slabInitialSize);
// initialize the free page list and physical page mapper
vm_page_init(args);