From: Christoph Rohland <hans-christoph.rohland@sap.com>
To: Linus Torvalds <torvalds@transmeta.com>
Cc: MM mailing list <linux-mm@kvack.org>,
Kanoj Sarcar <kanoj@google.engr.sgi.com>,
Ingo Molnar <mingo@chiara.csoma.elte.hu>
Subject: [Patch] shm cleanups
Date: 03 Nov 1999 22:30:45 +0100 [thread overview]
Message-ID: <qwwwvrzdzzu.fsf@sap.com> (raw)
In-Reply-To: Christoph Rohland's message of "03 Nov 1999 20:17:09 +0100"
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
diff -uNr 2.3.25/arch/i386/kernel/sys_i386.c 2.3.25-shm3/arch/i386/kernel/sys_i386.c
--- 2.3.25/arch/i386/kernel/sys_i386.c Fri Dec 18 01:27:35 1998
+++ 2.3.25-shm3/arch/i386/kernel/sys_i386.c Wed Nov 3 11:28:11 1999
@@ -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;
+ }
}
/*
diff -uNr 2.3.25/include/asm-alpha/shmparam.h 2.3.25-shm3/include/asm-alpha/shmparam.h
--- 2.3.25/include/asm-alpha/shmparam.h Mon Oct 7 14:12:29 1996
+++ 2.3.25-shm3/include/asm-alpha/shmparam.h Wed Nov 3 11:28:11 1999
@@ -1,47 +1,6 @@
#ifndef _ASMAXP_SHMPARAM_H
#define _ASMAXP_SHMPARAM_H
-/*
- * Address range for shared memory attaches if no address passed to shmat().
- */
-#define SHM_RANGE_START 0x14000000000
-#define SHM_RANGE_END 0x15000000000
-
-
-/*
- * 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 Alpha and
- * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
- */
-
-#define SHMMAX 0x3fa000 /* 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 /* _ASMAXP_SHMPARAM_H */
diff -uNr 2.3.25/include/asm-arm/proc-armo/shmparam.h 2.3.25-shm3/include/asm-arm/proc-armo/shmparam.h
--- 2.3.25/include/asm-arm/proc-armo/shmparam.h Wed Jan 21 01:39:42 1998
+++ 2.3.25-shm3/include/asm-arm/proc-armo/shmparam.h Wed Nov 3 11:28:11 1999
@@ -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
diff -uNr 2.3.25/include/asm-arm/proc-armv/shmparam.h 2.3.25-shm3/include/asm-arm/proc-armv/shmparam.h
--- 2.3.25/include/asm-arm/proc-armv/shmparam.h Wed Jan 21 01:39:43 1998
+++ 2.3.25-shm3/include/asm-arm/proc-armv/shmparam.h Wed Nov 3 11:28:11 1999
@@ -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
diff -uNr 2.3.25/include/asm-arm/shmparam.h 2.3.25-shm3/include/asm-arm/shmparam.h
--- 2.3.25/include/asm-arm/shmparam.h Mon Oct 25 09:25:29 1999
+++ 2.3.25-shm3/include/asm-arm/shmparam.h Wed Nov 3 11:28:11 1999
@@ -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 */
diff -uNr 2.3.25/include/asm-i386/shmparam.h 2.3.25-shm3/include/asm-i386/shmparam.h
--- 2.3.25/include/asm-i386/shmparam.h Sun Nov 8 23:06:18 1998
+++ 2.3.25-shm3/include/asm-i386/shmparam.h Wed Nov 3 11:28:11 1999
@@ -1,46 +1,6 @@
#ifndef _ASMI386_SHMPARAM_H
#define _ASMI386_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))
-#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 /* _ASMI386_SHMPARAM_H */
diff -uNr 2.3.25/include/asm-m68k/shmparam.h 2.3.25-shm3/include/asm-m68k/shmparam.h
--- 2.3.25/include/asm-m68k/shmparam.h Mon Oct 18 14:35:02 1999
+++ 2.3.25-shm3/include/asm-m68k/shmparam.h Wed Nov 3 11:28:16 1999
@@ -1,49 +1,6 @@
#ifndef _M68K_SHMPARAM_H
#define _M68K_SHMPARAM_H
-/* address range for shared memory attaches if no address passed to shmat() */
-#ifndef CONFIG_SUN3
-#define SHM_RANGE_START 0xC0000000
-#define SHM_RANGE_END 0xD0000000
-#else
-#define SHM_RANGE_START 0x0C000000
-#define SHM_RANGE_END 0x0D000000
-#endif
-
-/*
- * 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 /* _M68K_SHMPARAM_H */
diff -uNr 2.3.25/include/asm-mips/shmparam.h 2.3.25-shm3/include/asm-mips/shmparam.h
--- 2.3.25/include/asm-mips/shmparam.h Sat Jun 26 02:37:53 1999
+++ 2.3.25-shm3/include/asm-mips/shmparam.h Wed Nov 3 11:28:16 1999
@@ -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 */
diff -uNr 2.3.25/include/asm-ppc/shmparam.h 2.3.25-shm3/include/asm-ppc/shmparam.h
--- 2.3.25/include/asm-ppc/shmparam.h Mon Oct 18 14:35:24 1999
+++ 2.3.25-shm3/include/asm-ppc/shmparam.h Wed Nov 3 11:28:16 1999
@@ -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 */
diff -uNr 2.3.25/include/asm-sh/shmparam.h 2.3.25-shm3/include/asm-sh/shmparam.h
--- 2.3.25/include/asm-sh/shmparam.h Mon Oct 18 14:34:54 1999
+++ 2.3.25-shm3/include/asm-sh/shmparam.h Wed Nov 3 11:28:16 1999
@@ -1,46 +1,6 @@
#ifndef __ASM_SH_SHMPARAM_H
#define __ASM_SH_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))
-#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 /* __ASM_SH_SHMPARAM_H */
diff -uNr 2.3.25/include/asm-sparc/shmparam.h 2.3.25-shm3/include/asm-sparc/shmparam.h
--- 2.3.25/include/asm-sparc/shmparam.h Sun Oct 4 19:22:44 1998
+++ 2.3.25-shm3/include/asm-sparc/shmparam.h Wed Nov 3 11:28:16 1999
@@ -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 */
diff -uNr 2.3.25/include/asm-sparc64/shmparam.h 2.3.25-shm3/include/asm-sparc64/shmparam.h
--- 2.3.25/include/asm-sparc64/shmparam.h Sun Oct 4 19:22:44 1998
+++ 2.3.25-shm3/include/asm-sparc64/shmparam.h Wed Nov 3 11:28:16 1999
@@ -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 */
diff -uNr 2.3.25/include/linux/shm.h 2.3.25-shm3/include/linux/shm.h
--- 2.3.25/include/linux/shm.h Tue Nov 2 12:46:29 1999
+++ 2.3.25-shm3/include/linux/shm.h Wed Nov 3 11:28:16 1999
@@ -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 */
diff -uNr 2.3.25/include/linux/swap.h 2.3.25-shm3/include/linux/swap.h
--- 2.3.25/include/linux/swap.h Wed Nov 3 18:00:50 1999
+++ 2.3.25-shm3/include/linux/swap.h Wed Nov 3 11:55:52 1999
@@ -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
diff -uNr 2.3.25/include/linux/sysctl.h 2.3.25-shm3/include/linux/sysctl.h
--- 2.3.25/include/linux/sysctl.h Thu Oct 28 09:26:49 1999
+++ 2.3.25-shm3/include/linux/sysctl.h Wed Nov 3 19:58:43 1999
@@ -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 */
};
diff -uNr 2.3.25/ipc/shm.c 2.3.25-shm3/ipc/shm.c
--- 2.3.25/ipc/shm.c Tue Nov 2 12:46:29 1999
+++ 2.3.25-shm3/ipc/shm.c Wed Nov 3 11:55:39 1999
@@ -9,6 +9,8 @@
* BIGMEM support, Andrea Arcangeli <andrea@suse.de>
* SMP thread shm, Jean-Luc Boyard <jean-luc.boyard@siemens.fr>
* HIGHMEM support, Ingo Molnar <mingo@redhat.com>
+ * avoid vmalloc and make shmmax, shmall, shmmni sysctl'able,
+ * Christoph Rohland <hans-christoph.rohland@sap.com>
*/
#include <linux/config.h>
@@ -25,7 +27,17 @@
#include <asm/uaccess.h>
#include <asm/pgtable.h>
-extern int ipcperms (struct ipc_perm *ipcp, short shmflg);
+#include "util.h"
+
+struct shmid_kernel /* extend struct shmis_ds with private fields */
+{
+ struct shmid_ds u;
+ unsigned long shm_npages; /* size of segment (pages) */
+ pte_t **shm_dir; /* ptr to array of ptrs to frames -> SHMMAX */
+ struct vm_area_struct *attaches; /* descriptors for attaches */
+ int id; /* backreference to id for shm_close */
+};
+
static int findkey (key_t key);
static int newseg (key_t key, int shmflg, size_t size);
static int shm_map (struct vm_area_struct *shmd);
@@ -38,13 +50,15 @@
static int sysvipc_shm_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data);
#endif
+unsigned int shm_prm[3] = {SHMMAX, SHMALL, SHMMNI};
+
static int shm_tot = 0; /* total number of shared memory pages */
static int shm_rss = 0; /* number of shared memory pages that are in memory */
static int shm_swp = 0; /* number of shared memory pages that are in swap */
-static int max_shmid = 0; /* every used id is <= max_shmid */
+static int max_shmid = -1; /* every used id is <= max_shmid */
static DECLARE_WAIT_QUEUE_HEAD(shm_wait); /* calling findkey() may need to wait */
-static struct shmid_kernel *shm_segs[SHMMNI];
-
+static struct shmid_kernel **shm_segs = NULL;
+static unsigned int num_segs = 0;
static unsigned short shm_seq = 0; /* incremented, for recognizing stale ids */
spinlock_t shm_lock = SPIN_LOCK_UNLOCKED;
@@ -56,22 +70,109 @@
void __init shm_init (void)
{
- int id;
-
- for (id = 0; id < SHMMNI; id++)
- shm_segs[id] = (struct shmid_kernel *) IPC_UNUSED;
- shm_tot = shm_rss = shm_seq = max_shmid = used_segs = 0;
- init_waitqueue_head(&shm_wait);
#ifdef CONFIG_PROC_FS
create_proc_read_entry("sysvipc/shm", 0, 0, sysvipc_shm_read_proc, NULL);
#endif
return;
}
+#define SHM_ENTRY(shp, index) (shp)->shm_dir[(index)/PTRS_PER_PTE][(index)%PTRS_PER_PTE]
+
+static pte_t **shm_alloc(unsigned long pages)
+{
+ unsigned short dir = pages / PTRS_PER_PTE;
+ unsigned short last = pages % PTRS_PER_PTE;
+ pte_t **ret, **ptr;
+
+ ret = kmalloc ((dir+1) * sizeof(unsigned long), GFP_KERNEL);
+ if (ret == NULL)
+ return NULL;
+
+ for (ptr = ret; ptr < ret+dir ; ptr++)
+ {
+ *ptr = (pte_t *)__get_free_page (GFP_KERNEL);
+ if (*ptr == NULL)
+ goto free;
+ memset (*ptr, 0, PAGE_SIZE);
+ }
+
+ /* The last one is probably not of PAGE_SIZE: we use kmalloc */
+ if (last) {
+ *ptr = kmalloc (last*sizeof(pte_t *), GFP_KERNEL);
+ if (*ptr == NULL)
+ goto free;
+ memset (*ptr, 0, last*sizeof(pte_t *));
+ }
+
+ return ret;
+
+free:
+ /* The last failed: we decrement first */
+ while (--ptr >= ret)
+ free_page ((unsigned long)*ptr);
+
+ kfree (ret);
+ return NULL;
+}
+
+
+static void shm_free(pte_t** dir, unsigned long pages)
+{
+ pte_t **ptr = dir+pages/PTRS_PER_PTE;
+
+ /* first the last page */
+ if (pages%PTRS_PER_PTE)
+ kfree (*ptr);
+ /* now the whole pages */
+ while (--ptr >= dir)
+ free_page ((unsigned long)*ptr);
+
+ /* Now the indirect block */
+ kfree (dir);
+}
+
+static int shm_expand (unsigned int size)
+{
+ int id;
+ struct shmid_kernel ** new_array;
+
+ spin_unlock(&shm_lock);
+ new_array = kmalloc (size * sizeof(struct shmid_kernel *), GFP_KERNEL);
+ spin_lock(&shm_lock);
+
+ if (!new_array)
+ return -ENOMEM;
+
+ if (size <= num_segs){ /* We check this after kmalloc so
+ nobody changes num_segs afterwards */
+ /*
+ * We never shrink the segment. If we shrink we have to
+ * check for stale handles in newseg
+ */
+ kfree (new_array);
+ return 0;
+ }
+
+ if (num_segs) {
+ memcpy (new_array, shm_segs,
+ size*sizeof(struct shmid_kernel *));
+ kfree (shm_segs);
+ }
+ for (id = num_segs; id < size; id++)
+ new_array[id] = (void *) IPC_UNUSED;
+
+ shm_segs = new_array;
+ num_segs = size;
+ return 0;
+}
+
static int findkey (key_t key)
{
int id;
struct shmid_kernel *shp;
+
+ if (!num_segs)
+ return -1;
for (id = 0; id <= max_shmid; id++) {
if ((shp = shm_segs[id]) == IPC_NOID) {
@@ -89,9 +190,8 @@
__set_current_state(TASK_RUNNING);
remove_wait_queue(&shm_wait, &wait);
}
- if (shp == IPC_UNUSED)
- continue;
- if (key == shp->u.shm_perm.key)
+ if (shp != IPC_UNUSED &&
+ key == shp->u.shm_perm.key)
return id;
}
return -1;
@@ -99,18 +199,33 @@
/*
* allocate new shmid_kernel and pgtable. protected by shm_segs[id] = NOID.
+ * This has to be called with the shm_lock held
*/
static int newseg (key_t key, int shmflg, size_t size)
{
struct shmid_kernel *shp;
int numpages = (size + PAGE_SIZE -1) >> PAGE_SHIFT;
- int id;
+ int id, err;
+ unsigned int shmall, shmmni;
+ lock_kernel();
+ shmall = shm_prm[1];
+ shmmni = shm_prm[2];
+ if (shmmni > IPCMNI) {
+ printk ("shmmni reset to max of %u\n", IPCMNI);
+ shmmni = shm_prm[2] = IPCMNI;
+ }
+ unlock_kernel();
+
+ if (shmmni < used_segs)
+ return -ENOSPC;
+ if ((err = shm_expand (shmmni)))
+ return err;
if (size < SHMMIN)
return -EINVAL;
- if (shm_tot + numpages >= SHMALL)
+ if (shm_tot + numpages >= shmall)
return -ENOSPC;
- for (id = 0; id < SHMMNI; id++)
+ for (id = 0; id < num_segs; id++)
if (shm_segs[id] == IPC_UNUSED) {
shm_segs[id] = (struct shmid_kernel *) IPC_NOID;
goto found;
@@ -126,10 +241,8 @@
wake_up (&shm_wait);
return -ENOMEM;
}
- lock_kernel();
- shp->shm_pages = (pte_t *) vmalloc (numpages*sizeof(pte_t));
- unlock_kernel();
- if (!shp->shm_pages) {
+ shp->shm_dir = shm_alloc (numpages);
+ if (!shp->shm_dir) {
kfree(shp);
spin_lock(&shm_lock);
shm_segs[id] = (struct shmid_kernel *) IPC_UNUSED;
@@ -137,8 +250,6 @@
return -ENOMEM;
}
- memset(shp->shm_pages, 0, numpages*sizeof(pte_t));
-
shp->u.shm_perm.key = key;
shp->u.shm_perm.mode = (shmflg & S_IRWXUGO);
shp->u.shm_perm.cuid = shp->u.shm_perm.uid = current->euid;
@@ -150,6 +261,7 @@
shp->u.shm_atime = shp->u.shm_dtime = 0;
shp->u.shm_ctime = CURRENT_TIME;
shp->shm_npages = numpages;
+ shp->id = id;
spin_lock(&shm_lock);
@@ -161,21 +273,25 @@
shm_segs[id] = shp;
used_segs++;
wake_up (&shm_wait);
- return (unsigned int) shp->u.shm_perm.seq * SHMMNI + id;
+ return (unsigned int) shp->u.shm_perm.seq * IPCMNI + id;
}
-size_t shmmax = SHMMAX;
-
asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
{
struct shmid_kernel *shp;
int err, id = 0;
+ size_t shmmax;
+
+ lock_kernel();
+ shmmax = shm_prm[0];
+ unlock_kernel();
+
+ if (size > shmmax)
+ return -EINVAL;
down(¤t->mm->mmap_sem);
spin_lock(&shm_lock);
- if (size > shmmax) {
- err = -EINVAL;
- } else if (key == IPC_PRIVATE) {
+ if (key == IPC_PRIVATE) {
err = newseg(key, shmflg, size);
} else if ((id = findkey (key)) == -1) {
if (!(shmflg & IPC_CREAT))
@@ -193,7 +309,7 @@
else if (ipcperms (&shp->u.shm_perm, shmflg))
err = -EACCES;
else
- err = (int) shp->u.shm_perm.seq * SHMMNI + id;
+ err = (int) shp->u.shm_perm.seq * IPCMNI + id;
}
spin_unlock(&shm_lock);
up(¤t->mm->mmap_sem);
@@ -214,18 +330,18 @@
if (shp == IPC_NOID || shp == IPC_UNUSED)
BUG();
shp->u.shm_perm.seq++; /* for shmat */
- shm_seq = (shm_seq+1) % ((unsigned)(1<<31)/SHMMNI); /* increment, but avoid overflow */
+ shm_seq = (shm_seq+1) % ((unsigned)(1<<31)/IPCMNI); /* increment, but avoid overflow */
shm_segs[id] = (struct shmid_kernel *) IPC_UNUSED;
used_segs--;
if (id == max_shmid)
- while (max_shmid && (shm_segs[--max_shmid] == IPC_UNUSED));
- if (!shp->shm_pages)
- BUG();
+ while (max_shmid-- > 0 && (shm_segs[max_shmid] == IPC_UNUSED));
+ if (!shp->shm_dir)
+ BUG();
spin_unlock(&shm_lock);
numpages = shp->shm_npages;
for (i = 0, rss = 0, swp = 0; i < numpages ; i++) {
pte_t pte;
- pte = shp->shm_pages[i];
+ pte = SHM_ENTRY (shp,i);
if (pte_none(pte))
continue;
if (pte_present(pte)) {
@@ -238,9 +354,7 @@
swp++;
}
}
- lock_kernel();
- vfree(shp->shm_pages);
- unlock_kernel();
+ shm_free (shp->shm_dir, numpages);
kfree(shp);
spin_lock(&shm_lock);
shm_rss -= rss;
@@ -269,19 +383,20 @@
case IPC_INFO:
{
struct shminfo shminfo;
+ spin_unlock(&shm_lock);
err = -EFAULT;
if (!buf)
goto out;
- shminfo.shmmni = SHMMNI;
- shminfo.shmmax = shmmax;
+ lock_kernel();
+ shminfo.shmmni = shminfo.shmseg = shm_prm[2];
+ shminfo.shmmax = shm_prm[0];
+ shminfo.shmall = shm_prm[1];
+ unlock_kernel();
shminfo.shmmin = SHMMIN;
- shminfo.shmall = SHMALL;
- shminfo.shmseg = SHMSEG;
- spin_unlock(&shm_lock);
if(copy_to_user (buf, &shminfo, sizeof(struct shminfo)))
goto out_unlocked;
spin_lock(&shm_lock);
- err = max_shmid;
+ err = max_shmid < 0 ? 0 : max_shmid;
goto out;
}
case SHM_INFO:
@@ -298,7 +413,7 @@
if(copy_to_user (buf, &shm_info, sizeof(shm_info)))
goto out_unlocked;
spin_lock(&shm_lock);
- err = max_shmid;
+ err = max_shmid < 0 ? 0 : max_shmid;
goto out;
}
case SHM_STAT:
@@ -310,7 +425,7 @@
goto out;
if (ipcperms (&shp->u.shm_perm, S_IRUGO))
goto out;
- id = (unsigned int) shp->u.shm_perm.seq * SHMMNI + shmid;
+ id = (unsigned int) shp->u.shm_perm.seq * IPCMNI + shmid;
err = -EFAULT;
spin_unlock(&shm_lock);
if(copy_to_user (buf, &shp->u, sizeof(*buf)))
@@ -320,12 +435,13 @@
goto out;
}
- shp = shm_segs[id = (unsigned int) shmid % SHMMNI];
err = -EINVAL;
- if (shp == IPC_UNUSED || shp == IPC_NOID)
+ if ((id = (unsigned int) shmid % IPCMNI) > max_shmid)
+ goto out;
+ if ((shp = shm_segs[id]) == IPC_UNUSED || shp == IPC_NOID)
goto out;
err = -EIDRM;
- if (shp->u.shm_perm.seq != (unsigned int) shmid / SHMMNI)
+ if (shp->u.shm_perm.seq != (unsigned int) shmid / IPCMNI)
goto out;
ipcp = &shp->u.shm_perm;
@@ -480,7 +596,7 @@
if (shmid < 0)
goto out;
- shp = shm_segs[id = (unsigned int) shmid % SHMMNI];
+ shp = shm_segs[id = (unsigned int) shmid % IPCMNI];
if (shp == IPC_UNUSED || shp == IPC_NOID)
goto out;
@@ -523,7 +639,7 @@
if (ipcperms(&shp->u.shm_perm, shmflg & SHM_RDONLY ? S_IRUGO : S_IRUGO|S_IWUGO))
goto out;
err = -EIDRM;
- if (shp->u.shm_perm.seq != (unsigned int) shmid / SHMMNI)
+ if (shp->u.shm_perm.seq != (unsigned int) shmid / IPCMNI)
goto out;
spin_unlock(&shm_lock);
@@ -532,13 +648,13 @@
spin_lock(&shm_lock);
if (!shmd)
goto out;
- if ((shp != shm_segs[id]) || (shp->u.shm_perm.seq != (unsigned int) shmid / SHMMNI)) {
+ if ((shp != shm_segs[id]) || (shp->u.shm_perm.seq != (unsigned int) shmid / IPCMNI)) {
kmem_cache_free(vm_area_cachep, shmd);
err = -EIDRM;
goto out;
}
- shmd->vm_private_data = shm_segs + id;
+ shmd->vm_private_data = shm_segs[id];
shmd->vm_start = addr;
shmd->vm_end = addr + shp->shm_npages * PAGE_SIZE;
shmd->vm_mm = current->mm;
@@ -584,7 +700,7 @@
struct shmid_kernel *shp;
spin_lock(&shm_lock);
- shp = *(struct shmid_kernel **) shmd->vm_private_data;
+ shp = (struct shmid_kernel *) shmd->vm_private_data;
insert_attach(shp,shmd); /* insert shmd into shp->attaches */
shp->u.shm_nattch++;
shp->u.shm_atime = CURRENT_TIME;
@@ -604,14 +720,12 @@
spin_lock(&shm_lock);
/* remove from the list of attaches of the shm segment */
- shp = *(struct shmid_kernel **) shmd->vm_private_data;
+ shp = (struct shmid_kernel *) shmd->vm_private_data;
remove_attach(shp,shmd); /* remove from shp->attaches */
shp->u.shm_lpid = current->pid;
shp->u.shm_dtime = CURRENT_TIME;
- if (--shp->u.shm_nattch <= 0 && shp->u.shm_perm.mode & SHM_DEST) {
- unsigned int id = (struct shmid_kernel **)shmd->vm_private_data - shm_segs;
- killseg (id);
- }
+ if (--shp->u.shm_nattch <= 0 && shp->u.shm_perm.mode & SHM_DEST)
+ killseg (shp->id);
spin_unlock(&shm_lock);
}
@@ -648,7 +762,7 @@
}
/*
- * page not present ... go through shm_pages
+ * page not present ... go through shm_dir
*/
static struct page * shm_nopage(struct vm_area_struct * shmd, unsigned long address, int no_share)
{
@@ -657,13 +771,13 @@
unsigned int idx;
struct page * page;
- shp = *(struct shmid_kernel **) shmd->vm_private_data;
+ shp = (struct shmid_kernel *) shmd->vm_private_data;
idx = (address - shmd->vm_start) >> PAGE_SHIFT;
idx += shmd->vm_pgoff;
spin_lock(&shm_lock);
again:
- pte = shp->shm_pages[idx];
+ pte = SHM_ENTRY(shp,idx);
if (!pte_present(pte)) {
if (pte_none(pte)) {
spin_unlock(&shm_lock);
@@ -672,7 +786,7 @@
goto oom;
clear_highpage(page);
spin_lock(&shm_lock);
- if (pte_val(pte) != pte_val(shp->shm_pages[idx]))
+ if (pte_val(pte) != pte_val(SHM_ENTRY(shp, idx)))
goto changed;
} else {
swp_entry_t entry = pte_to_swp_entry(pte);
@@ -694,18 +808,18 @@
unlock_kernel();
spin_lock(&shm_lock);
shm_swp--;
- pte = shp->shm_pages[idx];
+ pte = SHM_ENTRY(shp, idx);
if (pte_present(pte))
goto present;
}
shm_rss++;
pte = pte_mkdirty(mk_pte(page, PAGE_SHARED));
- shp->shm_pages[idx] = pte;
+ SHM_ENTRY(shp, idx) = pte;
} else
--current->maj_flt; /* was incremented in do_no_page */
done:
- /* pte_val(pte) == shp->shm_pages[idx] */
+ /* pte_val(pte) == SHM_ENTRY (shp, idx) */
get_page(pte_page(pte));
spin_unlock(&shm_lock);
current->min_flt++;
@@ -770,7 +884,7 @@
if (idx >= shp->shm_npages)
goto next_id;
- page = shp->shm_pages[idx];
+ page = SHM_ENTRY(shp, idx);
if (!pte_present(page))
goto check_table;
page_map = pte_page(page);
@@ -792,7 +906,7 @@
goto check_table;
if (!(page_map = prepare_highmem_swapout(page_map)))
goto check_table;
- shp->shm_pages[idx] = swp_entry_to_pte(swap_entry);
+ SHM_ENTRY (shp, idx) = swp_entry_to_pte(swap_entry);
swap_successes++;
shm_swp++;
shm_rss--;
@@ -812,12 +926,12 @@
* Free the swap entry and set the new pte for the shm page.
*/
static void shm_unuse_page(struct shmid_kernel *shp, unsigned long idx,
- swp_entry_t entry, struct page *page)
+ swp_entry_t entry, struct page *page)
{
pte_t pte;
pte = pte_mkdirty(mk_pte(page, PAGE_SHARED));
- shp->shm_pages[idx] = pte;
+ SHM_ENTRY(shp, idx) = pte;
get_page(page);
shm_rss++;
@@ -837,16 +951,16 @@
int i, n;
spin_lock(&shm_lock);
- for (i = 0; i < SHMMNI; i++) {
+ for (i = 0; i <= max_shmid; i++) {
struct shmid_kernel *seg = shm_segs[i];
if ((seg == IPC_UNUSED) || (seg == IPC_NOID))
continue;
for (n = 0; n < seg->shm_npages; n++) {
- if (pte_none(seg->shm_pages[n]))
+ if (pte_none(SHM_ENTRY(seg,n)))
continue;
- if (pte_present(seg->shm_pages[n]))
+ if (pte_present(SHM_ENTRY(seg,n)))
continue;
- if (pte_to_swp_entry(seg->shm_pages[n]).val == entry.val) {
+ if (pte_to_swp_entry(SHM_ENTRY(seg,n)).val == entry.val) {
shm_unuse_page(seg, n, entry, page);
return;
}
@@ -865,7 +979,7 @@
len += sprintf(buffer, " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime\n");
spin_lock(&shm_lock);
- for(i = 0; i < SHMMNI; i++)
+ for(i = 0; i <= max_shmid; i++)
if(shm_segs[i] != IPC_UNUSED) {
#define SMALL_STRING "%10d %10d %4o %10u %5u %5u %5d %5u %5u %5u %5u %10lu %10lu %10lu\n"
#define BIG_STRING "%10d %10d %4o %21u %5u %5u %5d %5u %5u %5u %5u %10lu %10lu %10lu\n"
@@ -877,7 +991,7 @@
format = BIG_STRING;
len += sprintf(buffer + len, format,
shm_segs[i]->u.shm_perm.key,
- shm_segs[i]->u.shm_perm.seq * SHMMNI + i,
+ shm_segs[i]->u.shm_perm.seq * IPCMNI + i,
shm_segs[i]->u.shm_perm.mode,
shm_segs[i]->u.shm_segsz,
shm_segs[i]->u.shm_cpid,
diff -uNr 2.3.25/ipc/util.c 2.3.25-shm3/ipc/util.c
--- 2.3.25/ipc/util.c Tue Nov 2 12:46:29 1999
+++ 2.3.25-shm3/ipc/util.c Wed Nov 3 20:04:41 1999
@@ -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);
diff -uNr 2.3.25/ipc/util.h 2.3.25-shm3/ipc/util.h
--- 2.3.25/ipc/util.h Thu Jan 1 01:00:00 1970
+++ 2.3.25-shm3/ipc/util.h Wed Nov 3 11:28:16 1999
@@ -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);
diff -uNr 2.3.25/kernel/sysctl.c 2.3.25-shm3/kernel/sysctl.c
--- 2.3.25/kernel/sysctl.c Tue Nov 2 12:46:29 1999
+++ 2.3.25-shm3/kernel/sysctl.c Wed Nov 3 11:32:02 1999
@@ -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
diff -uNr 2.3.25/mm/swap_state.c 2.3.25-shm3/mm/swap_state.c
--- 2.3.25/mm/swap_state.c Tue Nov 2 12:46:29 1999
+++ 2.3.25-shm3/mm/swap_state.c Wed Nov 3 11:28:16 1999
@@ -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;
diff -uNr 2.3.25/mm/swapfile.c 2.3.25-shm3/mm/swapfile.c
--- 2.3.25/mm/swapfile.c Tue Nov 2 12:46:29 1999
+++ 2.3.25-shm3/mm/swapfile.c Wed Nov 3 11:28:16 1999
@@ -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 majordomo@kvack.org. For more info on Linux MM,
see: http://humbolt.geo.uu.nl/Linux-MM/
next reply other threads:[~1999-11-03 21:30 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
1999-11-03 21:30 Christoph Rohland [this message]
1999-11-04 8:10 ` Ingo Molnar
1999-11-04 12:40 ` Christoph Rohland
1999-11-04 17:58 ` Ingo Molnar
1999-11-04 19:02 ` Rik van Riel
1999-11-04 22:30 ` Ingo Molnar
1999-11-05 0:14 ` Andrea Arcangeli
1999-11-05 12:35 ` Christoph Rohland
1999-11-05 13:18 ` Andrea Arcangeli
1999-11-05 16:16 ` Christoph Rohland
1999-11-05 16:21 ` Andrea Arcangeli
1999-11-05 16:28 ` Christoph Rohland
1999-11-05 10:36 ` Christoph Rohland
-- strict thread matches above, loose matches on Subject: below --
1999-11-03 19:17 Christoph Rohland
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=qwwwvrzdzzu.fsf@sap.com \
--to=hans-christoph.rohland@sap.com \
--cc=kanoj@google.engr.sgi.com \
--cc=linux-mm@kvack.org \
--cc=mingo@chiara.csoma.elte.hu \
--cc=torvalds@transmeta.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox