|
@@ -85,6 +85,7 @@ int sysctl_overcommit_memory __read_mostly = OVERCOMMIT_GUESS; /* heuristic ove
|
|
|
int sysctl_overcommit_ratio __read_mostly = 50; /* default is 50% */
|
|
|
int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;
|
|
|
unsigned long sysctl_user_reserve_kbytes __read_mostly = 1UL << 17; /* 128MB */
|
|
|
+unsigned long sysctl_admin_reserve_kbytes __read_mostly = 1UL << 13; /* 8MB */
|
|
|
/*
|
|
|
* Make sure vm_committed_as in one cacheline and not cacheline shared with
|
|
|
* other variables. It can be updated by several CPUs frequently.
|
|
@@ -164,10 +165,10 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin)
|
|
|
free -= totalreserve_pages;
|
|
|
|
|
|
/*
|
|
|
- * Leave the last 3% for root
|
|
|
+ * Reserve some for root
|
|
|
*/
|
|
|
if (!cap_sys_admin)
|
|
|
- free -= free / 32;
|
|
|
+ free -= sysctl_admin_reserve_kbytes >> (PAGE_SHIFT - 10);
|
|
|
|
|
|
if (free > pages)
|
|
|
return 0;
|
|
@@ -178,10 +179,10 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin)
|
|
|
allowed = (totalram_pages - hugetlb_total_pages())
|
|
|
* sysctl_overcommit_ratio / 100;
|
|
|
/*
|
|
|
- * Leave the last 3% for root
|
|
|
+ * Reserve some for root
|
|
|
*/
|
|
|
if (!cap_sys_admin)
|
|
|
- allowed -= allowed / 32;
|
|
|
+ allowed -= sysctl_admin_reserve_kbytes >> (PAGE_SHIFT - 10);
|
|
|
allowed += total_swap_pages;
|
|
|
|
|
|
/*
|
|
@@ -3119,3 +3120,24 @@ static int __meminit init_user_reserve(void)
|
|
|
return 0;
|
|
|
}
|
|
|
module_init(init_user_reserve)
|
|
|
+
|
|
|
+/*
|
|
|
+ * Initialise sysctl_admin_reserve_kbytes.
|
|
|
+ *
|
|
|
+ * The purpose of sysctl_admin_reserve_kbytes is to allow the sys admin
|
|
|
+ * to log in and kill a memory hogging process.
|
|
|
+ *
|
|
|
+ * Systems with more than 256MB will reserve 8MB, enough to recover
|
|
|
+ * with sshd, bash, and top in OVERCOMMIT_GUESS. Smaller systems will
|
|
|
+ * only reserve 3% of free pages by default.
|
|
|
+ */
|
|
|
+static int __meminit init_admin_reserve(void)
|
|
|
+{
|
|
|
+ unsigned long free_kbytes;
|
|
|
+
|
|
|
+ free_kbytes = global_page_state(NR_FREE_PAGES) << (PAGE_SHIFT - 10);
|
|
|
+
|
|
|
+ sysctl_admin_reserve_kbytes = min(free_kbytes / 32, 1UL << 13);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+module_init(init_admin_reserve)
|