Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 365432
b: refs/heads/master
c: 4eeab4f
h: refs/heads/master
v: v3
  • Loading branch information
Andrew Shewmaker authored and Linus Torvalds committed Apr 29, 2013
1 parent 868bd4a commit aa4ee03
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 9 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: c9b1d0981fcce3d9976d7b7a56e4e0503bc610dd
refs/heads/master: 4eeab4f5580d11bffedc697684b91b0bca0d5009
30 changes: 30 additions & 0 deletions trunk/Documentation/sysctl/vm.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ files can be found in mm/swap.c.

Currently, these files are in /proc/sys/vm:

- admin_reserve_kbytes
- block_dump
- compact_memory
- dirty_background_bytes
Expand Down Expand Up @@ -59,6 +60,35 @@ Currently, these files are in /proc/sys/vm:

==============================================================

admin_reserve_kbytes

The amount of free memory in the system that should be reserved for users
with the capability cap_sys_admin.

admin_reserve_kbytes defaults to min(3% of free pages, 8MB)

That should provide enough for the admin to log in and kill a process,
if necessary, under the default overcommit 'guess' mode.

Systems running under overcommit 'never' should increase this to account
for the full Virtual Memory Size of programs used to recover. Otherwise,
root may not be able to log in to recover the system.

How do you calculate a minimum useful reserve?

sshd or login + bash (or some other shell) + top (or ps, kill, etc.)

For overcommit 'guess', we can sum resident set sizes (RSS).
On x86_64 this is about 8MB.

For overcommit 'never', we can take the max of their virtual sizes (VSZ)
and add the sum of their RSS.
On x86_64 this is about 128MB.

Changing this takes effect whenever an application requests memory.

==============================================================

block_dump

block_dump enables block I/O debugging when set to a nonzero value. More
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ extern int sysctl_legacy_va_layout;
#include <asm/processor.h>

extern unsigned long sysctl_user_reserve_kbytes;
extern unsigned long sysctl_admin_reserve_kbytes;

#define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))

Expand Down
7 changes: 7 additions & 0 deletions trunk/kernel/sysctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1436,6 +1436,13 @@ static struct ctl_table vm_table[] = {
.mode = 0644,
.proc_handler = proc_doulongvec_minmax,
},
{
.procname = "admin_reserve_kbytes",
.data = &sysctl_admin_reserve_kbytes,
.maxlen = sizeof(sysctl_admin_reserve_kbytes),
.mode = 0644,
.proc_handler = proc_doulongvec_minmax,
},
{ }
};

Expand Down
30 changes: 26 additions & 4 deletions trunk/mm/mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand All @@ -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;

/*
Expand Down Expand Up @@ -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)
30 changes: 26 additions & 4 deletions trunk/mm/nommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ int sysctl_overcommit_ratio = 50; /* default is 50% */
int sysctl_max_map_count = DEFAULT_MAX_MAP_COUNT;
int sysctl_nr_trim_pages = CONFIG_NOMMU_INITIAL_TRIM_EXCESS;
unsigned long sysctl_user_reserve_kbytes __read_mostly = 1UL << 17; /* 128MB */
unsigned long sysctl_admin_reserve_kbytes __read_mostly = 1UL << 13; /* 8MB */
int heap_stack_gap = 0;

atomic_long_t mmap_pages_allocated;
Expand Down Expand Up @@ -1939,10 +1940,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;
Expand All @@ -1952,10 +1953,10 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin)

allowed = totalram_pages * sysctl_overcommit_ratio / 100;
/*
* Leave the last 3% for root
* Reserve some 3% for root
*/
if (!cap_sys_admin)
allowed -= allowed / 32;
allowed -= sysctl_admin_reserve_kbytes >> (PAGE_SHIFT - 10);
allowed += total_swap_pages;

/*
Expand Down Expand Up @@ -2147,3 +2148,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)

0 comments on commit aa4ee03

Please sign in to comment.