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:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user