All of lore.kernel.org
 help / color / mirror / Atom feed
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(&current->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(&current->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/

             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 ` [Patch] shm cleanups 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.