From c87ef6db88e8dbc06accf256f7bac1c68a8b431f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 15 Jan 2008 16:47:26 +0000 Subject: [PATCH] Made Haiku behave better when you have more memory: * with 1 GB or more, the semaphore limit is now 131072 instead of 65536. * double the heap when there is 1 GB or more (64 MB). * the low memory handler now also watches semaphore usage; in the end, we need a low resource handler, not a low memory handler. * create_sem_etc() no longer calls vfs_free_unused_vnodes() directly as this could actually deadlock (at least because the address space is a R/W lock, not a recursive lock). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23538 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/sem.c | 11 ++++++++--- src/system/kernel/vm/vm.cpp | 4 +++- src/system/kernel/vm/vm_low_memory.cpp | 14 ++++++++++++-- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/system/kernel/sem.c b/src/system/kernel/sem.c index 2dbc0b71a1..de508e8d3a 100644 --- a/src/system/kernel/sem.c +++ b/src/system/kernel/sem.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. * Distributed under the terms of the MIT License. * * Copyright 2001, Travis Geiselbrecht. All rights reserved. @@ -67,7 +67,7 @@ struct sem_entry { } u; }; -static const int32 kMaxSemaphores = 65536; +static const int32 kMaxSemaphores = 131072; static int32 sMaxSems = 4096; // Final value is computed based on the amount of available memory static int32 sUsedSems = 0; @@ -350,7 +350,8 @@ sem_init(kernel_args *args) // compute maximal number of semaphores depending on the available memory // 128 MB -> 16384 semaphores, 448 kB fixed array size // 256 MB -> 32768, 896 kB - // 512 MB and more -> 1.75 MB + // 512 MB -> 65536, 1.75 MB + // 1024 MB and more -> 131072, 3.5 MB i = vm_page_num_pages() / 2; while (sMaxSems < i && sMaxSems < kMaxSemaphores) sMaxSems <<= 1; @@ -399,6 +400,9 @@ create_sem_etc(int32 count, const char *name, team_id owner) if (sSemsActive == false) return B_NO_MORE_SEMS; +#if 0 + // TODO: the code below might cause unwanted deadlocks, + // we need an asynchronously running low resource handler. if (sUsedSems == sMaxSems) { // The vnode cache may have collected lots of semaphores. // Freeing some unused vnodes should improve our situation. @@ -410,6 +414,7 @@ create_sem_etc(int32 count, const char *name, team_id owner) // try again with more enthusiasm vfs_free_unused_vnodes(B_LOW_MEMORY_CRITICAL); } +#endif if (sUsedSems == sMaxSems) return B_NO_MORE_SEMS; diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index 3d8dd33b88..204f2115b5 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. @@ -3468,6 +3468,8 @@ vm_init(kernel_args *args) heapSize /= 4; else if (sAvailableMemory < 200 * 1024 * 1024) heapSize /= 2; + else if (sAvailableMemory >= 1024 * 1024 * 1024) + heapSize *= 2; // map in the new heap and initialize it addr_t heapBase = vm_allocate_early(args, heapSize, heapSize, diff --git a/src/system/kernel/vm/vm_low_memory.cpp b/src/system/kernel/vm/vm_low_memory.cpp index b3ff74ffe5..9a3c7aea28 100644 --- a/src/system/kernel/vm/vm_low_memory.cpp +++ b/src/system/kernel/vm/vm_low_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2005-2007, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2005-2008, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -74,13 +75,22 @@ compute_state(void) sLastMeasurement = system_time(); uint32 freePages = vm_page_num_free_pages(); + + if (freePages > kNoteLimit) { + // TODO: work-around for a missing general low resource handler + if (sem_used_sems() * 6 > sem_max_sems() * 5) + return B_LOW_MEMORY_WARNING; + if (sem_used_sems() * 3 > sem_max_sems() * 2) + return B_LOW_MEMORY_NOTE; + } + if (freePages >= kNoteLimit) return B_NO_LOW_MEMORY; // specify low memory level if (freePages < kCriticalLimit) return B_LOW_MEMORY_CRITICAL; - else if (freePages < kWarnLimit) + if (freePages < kWarnLimit) return B_LOW_MEMORY_WARNING; return B_LOW_MEMORY_NOTE;