kernel/vm: Use more than one object_cache for the page mappings.
Every time a page is mapped into an area on fault, we have to allocate a mapping object for it. While the object_cache does have per-CPU depots, these depots only store a limited number of items, and once they run out the object_cache's lock must be acquired. So, to reduce lock contention on SMP systems, create a number of object caches corresponding to the nearest power of 2 that is equal or smaller than the count of CPUs. (We already allocate dozens of object caches for the block allocator no matter how many CPUs there are, so a few more depending on CPU count shouldn't impact memory use too much. Besides, the object_caches are wired into the low_resource system.) This significantly reduces lock contention on SMP systems. Same benchmark setup as yesterday (compile mime_db and relink HaikuDepot, VMware, -j4), before: real 0m16.981s user 0m14.357s sys 0m6.060s after: real 0m14.522s user 0m14.194s sys 0m4.337s And the page_mappings object_cache locks went from having 200,000+ waits and ~14 seconds waiting time (across all threads) down to ~900 (yes, that's not a typo) and ~0.05s wait time (though these numbers were captured in conjunction with the following commit.)
This commit is contained in:
@@ -17,7 +17,6 @@
|
||||
|
||||
struct generic_io_vec;
|
||||
struct kernel_args;
|
||||
struct ObjectCache;
|
||||
struct system_memory_info;
|
||||
struct VMAddressSpace;
|
||||
struct VMArea;
|
||||
@@ -48,9 +47,6 @@ struct VMPageWiringInfo;
|
||||
#define VM_MEMORY_RESERVE_SYSTEM (VM_PAGE_RESERVE_SYSTEM * B_PAGE_SIZE)
|
||||
|
||||
|
||||
extern struct ObjectCache* gPageMappingsObjectCache;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -86,6 +82,8 @@ area_id transfer_area(area_id id, void** _address, uint32 addressSpec,
|
||||
|
||||
const char* vm_cache_type_to_string(int32 type);
|
||||
|
||||
void vm_free_page_mapping(page_num_t page, vm_page_mapping* mapping, uint32 flags);
|
||||
|
||||
status_t vm_prepare_kernel_area_debug_protection(area_id id, void** cookie);
|
||||
status_t vm_set_kernel_area_debug_protection(void* cookie, void* _address,
|
||||
size_t size, uint32 protection);
|
||||
|
||||
Reference in New Issue
Block a user