Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 365433
b: refs/heads/master
c: 1640879
h: refs/heads/master
i:
  365431: 868bd4a
v: v3
  • Loading branch information
Andrew Shewmaker authored and Linus Torvalds committed Apr 29, 2013
1 parent aa4ee03 commit 57cfc7f
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4eeab4f5580d11bffedc697684b91b0bca0d5009
refs/heads/master: 1640879afe0065caf276e98fff059c4dc01c97ae
76 changes: 74 additions & 2 deletions trunk/mm/mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
#include <linux/uprobes.h>
#include <linux/rbtree_augmented.h>
#include <linux/sched/sysctl.h>
#include <linux/notifier.h>
#include <linux/memory.h>

#include <asm/uaccess.h>
#include <asm/cacheflush.h>
Expand Down Expand Up @@ -3110,7 +3112,7 @@ void __init mmap_init(void)
* The default value is min(3% of free memory, 128MB)
* 128MB is enough to recover with sshd/login, bash, and top/kill.
*/
static int __meminit init_user_reserve(void)
static int init_user_reserve(void)
{
unsigned long free_kbytes;

Expand All @@ -3131,7 +3133,7 @@ module_init(init_user_reserve)
* 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)
static int init_admin_reserve(void)
{
unsigned long free_kbytes;

Expand All @@ -3141,3 +3143,73 @@ static int __meminit init_admin_reserve(void)
return 0;
}
module_init(init_admin_reserve)

/*
* Reinititalise user and admin reserves if memory is added or removed.
*
* The default user reserve max is 128MB, and the default max for the
* admin reserve is 8MB. These are usually, but not always, enough to
* enable recovery from a memory hogging process using login/sshd, a shell,
* and tools like top. It may make sense to increase or even disable the
* reserve depending on the existence of swap or variations in the recovery
* tools. So, the admin may have changed them.
*
* If memory is added and the reserves have been eliminated or increased above
* the default max, then we'll trust the admin.
*
* If memory is removed and there isn't enough free memory, then we
* need to reset the reserves.
*
* Otherwise keep the reserve set by the admin.
*/
static int reserve_mem_notifier(struct notifier_block *nb,
unsigned long action, void *data)
{
unsigned long tmp, free_kbytes;

switch (action) {
case MEM_ONLINE:
/* Default max is 128MB. Leave alone if modified by operator. */
tmp = sysctl_user_reserve_kbytes;
if (0 < tmp && tmp < (1UL << 17))
init_user_reserve();

/* Default max is 8MB. Leave alone if modified by operator. */
tmp = sysctl_admin_reserve_kbytes;
if (0 < tmp && tmp < (1UL << 13))
init_admin_reserve();

break;
case MEM_OFFLINE:
free_kbytes = global_page_state(NR_FREE_PAGES) << (PAGE_SHIFT - 10);

if (sysctl_user_reserve_kbytes > free_kbytes) {
init_user_reserve();
pr_info("vm.user_reserve_kbytes reset to %lu\n",
sysctl_user_reserve_kbytes);
}

if (sysctl_admin_reserve_kbytes > free_kbytes) {
init_admin_reserve();
pr_info("vm.admin_reserve_kbytes reset to %lu\n",
sysctl_admin_reserve_kbytes);
}
break;
default:
break;
}
return NOTIFY_OK;
}

static struct notifier_block reserve_mem_nb = {
.notifier_call = reserve_mem_notifier,
};

static int __meminit init_reserve_notifier(void)
{
if (register_hotmemory_notifier(&reserve_mem_nb))
printk("Failed registering memory add/remove notifier for admin reserve");

return 0;
}
module_init(init_reserve_notifier)

0 comments on commit 57cfc7f

Please sign in to comment.