shm cleanups
Subsystems (3)
PATCH 1/1 shm cleanups
The following message was crippled somewhere on the way to linux-mm so I resend it:
Hi Linus,
Here is a patch against 2.3.25 which
1) avoids vmalloc in the shm coding.
2) cleans a lot of cruft out of the shm headers
3) makes shm sysctl'able
I did test it a lot on SMP/HIGHMEM. Since 2.3.25 with and without this breaks on swapping shm and other high memory load conditions I could not verify everything. But I would like to see this in the mainstream kernel. I will then proceed debugging the swapping issues.
Greetings
Christoph
arch/i386/kernel/sys_i386.c +64 -79
@@ -116,86 +116,71 @@ version = call >>16 ;/* hack for backward compatibility */ call &=0xffff ; -if (call <=SEMCTL ) -switch (call) { -case SEMOP : -return sys_semop (first, (struct sembuf *)ptr, second); -case SEMGET : -return sys_semget (first, second, third); -case SEMCTL : { -union semun fourth; -if (!ptr) -return -EINVAL ; -if (get_user (fourth.__pad, (void **) ptr)) -return -EFAULT ; -return sys_semctl (first, second, third, fourth); - } -default : -return -EINVAL ; - } +switch (call) { +case SEMOP : +return sys_semop (first, (struct sembuf *)ptr, second); +case SEMGET : +return sys_semget (first, second, third); +case SEMCTL : { +union semun fourth; +if (!ptr) +return -EINVAL ; +if (get_user (fourth.__pad, (void **) ptr)) +return -EFAULT ; +return sys_semctl (first, second, third, fourth); + } -if (call <=MSGCTL ) -switch (call) { -case MSGSND : -return sys_msgsnd (first, (struct msgbuf *) ptr, - second, third); -case MSGRCV : -switch (version) { -case 0 : { -struct ipc_kludge tmp; -if (!ptr) -return -EINVAL ; - -if (copy_from_user (&tmp, - (struct ipc_kludge *) ptr, -sizeof (tmp))) -return -EFAULT ; -return sys_msgrcv (first, tmp.msgp, second, - tmp.msgtyp, third); - } -default : -return sys_msgrcv (first, - (struct msgbuf *) ptr, - second, fifth, third); - } -case MSGGET : -return sys_msgget ((key_t ) first, second); -case MSGCTL : -return sys_msgctl (first, second, - (struct msqid_ds *) ptr); -default : -return -EINVAL ; - } -if (call <=SHMCTL ) -switch (call) { -case SHMAT : -switch (version) { -default : { -ulong raddr; - ret =sys_shmat (first, (char *) ptr, - second, &raddr); -if (ret) -return ret; -return put_user (raddr, (ulong *) third); - } -case 1 :/* iBCS2 emulator entry point */ -if (!segment_eq (get_fs (),get_ds ())) -return -EINVAL ; -return sys_shmat (first, (char *) ptr, - second, (ulong *) third); - } -case SHMDT : -return sys_shmdt ((char *)ptr); -case SHMGET : -return sys_shmget (first, second, third); -case SHMCTL : -return sys_shmctl (first, second, - (struct shmid_ds *) ptr); -default : -return -EINVAL ; - } - -return -EINVAL ; +case MSGSND : +return sys_msgsnd (first, (struct msgbuf *) ptr, + second, third); +case MSGRCV : +switch (version) { +case 0 : { +struct ipc_kludge tmp; +if (!ptr) +return -EINVAL ; + +if (copy_from_user (&tmp, + (struct ipc_kludge *) ptr, +sizeof (tmp))) +return -EFAULT ; +return sys_msgrcv (first, tmp.msgp, second, + tmp.msgtyp, third); + } +default : +return sys_msgrcv (first, + (struct msgbuf *) ptr, + second, fifth, third); + } +case MSGGET : +return sys_msgget ((key_t ) first, second); +case MSGCTL : +return sys_msgctl (first, second, (struct msqid_ds *) ptr); + +case SHMAT : +switch (version) { +default : { +ulong raddr; + ret =sys_shmat (first, (char *) ptr, second, &raddr); +if (ret) +return ret; +return put_user (raddr, (ulong *) third); + } +case 1 :/* iBCS2 emulator entry point */ +if (!segment_eq (get_fs (),get_ds ())) +return -EINVAL ; +return sys_shmat (first, (char *) ptr, second, (ulong *) third); + } +case SHMDT : +return sys_shmdt ((char *)ptr); +case SHMGET : +return sys_shmget (first, second, third); +case SHMCTL : +return sys_shmctl (first, second, + (struct shmid_ds *) ptr); +default : +return -EINVAL ; + } }/*
include/asm-alpha/shmparam.h +1 -42
48 lines not on this page · raw message
include/asm-arm/proc-armo/shmparam.h +1 -3
@@ -9,9 +9,7 @@#ifndef __ASM_PROC_SHMPARAM_H#define __ASM_PROC_SHMPARAM_H -#ifndef SHM_RANGE_START -#define SHM_RANGE_START 0x00a00000 -#define SHM_RANGE_END 0x00c00000 +#ifndef SHMMAX #define SHMMAX 0x003fa000#endif
include/asm-arm/proc-armv/shmparam.h +1 -3
@@ -10,9 +10,7 @@#ifndef __ASM_PROC_SHMPARAM_H#define __ASM_PROC_SHMPARAM_H -#ifndef SHM_RANGE_START -#define SHM_RANGE_START 0x50000000 -#define SHM_RANGE_END 0x60000000 +#ifndef SHMMAX #define SHMMAX 0x01000000#endif
include/asm-arm/shmparam.h +1 -34
@@ -3,39 +3,6 @@#include <asm/proc/shmparam.h> -/* -* Format of a swap-entry for shared memory pages currently out in -* swap space (see also mm/swap.c). -* -* SWP_TYPE = SHM_SWP_TYPE -* SWP_OFFSET is used as follows: -* -* bits 0..6 : id of shared memory segment page belongs to (SHM_ID) -* bits 7..21: index of page within shared memory segment (SHM_IDX) -* (actually fewer bits get used since SHMMAX is so low) -*/ - -/* -* Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and -* there is a static array of size SHMMNI. -*/ -#define _SHM_ID_BITS 7 -#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1) - -#define SHM_IDX_SHIFT (_SHM_ID_BITS) -#define _SHM_IDX_BITS 15 -#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1) - -/* -* _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and -* SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS). -*/ - -#define SHMMIN 1/* really PAGE_SIZE */ /* min shared seg size (bytes) */ -#define SHMMNI (1<<_SHM_ID_BITS)/* max num of segs system wide */ -#define SHMALL /* max shm system wide (pages) */ \ - (1<<(_SHM_IDX_BITS+_SHM_ID_BITS)) -#define SHMLBA PAGE_SIZE/* attach addr a multiple of this */ -#define SHMSEG SHMMNI/* max shared segs per process */ +#define SHMLBA PAGE_SIZE/* attach addr a multiple of this */ #endif /* _ASMARM_SHMPARAM_H */
include/asm-i386/shmparam.h +1 -41
47 lines not on this page · raw message
include/asm-m68k/shmparam.h +1 -44
50 lines not on this page · raw message
include/asm-mips/shmparam.h +0 -40
@@ -1,49 +1,9 @@#ifndef __ASM_MIPS_SHMPARAM_H#define __ASM_MIPS_SHMPARAM_H -/* address range for shared memory attaches if no address passed to shmat() */ -#define SHM_RANGE_START 0x50000000 -#define SHM_RANGE_END 0x60000000 - -/* -* Format of a swap-entry for shared memory pages currently out in -* swap space (see also mm/swap.c). -* -* SWP_TYPE = SHM_SWP_TYPE -* SWP_OFFSET is used as follows: -* -* bits 0..6 : id of shared memory segment page belongs to (SHM_ID) -* bits 7..21: index of page within shared memory segment (SHM_IDX) -* (actually fewer bits get used since SHMMAX is so low) -*/ - -/* -* Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and -* there is a static array of size SHMMNI. -*/ -#define _SHM_ID_BITS 7 -#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1) - -#define SHM_IDX_SHIFT (_SHM_ID_BITS) -#define _SHM_IDX_BITS 15 -#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1) - -/* -* _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and -* SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS). -*/ - -#define SHMMAX 0x2000000/* max shared seg size (bytes) */ -/* Try not to change the default shipped SHMMAX - people rely on it */ - -#define SHMMIN 1/* really PAGE_SIZE */ /* min shared seg size (bytes) */ -#define SHMMNI (1<<_SHM_ID_BITS)/* max num of segs system wide */ -#define SHMALL /* max shm system wide (pages) */ \ - (1<<(_SHM_IDX_BITS+_SHM_ID_BITS))/* * This constant is very large but the ABI in it's wisdom says ... */ #define SHMLBA 0x40000/* attach addr a multiple of this */ -#define SHMSEG SHMMNI/* max shared segs per process */ #endif /* __ASM_MIPS_SHMPARAM_H */
include/asm-ppc/shmparam.h +1 -39
@@ -1,44 +1,6 @@#ifndef _PPC_SHMPARAM_H#define _PPC_SHMPARAM_H -/* address range for shared memory attaches if no address passed to shmat() */ -#define SHM_RANGE_START 0x50000000 -#define SHM_RANGE_END 0x60000000 - -/* -* Format of a swap-entry for shared memory pages currently out in -* swap space (see also mm/swap.c). -* -* SWP_TYPE = SHM_SWP_TYPE -* SWP_OFFSET is used as follows: -* -* bits 0..6 : id of shared memory segment page belongs to (SHM_ID) -* bits 7..21: index of page within shared memory segment (SHM_IDX) -* (actually fewer bits get used since SHMMAX is so low) -*/ - -/* -* Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and -* there is a static array of size SHMMNI. -*/ -#define _SHM_ID_BITS 7 -#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1) - -#define SHM_IDX_SHIFT (_SHM_ID_BITS) -#define _SHM_IDX_BITS 15 -#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1) - -/* -* _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and -* SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS). -*/ - -#define SHMMAX 0x2000000/* max shared seg size (bytes) */ -#define SHMMIN 1/* really PAGE_SIZE */ /* min shared seg size (bytes) */ -#define SHMMNI (1<<_SHM_ID_BITS)/* max num of segs system wide */ -#define SHMALL /* max shm system wide (pages) */ \ - (1<<(_SHM_IDX_BITS+_SHM_ID_BITS)) -#define SHMLBA PAGE_SIZE/* attach addr a multiple of this */ -#define SHMSEG SHMMNI/* max shared segs per process */ +#define SHMLBA PAGE_SIZE/* attach addr a multiple of this */ #endif /* _PPC_SHMPARAM_H */
include/asm-sh/shmparam.h +1 -41
47 lines not on this page · raw message
include/asm-sparc/shmparam.h +1 -39
@@ -2,44 +2,6 @@#ifndef _ASMSPARC_SHMPARAM_H#define _ASMSPARC_SHMPARAM_H -/* address range for shared memory attaches if no address passed to shmat() */ -#define SHM_RANGE_START 0x10000000 -#define SHM_RANGE_END 0x20000000 - -/* -* Format of a swap-entry for shared memory pages currently out in -* swap space (see also mm/swap.c). -* -* SWP_TYPE = SHM_SWP_TYPE -* SWP_OFFSET is used as follows: -* -* bits 0..6 : id of shared memory segment page belongs to (SHM_ID) -* bits 7..21: index of page within shared memory segment (SHM_IDX) -* (actually fewer bits get used since SHMMAX is so low) -*/ - -/* -* Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and -* there is a static array of size SHMMNI. -*/ -#define _SHM_ID_BITS 7 -#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1) - -#define SHM_IDX_SHIFT (_SHM_ID_BITS) -#define _SHM_IDX_BITS 15 -#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1) - -/* -* _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and -* SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS). -*/ - -#define SHMMAX 0x1000000/* max shared seg size (bytes) */ -#define SHMMIN 1/* really PAGE_SIZE */ /* min shared seg size (bytes) */ -#define SHMMNI (1<<_SHM_ID_BITS)/* max num of segs system wide */ -#define SHMALL /* max shm system wide (pages) */ \ - (1<<(_SHM_IDX_BITS+_SHM_ID_BITS)) -#define SHMLBA PAGE_SIZE/* attach addr a multiple of this */ -#define SHMSEG SHMMNI/* max shared segs per process */ +#define SHMLBA PAGE_SIZE/* attach addr a multiple of this */ #endif /* _ASMSPARC_SHMPARAM_H */
include/asm-sparc64/shmparam.h +0 -40
@@ -2,46 +2,6 @@#ifndef _ASMSPARC64_SHMPARAM_H#define _ASMSPARC64_SHMPARAM_H -/* XXX Redo most of this... */ - -/* address range for shared memory attaches if no address passed to shmat() */ -#define SHM_RANGE_START 0x10000000 -#define SHM_RANGE_END 0x20000000 - -/* -* Format of a swap-entry for shared memory pages currently out in -* swap space (see also mm/swap.c). -* -* SWP_TYPE = SHM_SWP_TYPE -* SWP_OFFSET is used as follows: -* -* bits 0..6 : id of shared memory segment page belongs to (SHM_ID) -* bits 7..21: index of page within shared memory segment (SHM_IDX) -* (actually fewer bits get used since SHMMAX is so low) -*/ - -/* -* Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and -* there is a static array of size SHMMNI. -*/ -#define _SHM_ID_BITS 7 -#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1) - -#define SHM_IDX_SHIFT (_SHM_ID_BITS) -#define _SHM_IDX_BITS 15 -#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1) - -/* -* _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and -* SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS). -*/ - -#define SHMMAX 0x1000000/* max shared seg size (bytes) */ -#define SHMMIN 1/* really PAGE_SIZE */ /* min shared seg size (bytes) */ -#define SHMMNI (1<<_SHM_ID_BITS)/* max num of segs system wide */ -#define SHMALL /* max shm system wide (pages) */ \ - (1<<(_SHM_IDX_BITS+_SHM_ID_BITS))#define SHMLBA (PAGE_SIZE<<1)/* attach addr a multiple of this */ -#define SHMSEG SHMMNI/* max shared segs per process */ #endif /* _ASMSPARC64_SHMPARAM_H */
include/linux/shm.h +11 -9
@@ -3,6 +3,17 @@#include <linux/ipc.h> +/* +* SHMMAX, SHMMNI and SHMALL are upper limits are defaults which can +* be increased by sysctl +*/ + +#define SHMMAX 0x2000000/* max shared seg size (bytes) */ +#define SHMMIN 1/* really PAGE_SIZE */ /* min shared seg size (bytes) */ +#define SHMMNI 128/* max num of segs system wide */ +#define SHMALL (SHMMAX/PAGE_SIZE*SHMMNI)/* max shm system wide (pages) */ +#define SHMSEG SHMMNI/* max shared segs per process */ +#include <asm/shmparam.h> struct shmid_ds {
@@ -17,15 +28,6 @@unsigned short shm_unused;/* compatibility */ void *shm_unused2;/* ditto - used by DIPC */ void *shm_unused3;/* unused */ -}; - -struct shmid_kernel -{ -struct shmid_ds u; -/* the following are private */ -unsigned long shm_npages;/* size of segment (pages) */ -pte_t *shm_pages;/* array of ptrs to frames -> SHMMAX */ -struct vm_area_struct *attaches;/* descriptors for attaches */ };/* permission flag for shmget */
include/linux/swap.h +0 -11
@@ -122,17 +122,6 @@asmlinkage long sys_swapoff (const char *);asmlinkage long sys_swapon (const char *,int ); -/* -* vm_ops not present page codes for shared memory. -* -* Will go away eventually.. -*/ -#define SHM_SWP_TYPE 0x20 - -/* -* swap cache stuff (in linux/mm/swap_state.c) -*/ -#define SWAP_CACHE_INFO #ifdef SWAP_CACHE_INFO
include/linux/sysctl.h +1 -2
@@ -103,8 +103,7 @@KERN_MSGPOOL =37 ,/* int: Maximum system message pool size */ KERN_SYSRQ =38 ,/* int: Sysreq enable */ KERN_MAX_THREADS =39 ,/* int: Maximum nr of threads in the system */ -KERN_RANDOM =40 ,/* Random driver */ - KERN_SHMALL=41 /* int: Maximum size of shared memory */ + KERN_RANDOM=40 /* Random driver */ };
ipc/shm.c +189 -75
537 lines not on this page · raw message
ipc/util.c +2 -0
@@ -14,6 +14,8 @@#include <linux/init.h> #include <linux/msg.h> +#include "util.h" +#if defined(CONFIG_SYSVIPC )extern void sem_init (void ),msg_init (void ),shm_init (void );
ipc/util.h +12 -0
@@ -0,0 +1,12 @@ +/* +* linux/ipc/util.h +* Copyright (C) 1999 Christoph Rohland +*/ + +/* +* IPCMNI is the absolute maximum for ipc identifier. This is used to +* detect stale identifiers +*/ +#define IPCMNI (1<<15) + +extern int ipcperms (struct ipc_perm *ipcp,short shmflg);
kernel/sysctl.c +2 -2
@@ -49,7 +49,7 @@extern int sg_big_buff;#endif #ifdef CONFIG_SYSVIPC -extern size_t shmmax; +extern size_t shm_prm[];#endif #ifdef __sparc__
@@ -213,7 +213,7 @@ {KERN_RTSIGMAX ,"rtsig-max" , &max_queued_signals,sizeof (int ), 0644, NULL, &proc_dointvec}, #ifdef CONFIG_SYSVIPC - {KERN_SHMMAX, "shmmax", &shmmax, sizeof (size_t), + {KERN_SHMMAX, "shmmax", &shm_prm, 3*sizeof (size_t), 0644, NULL, &proc_doulongvec_minmax}, #endif #ifdef CONFIG_MAGIC_SYSRQ
mm/swap_state.c +0 -4
@@ -68,8 +68,6 @@if (!entry.val) goto out; type =SWP_TYPE (entry); -if (type &SHM_SWP_TYPE ) - goto out;if (type >= nr_swapfiles) goto bad_file; p = type + swap_info;
@@ -115,8 +113,6 @@if (!entry.val) goto bad_entry; type =SWP_TYPE (entry); -if (type &SHM_SWP_TYPE ) - goto out;if (type >= nr_swapfiles) goto bad_file; p = type + swap_info;
mm/swapfile.c +0 -4
@@ -135,8 +135,6 @@ goto out; type =SWP_TYPE (entry); -if (type &SHM_SWP_TYPE ) - goto out;if (type >= nr_swapfiles) goto bad_nofile; p = & swap_info[type];
@@ -190,8 +188,6 @@ goto new_swap_entry; entry.val = page->index; type =SWP_TYPE (entry); -if (type &SHM_SWP_TYPE ) - goto new_swap_entry;if (type >= nr_swapfiles) goto new_swap_entry; p = type + swap_info;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://humbolt.geo.uu.nl/Linux-MM/
Quoted 4 lines · Christoph Rohland
I did test it a lot on SMP/HIGHMEM. Since 2.3.25 with and without this breaks on swapping shm and other high memory load conditions I could not verify everything. But I would like to see this in the mainstream kernel. I will then proceed debugging the swapping issues.
(i can see the problems too, but i've got no explanation either, working on it as well.)
-- mingo
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://humbolt.geo.uu.nl/Linux-MM/
Hi Ingo,
Quoted 11 lines · Ingo Molnar
Quoted 4 lines · Christoph Rohland
I did test it a lot on SMP/HIGHMEM. Since 2.3.25 with and without this breaks on swapping shm and other high memory load conditions I could not verify everything. But I would like to see this in the mainstream kernel. I will then proceed debugging the swapping issues.
(i can see the problems too, but i've got no explanation either, working on it as well.)
-- mingo
After applying the following patch against ipc/shm.c (thanks to Larry Woodman <[email protected]> for the first one):
ipc/shm.c Thu Nov 4 12:47:14 1999 renamed from ipc/shm.c Tue Nov 2 12:46:29 1999 +2 -2
@@ -788,10 +789,10 @@ unlock_kernel(); return 0; } - if (page_count(page_map)) + if (page_count(page_map) != 1) goto check_table; if (!(page_map = prepare_highmem_swapout(page_map))) - goto check_table; + goto failed; shp->shm_pages[idx] = swp_entry_to_pte(swap_entry); swap_successes++; shm_swp++;
791c791
< if (page_count(page_map))
---
Quoted 1 line
if (page_count(page_map) != 1)
I get the same behaviour for shm swapping as on 2.3.22 as long as I only use 1G memory (HIGHMEM setting is always 64GB).
I do get swapping also with 8GB of RAM, but it runs out of memory before running out of swap space since prepare_highmem_swapout is failing way to often.
(It then locks up since it cannot free the shm segments and so is unable to free the memory. This should be perhaps addressed later in the oom handler. It cannot handle the case where nearly all memory is allocted in shm segments)
Greetings
Christoph
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://humbolt.geo.uu.nl/Linux-MM/
Quoted 8 lines · Christoph Rohland
I do get swapping also with 8GB of RAM, but it runs out of memory before running out of swap space since
prepare_highmem_swapoutis failing way to often.(It then locks up since it cannot free the shm segments and so is unable to free the memory. This should be perhaps addressed later in the oom handler. It cannot handle the case where nearly all memory is allocted in shm segments)
ho humm. I think prepare_highmem_swapout() has a design bug. It's way too naive in low memory situations, it should keep a short list of pages for emergency swapout. It's the GFP_ATOMIC that is failing too often, right?
i believe we should have some explicit mechanizm that tells vmscan that there is 'IO in progress which will result in more memory', to distinct between true out-of-memory and 'wait a little bit to get more RAM' cases? I think we'd have a lot less to worry about and there would be a much clearer distinction between true out-of-mem and 'just cannot allocate it right now but help is on the way' cases.
Ingo
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://humbolt.geo.uu.nl/Linux-MM/
Quoted 6 lines · Ingo Molnar
Quoted 3 lines · Christoph Rohland
I do get swapping also with 8GB of RAM, but it runs out of memory before running out of swap space since
prepare_highmem_swapoutis failing way to often.
Quoted 7 lines
ho humm. I think
prepare_highmem_swapout()has a design bug. It's way too naive in low memory situations, it should keep a short list of pages for emergency swapout. It's theGFP_ATOMICthat is failing too often, right?i believe we should have some explicit mechanizm that tells vmscan that there is 'IO in progress which will result in more memory', to distinct between true out-of-memory and 'wait a little bit to get more RAM' cases?
I think I see what is going on here. Kswapd sees that memory is low an "frees" a bunch of high memory pages, causing those pages to be shifted to low memory so the total number of free pages stays just as low as when kswapd started.
This can result in in-memory swap storms, we should probably limit the number of in-transit async himem pages to 256 or some other even smaller number.
regards,
Rik
--
The Internet is not a network of computers. It is a network of people. That is its real strength.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://humbolt.geo.uu.nl/Linux-MM/
Quoted 4 lines · Rik van Riel
I think I see what is going on here. Kswapd sees that memory is low an "frees" a bunch of high memory pages, causing those pages to be shifted to low memory so the total number of free pages stays just as low as when kswapd started.
hm, kswapd should really be immune against this.
Quoted 3 lines
This can result in in-memory swap storms, we should probably limit the number of in-transit async himem pages to 256 or some other even smaller number.
i introduced some stupid balancing bugs, and i wrongly thought that the fixes are already in 2.3.25, but no, it's the pre1-2.3.26 kernel that is supposed to have balancing right. basically the fix is to restore the original behavior of not counting high memory in memory pressure. This might sound an unfair policy, but the real critical resource is low memory. If this ever proves to be a problematic approach then we still can make it more sophisticated.
[Christoph, are you still seeing the same kind of bad swapping behavior with pre1-2.3.26?]
-- mingo
ps. some people might ask why we want to swap on an 8GB box, but i think it's really an issue in production systems to provide some kind of 'rubber wall' instead of 'hard concrete' if the system is reaching its limits. adding (99% unused) swap space does exactly this.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://humbolt.geo.uu.nl/Linux-MM/
Quoted 2 lines · Ingo Molnar
[Christoph, are you still seeing the same kind of bad swapping behavior with pre1-2.3.26?]
If you still get process killed during heavy swapout (cause OOM of an ATOMIC allocation) please try to increase the ATOMIC pool before designing a separate pool. We just have a pool for atomic allocation it may not be large enough for the increased pressure on the regular pages.
echo 1000 2000 4000 >/proc/sys/vm/freepages
This way you'll basically waste 16mbyte of ram. It's just to check if the ATOMIC allocation shortage is the source of the segfault or not.
Signature · 5 lines
Andrea -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://humbolt.geo.uu.nl/Linux-MM/
Quoted 10 lines · Andrea Arcangeli
Quoted 2 lines · Ingo Molnar
[Christoph, are you still seeing the same kind of bad swapping behavior with pre1-2.3.26?]
If you still get process killed during heavy swapout (cause OOM of an ATOMIC allocation) please try to increase the ATOMIC pool before designing a separate pool. We just have a pool for atomic allocation it may not be large enough for the increased pressure on the regular pages.
Quoted 4 lines
echo 1000 2000 4000 >/proc/sys/vm/freepagesThis way you'll basically waste 16mbyte of ram. It's just to check if the ATOMIC allocation shortage is the source of the segfault or not.
O.k. with and without these settings 2.3.26-pre2 looks pretty good about allocating bounce buffers and swapping highmem pages.
To swap shm the first part of the following patch is definitely needed. The second part makes the machine probably much more useable if we have problems allocating bounce buffers. Which now hardly ever happens when stresstesting my 8GB machine.
Linus, could you please apply this?
Christoph
ipc/shm.c Thu Nov 4 12:47:14 1999 renamed from ipc/shm.c Tue Nov 2 12:46:29 1999 +2 -2
@@ -788,10 +789,10 @@ unlock_kernel(); return 0; } - if (page_count(page_map)) + if (page_count(page_map) != 1) goto check_table; if (!(page_map = prepare_highmem_swapout(page_map))) - goto check_table; + goto failed; shp->shm_pages[idx] = swp_entry_to_pte(swap_entry); swap_successes++; shm_swp++;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://humbolt.geo.uu.nl/Linux-MM/
ipc/shm.c Thu Nov 4 12:47:14 1999 line 795
Quoted 3 lines · Christoph Rohland
if (!(page_map =
prepare_highmem_swapout(page_map)))ipc/shm.c Thu Nov 4 12:47:14 1999 renamed from ipc/shm.c Tue Nov 2 12:46:29 1999 +1
-1- goto check_table; + goto failed;
This fragment isn't correct. You may fail too early and so you may get a task killed due OOM even if you still have lots of regular pages queued in a shm segment.
Signature · 5 lines
Andrea -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://humbolt.geo.uu.nl/Linux-MM/
Quoted 9 lines · Andrea Arcangeli
ipc/shm.c Thu Nov 4 12:47:14 1999 line 795
Quoted 3 lines · Christoph Rohland
if (!(page_map =
prepare_highmem_swapout(page_map)))ipc/shm.c Thu Nov 4 12:47:14 1999 renamed from ipc/shm.c Tue Nov 2 12:46:29 1999 +1
-1- goto check_table; + goto failed;This fragment isn't correct. You may fail too early and so you may get a task killed due OOM even if you still have lots of regular pages queued in a shm segment.
Yes I know it is questionable, but if prepare_highmem_swapout fails we are in the highmem area and probably most of the rest of shm is also there. So we only consume a lot of CPU if going on and calling prepare_highmem_swapout again and again..
prepare_highmem_swapout should not fail (and does not fail very often in 2.3.26-pre2) In 2.3.25 the machine effectivly locked up when it failed (and it failed very often).
On 2.3.26-pre2 I do not see a difference between the two versions. So I do not know which way will be better.
Christoph
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://humbolt.geo.uu.nl/Linux-MM/
Quoted 3 lines · Christoph Rohland
Yes I know it is questionable, but if
prepare_highmem_swapoutfails we are in the highmem area and probably most of the rest of shm is also there. So we only consume a lot of CPU if going on and calling
If prepare_highmem_swapout fails maybe all the regular pages are allocated in the rest of the shm segment and to free them and do progresses you should continue to properly shrink the VM.
Quoted 1 line
prepare_highmem_swapoutagain and again..
That will happen in the patological unlikely to happen case so the performance of such path is not an issue.
Andrea
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://humbolt.geo.uu.nl/Linux-MM/
Quoted 6 lines · Andrea Arcangeli
Quoted 3 lines · Christoph Rohland
Yes I know it is questionable, but if
prepare_highmem_swapoutfails we are in the highmem area and probably most of the rest of shm is also there. So we only consume a lot of CPU if going on and calling
Quoted 8 lines
If
prepare_highmem_swapoutfails maybe all the regular pages are allocated in the rest of the shm segment and to free them and do progresses you should continue to properly shrink the VM.Quoted 1 line
prepare_highmem_swapoutagain and again..That will happen in the patological unlikely to happen case so the performance of such path is not an issue.
So we only need the first part of the patch.
Christoph
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://humbolt.geo.uu.nl/Linux-MM/
Quoted 21 lines · Ingo Molnar
Quoted 4 lines · Rik van Riel
I think I see what is going on here. Kswapd sees that memory is low an "frees" a bunch of high memory pages, causing those pages to be shifted to low memory so the total number of free pages stays just as low as when kswapd started.
hm, kswapd should really be immune against this.
Quoted 3 lines
This can result in in-memory swap storms, we should probably limit the number of in-transit async himem pages to 256 or some other even smaller number.
i introduced some stupid balancing bugs, and i wrongly thought that the fixes are already in 2.3.25, but no, it's the pre1-2.3.26 kernel that is supposed to have balancing right. basically the fix is to restore the original behavior of not counting high memory in memory pressure. This might sound an unfair policy, but the real critical resource is low memory. If this ever proves to be a problematic approach then we still can make it more sophisticated.
Quoted 2 lines
[Christoph, are you still seeing the same kind of bad swapping behavior with pre1-2.3.26?]
No, after applying the following patch, it is much better now:
ipc/shm.c Fri Nov 5 10:54:09 1999 renamed from ipc/shm.c Fri Nov 5 10:25:40 1999 +2 -2
@@ -897,10 +897,10 @@ unlock_kernel(); return 0; } - if (page_count(page_map)) + if (page_count(page_map) != 1) goto check_table; if (!(page_map = prepare_highmem_swapout(page_map))) - goto check_table; + goto failed; SHM_ENTRY (shp, idx) = swp_entry_to_pte(swap_entry); swap_successes++; shm_swp++;
[root@ls3016 src]# ipcs -um
------ Shared Memory Status --------
segments allocated 274
pages allocated 2244608
pages resident 2043405
pages swapped 177175
Swap performance: 251917 attempts 241439 successes
[root@ls3016 src]# cat /proc/meminfo
total: used: free: shared: buffers: cached:
Mem: 4152516608 4133502976 19013632 0 512000 21954560 Swap: 4133269504 725725184 3407544320 MemTotal: 8249496 kB MemFree: 18568 kB MemShared: 0 kB Buffers: 500 kB Cached: 21440 kB HighTotal: 7471104 kB HighFree: 0 kB SwapTotal: 4036396 kB SwapFree: 3327680 kB
and output of vmstat 5:
procs memory swap io system cpu r b w swpd free buff cache si so bi bo in cs us sy id 17 3 1 424020 2688 244 25932 407 10280 104 2570 970 1490 0 92 7 20 0 1 461380 1688 240 24464 467 8048 120 2012 758 1188 0 87 13 18 1 1 484676 27728 240 20692 994 5644 250 1411 549 910 0 90 10 19 0 1 497068 2732 260 25700 2690 5055 675 1264 532 1038 0 81 18 11 8 1 529820 4692 272 25192 4232 10643 1063 2661 1191 2126 0 85 15 17 2 1 559572 1472 264 19860 2538 8473 641 2118 919 1653 0 81 19 12 7 1 609780 1944 268 24280 3620 13611 912 3404 1485 2799 0 79 21 15 3 1 648148 1836 272 16648 8061 15666 2025 3916 2227 3731 0 78 22 12 6 1 692208 3044 280 23192 5394 14147 1359 3538 1768 3163 0 75 25 12 5 0 742160 2256 276 38144 6208 16190 1559 4047 1936 3419 0 78 22
So we have very few failes. Probably we never get caught by the second part of the above patch any more.
Quoted 6 lines
-- mingo
ps. some people might ask why we want to swap on an 8GB box, but i think it's really an issue in production systems to provide some kind of 'rubber wall' instead of 'hard concrete' if the system is reaching its limits. adding (99% unused) swap space does exactly this.
Yes we need it for ERP applications. You do not beleive how many data is processed sometimes in business applications.
And to have a hard limit for production servers is always a reason to use something else.
Christoph
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://humbolt.geo.uu.nl/Linux-MM/