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);
|
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();
|
void slab_init_post_sem();
|
||||||
|
|
||||||
// to protect code regions with interrupts turned on
|
// to protect code regions with interrupts turned on
|
||||||
|
|||||||
@@ -72,6 +72,10 @@ struct object_cache : DoublyLinkedListLinkImpl<object_cache> {
|
|||||||
object_cache_destructor destructor;
|
object_cache_destructor destructor;
|
||||||
object_cache_reclaimer reclaimer;
|
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;
|
object_depot depot;
|
||||||
|
|
||||||
virtual slab *CreateSlab(uint32 flags) = 0;
|
virtual slab *CreateSlab(uint32 flags) = 0;
|
||||||
@@ -156,6 +160,7 @@ static ObjectCacheList sObjectCaches;
|
|||||||
static benaphore sObjectCacheListLock;
|
static benaphore sObjectCacheListLock;
|
||||||
|
|
||||||
static uint8 *sInitialBegin, *sInitialLimit, *sInitialPointer;
|
static uint8 *sInitialBegin, *sInitialLimit, *sInitialPointer;
|
||||||
|
static kernel_args *sKernelArgs;
|
||||||
|
|
||||||
|
|
||||||
static status_t object_cache_reserve_internal(object_cache *cache,
|
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
|
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);
|
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
|
static void
|
||||||
free_pages(object_cache *cache, void *pages)
|
area_free_pages(object_cache *cache, void *pages)
|
||||||
{
|
{
|
||||||
area_id id = area_for(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
|
static void
|
||||||
object_cache_low_memory(void *_self, int32 level)
|
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->destructor = destructor;
|
||||||
cache->reclaimer = reclaimer;
|
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);
|
register_low_memory_handler(object_cache_low_memory, cache, 0);
|
||||||
|
|
||||||
BenaphoreLocker _(sObjectCacheListLock);
|
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
|
static void
|
||||||
delete_cache(object_cache *cache)
|
delete_cache(object_cache *cache)
|
||||||
{
|
{
|
||||||
@@ -1202,12 +1263,14 @@ dump_cache_info(int argc, char *argv[])
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
slab_init(addr_t initialBase, size_t initialSize)
|
slab_init(kernel_args *args, addr_t initialBase, size_t initialSize)
|
||||||
{
|
{
|
||||||
sInitialBegin = (uint8 *)initialBase;
|
sInitialBegin = (uint8 *)initialBase;
|
||||||
sInitialLimit = sInitialBegin + initialSize;
|
sInitialLimit = sInitialBegin + initialSize;
|
||||||
sInitialPointer = sInitialBegin;
|
sInitialPointer = sInitialBegin;
|
||||||
|
|
||||||
|
sKernelArgs = args;
|
||||||
|
|
||||||
new (&sObjectCaches) ObjectCacheList();
|
new (&sObjectCaches) ObjectCacheList();
|
||||||
|
|
||||||
block_allocator_init_boot();
|
block_allocator_init_boot();
|
||||||
@@ -1228,8 +1291,11 @@ slab_init_post_sem()
|
|||||||
ObjectCacheList::Iterator it = sObjectCaches.GetIterator();
|
ObjectCacheList::Iterator it = sObjectCaches.GetIterator();
|
||||||
|
|
||||||
while (it.HasNext()) {
|
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");
|
panic("slab_init: failed to create sems");
|
||||||
|
if (cache->allocate_pages == early_allocate_pages)
|
||||||
|
object_cache_commit_pre_pages(cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
block_allocator_init_rest();
|
block_allocator_init_rest();
|
||||||
|
|||||||
@@ -2894,7 +2894,7 @@ vm_init(kernel_args *args)
|
|||||||
size_t slabInitialSize = 2 * B_PAGE_SIZE;
|
size_t slabInitialSize = 2 * B_PAGE_SIZE;
|
||||||
addr_t slabInitialBase = vm_allocate_early(args, slabInitialSize,
|
addr_t slabInitialBase = vm_allocate_early(args, slabInitialSize,
|
||||||
slabInitialSize, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
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
|
// initialize the free page list and physical page mapper
|
||||||
vm_page_init(args);
|
vm_page_init(args);
|
||||||
|
|||||||
Reference in New Issue
Block a user