Skip to contentSkip to conversation

kanoj-mm21-2.3.23 alow larger sizes to shmget()

PATCH In review Kanoj Sarcar 10 participants 56 messages Oct 28, 1999 – Mar 27, 2000 2 messages not in the archive

Subsystems (6)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 kanoj-mm21-2.3.23 alow larger sizes to shmget()

Linus,

Per our previous discussion, this is the patch to change the shmget() api to permit larger shm segments (now that larger user address spaces, as well as large memory machines are possible).

Note that I have defined shmget() as
shmget(key_t, size_t, int)
instead of as
shmget(key_t, unsigned int, int)
or as
shmget(key_t, unsigned long, int).

This is because the single unix spec sets down the first definition
(http://www.opengroup.org/onlinepubs/007908799/xsh/shmget.html).
This becomes interesting, because size_t is of different sizes on different architectures, so the shmfs code has to do careful formatting. (This logic is also probably needed in the ipcs command).

Let me know if the patch looks okay.

Thanks.

Kanoj

linux/shm.h renamed from usr/tmp/p_rdiff_a002SA/shm.h +3 -3
@@ -7,7 +7,7 @@
 
 struct shmid_ds {
 	struct ipc_perm		shm_perm;	/* operation perms */
-	int			shm_segsz;	/* size of segment (bytes) */
+	size_t			shm_segsz;	/* size of segment (bytes) */
 	__kernel_time_t		shm_atime;	/* last attach time */
 	__kernel_time_t		shm_dtime;	/* last detach time */
 	__kernel_time_t		shm_ctime;	/* last change time */
@@ -46,7 +46,7 @@
 #define SHM_INFO 	14
 
 struct	shminfo {
-	int shmmax;
+	size_t shmmax;
 	int shmmin;
 	int shmmni;
 	int shmseg;
@@ -68,7 +68,7 @@
 #define	SHM_DEST	01000	/* segment will be destroyed on last detach */
 #define SHM_LOCKED      02000   /* segment will not be swapped */
 
-asmlinkage long sys_shmget (key_t key, int size, int flag);
+asmlinkage long sys_shmget (key_t key, size_t size, int flag);
 asmlinkage long sys_shmat (int shmid, char *shmaddr, int shmflg, unsigned long *addr);
 asmlinkage long sys_shmdt (char *shmaddr);
 asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds *buf);
shm.c renamed from usr/tmp/p_rdiff_a002SJ/shm.c +16 -8
@@ -27,7 +27,7 @@
 
 extern int ipcperms (struct ipc_perm *ipcp, short shmflg);
 static int findkey (key_t key);
-static int newseg (key_t key, int shmflg, int size);
+static int newseg (key_t key, int shmflg, size_t size);
 static int shm_map (struct vm_area_struct *shmd);
 static void killseg (int id);
 static void shm_open (struct vm_area_struct *shmd);
@@ -104,7 +104,7 @@
 /*
  * allocate new shmid_kernel and pgtable. protected by shm_segs[id] = NOID.
  */
-static int newseg (key_t key, int shmflg, int size)
+static int newseg (key_t key, int shmflg, size_t size)
 {
 	struct shmid_kernel *shp;
 	int numpages = (size + PAGE_SIZE -1) >> PAGE_SHIFT;
@@ -168,9 +168,9 @@
 	return (unsigned int) shp->u.shm_perm.seq * SHMMNI + id;
 }
 
-int shmmax = SHMMAX;
+size_t shmmax = SHMMAX;
 
-asmlinkage long sys_shmget (key_t key, int size, int shmflg)
+asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
 {
 	struct shmid_kernel *shp;
 	int err, id = 0;
@@ -177,7 +177,7 @@
 
 	down(&current->mm->mmap_sem);
 	spin_lock(&shm_lock);
-	if (size < 0 || size > shmmax) {
+	if (size > shmmax) {
 		err = -EINVAL;
 	} else if (key == IPC_PRIVATE) {
 		err = newseg(key, shmflg, size);
@@ -494,7 +494,7 @@
 		err = -ENOMEM;
 		addr = 0;
 	again:
-		if (!(addr = get_unmapped_area(addr, shp->u.shm_segsz)))
+		if (!(addr = get_unmapped_area(addr, (unsigned long)shp->u.shm_segsz)))
 			goto out;
 		if(addr & (SHMLBA - 1)) {
 			addr = (addr + (SHMLBA - 1)) & ~(SHMLBA - 1);
@@ -520,7 +520,7 @@
 	if (addr < current->mm->start_stack &&
 	    addr > current->mm->start_stack - PAGE_SIZE*(shp->shm_npages + 4))
 		goto out;
-	if (!(shmflg & SHM_REMAP) && find_vma_intersection(current->mm, addr, addr + shp->u.shm_segsz))
+	if (!(shmflg & SHM_REMAP) && find_vma_intersection(current->mm, addr, addr + (unsigned long)shp->u.shm_segsz))
 		goto out;
 
 	err = -EACCES;
@@ -863,7 +863,15 @@
 	spin_lock(&shm_lock);
     	for(i = 0; i < SHMMNI; i++)
 		if(shm_segs[i] != IPC_UNUSED) {
-	    		len += sprintf(buffer + len, "%10d %10d  %4o %10d %5u %5u  %5d %5u %5u %5u %5u %10lu %10lu %10lu\n",
+#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"
+			char *format;
+
+			if (sizeof(size_t) <= sizeof(int))
+				format = SMALL_STRING;
+			else
+				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.mode,
sysctl.c renamed from usr/tmp/p_rdiff_a002SS/sysctl.c +3 -3
@@ -49,7 +49,7 @@
 extern int sg_big_buff;
 #endif
 #ifdef CONFIG_SYSVIPC
-extern int shmmax;
+extern size_t shmmax;
 #endif
 
 #ifdef __sparc__
@@ -213,8 +213,8 @@
 	{KERN_RTSIGMAX, "rtsig-max", &max_queued_signals, sizeof(int),
 	 0644, NULL, &proc_dointvec},
 #ifdef CONFIG_SYSVIPC
-	{KERN_SHMMAX, "shmmax", &shmmax, sizeof (int),
-	 0644, NULL, &proc_dointvec},
+	{KERN_SHMMAX, "shmmax", &shmmax, sizeof (size_t),
+	 0644, NULL, &proc_doulongvec_minmax},
 #endif
 #ifdef CONFIG_MAGIC_SYSRQ
 	{KERN_SYSRQ, "sysrq", &sysrq_enabled, sizeof (int),

--
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/

A message that is not in the archive (sent off-list or not yet received): [email protected]'s

#2 lore raw

Hi Kanoj,

This is probably breaking user space applications since shmid_ds is shared with user space in shmctl(2). On 32bit machines this does not matter, since sizeof(int) == sizeof(size_t), but on 64bit this will break.

How do we handle this?

Greetings
Christoph

Quoted 19 lines · [email protected] (Kanoj Sarcar) writes:

Linus,

Per our previous discussion, this is the patch to change the shmget() api to permit larger shm segments (now that larger user address spaces, as well as large memory machines are possible).

Note that I have defined shmget() as
shmget(key_t, size_t, int)
instead of as
shmget(key_t, unsigned int, int)
or as
shmget(key_t, unsigned long, int).

This is because the single unix spec sets down the first definition
(http://www.opengroup.org/onlinepubs/007908799/xsh/shmget.html).
This becomes interesting, because size_t is of different sizes on different architectures, so the shmfs code has to do careful formatting. (This logic is also probably needed in the ipcs command).

Quoted 5 lines

Let me know if the patch looks okay.

Thanks.

Kanoj

--
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/

#3 lore raw
Quoted 9 lines

Hi Kanoj,

This is probably breaking user space applications since shmid_ds is shared with user space in shmctl(2). On 32bit machines this does not matter, since sizeof(int) == sizeof(size_t), but on 64bit this will break.

How do we handle this?

Unfortunately, I don't think we can prevent this 64bit ABI breakage, if we want to conform to the single unix spec on those platforms. Its probably a good idea to have the ia64 port be SUS compliant, even though sparc64/alpha are currently not.

If it is really important to preserve the 64bit ABI, there's one more
alternative: preserve the shmget() api/abi on the old 64bit platforms, but be compliant on the 32 bit ones and newer 64 bit ones (mips64/ia64). This is not the cleanest solution, but can be done with a little header file reorganization in include/linux/shm.h and include/linux/shmparam.h.

Linus has put this patch into pre-25, lets talk if it is important to do the above ... it shouldn't take me more than a couple of hours to do it, if we so decided.

Thanks.

Kanoj

Quoted 31 lines

Greetings
Christoph

Quoted 24 lines · [email protected] (Kanoj Sarcar) writes:

Linus,

Per our previous discussion, this is the patch to change the shmget() api to permit larger shm segments (now that larger user address spaces, as well as large memory machines are possible).

Note that I have defined shmget() as
shmget(key_t, size_t, int)
instead of as
shmget(key_t, unsigned int, int)
or as
shmget(key_t, unsigned long, int).

This is because the single unix spec sets down the first definition
(http://www.opengroup.org/onlinepubs/007908799/xsh/shmget.html).
This becomes interesting, because size_t is of different sizes on different architectures, so the shmfs code has to do careful formatting. (This logic is also probably needed in the ipcs command).

Let me know if the patch looks okay.

Thanks.

Kanoj

--
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/

#4 lore raw
In reply to a message not in the archive
Quoted 21 lines · [email protected] (Kanoj Sarcar) writes:
Quoted 9 lines

Hi Kanoj,

This is probably breaking user space applications since shmid_ds is shared with user space in shmctl(2). On 32bit machines this does not matter, since sizeof(int) == sizeof(size_t), but on 64bit this will break.

How do we handle this?

Unfortunately, I don't think we can prevent this 64bit ABI breakage, if we want to conform to the single unix spec on those platforms. Its probably a good idea to have the ia64 port be SUS compliant, even though sparc64/alpha are currently not.

If it is really important to preserve the 64bit ABI, there's one more
alternative: preserve the shmget() api/abi on the old 64bit platforms, but be compliant on the 32 bit ones and newer 64 bit ones (mips64/ia64). This is not the cleanest solution, but can be done with a little header file reorganization in include/linux/shm.h and include/linux/shmparam.h.

Quoted 3 lines

Linus has put this patch into pre-25, lets talk if it is important to do the above ... it shouldn't take me more than a couple of hours to do it, if we so decided.

Since glibc is encapsulating these calls and headers, we could perhaps work with compatibility version. E.g. making shmget and shmctl a real system call and converting the structures in sys_ipc to the old ones for old libraries?

BTW I did some work to make the clean up the shm coding and make the limites sysctleable. It also avoids vmalloc for the page tables. The latter is really important for big servers. We run out of vm-space on some benchmarks. I appended the patch against 2.3.24. I could not finally test this patch since shm swapping has apparently a race condition on segment deletion introduced with the smp version. I am still investigating on that. But perhaps we could incorporate this patch anyways. It did survive stress testing shm-swapping as long as I do not remove segments.

Greetings
Christoph

--Multipart_Tue_Nov__2_10:54:18_1999-1
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="patch-24-shm1"
Content-Transfer-Encoding: 7bit

arch/i386/kernel/sys_i386.c +64 -79
diff -uNr 2.3.24/arch/i386/kernel/sys_i386.c 2.3.24-shm1/arch/i386/kernel/sys_i386.c
@@ -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
diff -uNr 2.3.24/include/asm-arm/proc-armo/shmparam.h 2.3.24-shm1/include/asm-arm/proc-armo/shmparam.h
@@ -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
diff -uNr 2.3.24/include/asm-arm/proc-armv/shmparam.h 2.3.24-shm1/include/asm-arm/proc-armv/shmparam.h
@@ -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
diff -uNr 2.3.24/include/asm-arm/shmparam.h 2.3.24-shm1/include/asm-arm/shmparam.h
@@ -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-i386/softirq.h +0 -1
diff -uNr 2.3.24/include/asm-i386/softirq.h 2.3.24-shm1/include/asm-i386/softirq.h
@@ -3,7 +3,6 @@
 
 #include <asm/atomic.h>
 #include <asm/hardirq.h>
-#include <linux/spinlock.h>
 
 extern unsigned int local_bh_count[NR_CPUS];
 
include/asm-m68k/shm.h +0 -1
diff -uNr 2.3.24/include/asm-m68k/shm.h 2.3.24-shm1/include/asm-m68k/shm.h
@@ -4,7 +4,6 @@
 /* format of page table entries that correspond to shared memory pages
    currently out in swap space (see also mm/swap.c):
    bits 0-1 (PAGE_PRESENT) is  = 0
-   bits 8..2 (SWP_TYPE) are = SHM_SWP_TYPE
    bits 31..9 are used like this:
    bits 15..9 (SHM_ID) the id of the shared memory segment
    bits 30..16 (SHM_IDX) the index of the page within the shared memory segment
include/asm-m68k/shmparam.h +1 -44

50 lines not on this page · raw message

include/asm-mips/shmparam.h +0 -40
diff -uNr 2.3.24/include/asm-mips/shmparam.h 2.3.24-shm1/include/asm-mips/shmparam.h
@@ -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
diff -uNr 2.3.24/include/asm-ppc/shmparam.h 2.3.24-shm1/include/asm-ppc/shmparam.h
@@ -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
diff -uNr 2.3.24/include/asm-sparc/shmparam.h 2.3.24-shm1/include/asm-sparc/shmparam.h
@@ -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
diff -uNr 2.3.24/include/asm-sparc64/shmparam.h 2.3.24-shm1/include/asm-sparc64/shmparam.h
@@ -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
diff -uNr 2.3.24/include/linux/shm.h 2.3.24-shm1/include/linux/shm.h
@@ -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
diff -uNr 2.3.24/include/linux/swap.h 2.3.24-shm1/include/linux/swap.h
@@ -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 -1
diff -uNr 2.3.24/include/linux/sysctl.h 2.3.24-shm1/include/linux/sysctl.h
@@ -104,7 +104,7 @@
 	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_SEMMAX=41,		/* int: limits for semaphores */
 };
 
 
ipc/shm.c +192 -72

549 lines not on this page · raw message

ipc/util.c +3 -0
diff -uNr 2.3.24/ipc/util.c 2.3.24-shm1/ipc/util.c
@@ -13,6 +13,9 @@
 #include <linux/shm.h>
 #include <linux/init.h>
 #include <linux/msg.h>
+#include <linux/malloc.h>
+
+#include "util.h"
 
 #if defined(CONFIG_SYSVIPC)
 
ipc/util.h +12 -0
diff -uNr 2.3.24/ipc/util.h 2.3.24-shm1/ipc/util.h
@@ -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 +3 -3
diff -uNr 2.3.24/kernel/sysctl.c 2.3.24-shm1/kernel/sysctl.c
@@ -49,7 +49,7 @@
 extern int sg_big_buff;
 #endif
 #ifdef CONFIG_SYSVIPC
-extern int shmmax;
+extern int shm_prm[];
 #endif
 
 #ifdef __sparc__
@@ -213,8 +213,8 @@
 	{KERN_RTSIGMAX, "rtsig-max", &max_queued_signals, sizeof(int),
 	 0644, NULL, &proc_dointvec},
 #ifdef CONFIG_SYSVIPC
-	{KERN_SHMMAX, "shmmax", &shmmax, sizeof (int),
-	 0644, NULL, &proc_dointvec},
+	{KERN_SHMMAX, "shmmax", &shm_prm, 3*sizeof(unsigned int),
+         0644, NULL, &proc_dointvec},
 #endif
 #ifdef CONFIG_MAGIC_SYSRQ
 	{KERN_SYSRQ, "sysrq", &sysrq_enabled, sizeof (int),
mm/swap_state.c +0 -4
diff -uNr 2.3.24/mm/swap_state.c 2.3.24-shm1/mm/swap_state.c
@@ -67,8 +67,6 @@
 	if (!pte_val(entry))
 		goto out;
 	type = SWP_TYPE(entry);
-	if (type & SHM_SWP_TYPE)
-		goto out;
 	if (type >= nr_swapfiles)
 		goto bad_file;
 	p = type + swap_info;
@@ -113,8 +111,6 @@
 	if (!pte_val(entry))
 		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
diff -uNr 2.3.24/mm/swapfile.c 2.3.24-shm1/mm/swapfile.c
@@ -134,8 +134,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];
@@ -189,8 +187,6 @@
 		goto new_swap_entry;
 	entry = get_pagecache_pte(page);
 	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;

--Multipart_Tue_Nov__2_10:54:18_1999-1--
--
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/

#5 lore raw
Quoted 6 lines

Since glibc is encapsulating these calls and headers, we could perhaps work with compatibility version. E.g. making shmget and shmctl a real system call and converting the structures in sys_ipc to the old ones for old libraries?

Quoted 10 lines

BTW I did some work to make the clean up the shm coding and make the limites sysctleable. It also avoids vmalloc for the page tables. The latter is really important for big servers. We run out of vm-space on some benchmarks. I appended the patch against 2.3.24. I could not finally test this patch since shm swapping has apparently a race condition on segment deletion introduced with the smp version. I am still investigating on that. But perhaps we could incorporate this patch anyways. It did survive stress testing shm-swapping as long as I do not remove segments.

The clean up code is similar to what I posted at

	http://humbolt.geo.uu.nl/lists/linux-mm/1999-06/msg00071.html 

previously. Although, I would point out that SHMMAX probably belongs to the asm/* header file (specially, with the size_t size parameter to shmget()).

The sysctl idea is good, although you need to clean up the code, and make 2 new nodes /proc/sys/kernel/* for ease of use.

The removal of struct shmid_kernel from shm.h to a private header file, or to shm.c is a very good idea. This has no business being user visible. Cleanups like this go a long way in creating a clean ddi/dki ...

The removal of vmalloc() from the shm.c sounds good in principle, although I haven't really reviewed your code in any detail ...

Thanks.

Kanoj
--
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/

#6 lore raw
In reply to a message not in the archive
Quoted 17 lines · [email protected] (Kanoj Sarcar) writes:
Quoted 6 lines

Since glibc is encapsulating these calls and headers, we could perhaps work with compatibility version. E.g. making shmget and shmctl a real system call and converting the structures in sys_ipc to the old ones for old libraries?

Quoted 10 lines

BTW I did some work to make the clean up the shm coding and make the limites sysctleable. It also avoids vmalloc for the page tables. The latter is really important for big servers. We run out of vm-space on some benchmarks. I appended the patch against 2.3.24. I could not finally test this patch since shm swapping has apparently a race condition on segment deletion introduced with the smp version. I am still investigating on that. But perhaps we could incorporate this patch anyways. It did survive stress testing shm-swapping as long as I do not remove segments.

Quoted 7 lines

The clean up code is similar to what I posted at

	http://humbolt.geo.uu.nl/lists/linux-mm/1999-06/msg00071.html 

previously. Although, I would point out that SHMMAX probably belongs to the asm/* header file (specially, with the size_t size parameter to shmget()).

Why should we make it arch dependend if we can tune it at runtime?

Quoted 2 lines

The sysctl idea is good, although you need to clean up the code, and make 2 new nodes /proc/sys/kernel/* for ease of use.

I preferred not to clutter the proc/sys/kernel namespace, but this is arguable. I think tuning these parameters belongs together and can easily be done in one file. Especially since you can tune the most import one alone. (SHMMAX is the first)

Quoted 7 lines

The removal of struct shmid_kernel from shm.h to a private header file, or to shm.c is a very good idea. This has no business being user visible. Cleanups like this go a long way in creating a clean ddi/dki ...

The removal of vmalloc() from the shm.c sounds good in principle, although I haven't really reviewed your code in any detail ...

It is crucial for big machines especially with highmem support. I still try to get 2.3.25 to swap out shm pages. There was something introduced after 2.3.22 which prevents shm pages to swap out (w/o my patch). At least 2.3.25 survives running out of memory with high memory so I can investigate.

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/

#7 lore raw
Quoted 10 lines
Quoted 7 lines

The clean up code is similar to what I posted at

	http://humbolt.geo.uu.nl/lists/linux-mm/1999-06/msg00071.html 

previously. Although, I would point out that SHMMAX probably belongs to the asm/* header file (specially, with the size_t size parameter to shmget()).

Why should we make it arch dependend if we can tune it at runtime?

Probably 95% of people who run Linux have no idea what /proc/sys/kernel/shmmax is, and end up recompiling the kernel with a bumped up SHMMAX, if they find SHMMAX too low for their app. On sparc64/alpha and yet to come mips64/ia64, SHMMAX can be pretty huge, compared to the ia32 0x2000000. Think out of the box, and you will see that keeping SHMMAX asm dependent will work better for most people ...

Kanoj
--
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/

#8 lore raw
In reply to a message not in the archive
Quoted 11 lines · [email protected] (Kanoj Sarcar) writes:
Quoted 10 lines
Quoted 7 lines

The clean up code is similar to what I posted at

	http://humbolt.geo.uu.nl/lists/linux-mm/1999-06/msg00071.html 

previously. Although, I would point out that SHMMAX probably belongs to the asm/* header file (specially, with the size_t size parameter to shmget()).

Why should we make it arch dependend if we can tune it at runtime?

Quoted 7 lines

Probably 95% of people who run Linux have no idea what /proc/sys/kernel/shmmax is, and end up recompiling the kernel with a bumped up SHMMAX, if they find SHMMAX too low for their app. On sparc64/alpha and yet to come mips64/ia64, SHMMAX can be pretty huge, compared to the ia32 0x2000000. Think out of the box, and you will see that keeping SHMMAX asm dependent will work better for most people ...

So we should include a comment in shm.h to do it via sysctl. For bigger machines you have many parameters to tune. So the people have to get used to sysctl and we will need a frontend to tune them persistently.

At least that's what I would do. In general I think it is good to keep the arch dependend part as small as possible. But I have no real objection for doing it the other way besides this.

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/

#9 lore raw
In reply to a message not in the archive

Hi Kanoj,

apparently my Mail got somehow broken up during transfer. At least I could not read my comments in the version from the list so I resend my comments.

Grettings
Christoph

Quoted 21 lines · [email protected] (Kanoj Sarcar) writes:
Quoted 9 lines

Hi Kanoj,

This is probably breaking user space applications since shmid_ds is shared with user space in shmctl(2). On 32bit machines this does not matter, since sizeof(int) == sizeof(size_t), but on 64bit this will break.

How do we handle this?

Unfortunately, I don't think we can prevent this 64bit ABI breakage, if we want to conform to the single unix spec on those platforms. Its probably a good idea to have the ia64 port be SUS compliant, even though sparc64/alpha are currently not.

If it is really important to preserve the 64bit ABI, there's one more
alternative: preserve the shmget() api/abi on the old 64bit platforms, but be compliant on the 32 bit ones and newer 64 bit ones (mips64/ia64). This is not the cleanest solution, but can be done with a little header file reorganization in include/linux/shm.h and include/linux/shmparam.h.

Quoted 3 lines

Linus has put this patch into pre-25, lets talk if it is important to do the above ... it shouldn't take me more than a couple of hours to do it, if we so decided.

Since glibc is encapsulating these calls and headers, we could perhaps work with compatibility version. E.g. making shmget and shmctl a real system call and converting the structures in sys_ipc to the old ones for old libraries?

BTW I did some work to make the clean up the shm coding and make the limites sysctleable. It also avoids vmalloc for the page tables. The latter is really important for big servers. We run out of vm-space on some benchmarks. I appended the patch against 2.3.24. I could not finally test this patch since shm swapping has apparently a race condition on segment deletion introduced with the smp version. I am still investigating on that. But perhaps we could incorporate this patch anyways. It did survive stress testing shm-swapping as long as I do not remove 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/

#10 lore raw

Re: The 4GB memory thing

In reply to a message not in the archive
Quoted 2 lines · [email protected] (Kanoj Sarcar) writes:

I don't see a README.gz under
http://www.kernel.org/pub/linux/kernel/people/andrea/tools/apply-patches/

lftp> pwd ftp://ftp.it.kernel.org/pub/linux/kernel/people/andrea/tools/apply-patches lftp> ls README.gz
-rw-r--r-- 1 ftp daemon 875 Oct 25 00:43 README.gz
lftp>

Quoted 2 lines

In any case, did you a have a small technical README on how rawio works on bigmem in 2.2.13aa3? Btw, I haven't seen the rawio 2.2 port, I am

As first you can have a look at the rawio patch.

        ftp://ftp.it.kernel.org/pub/linux/kernel/people/andrea/kernels/v2.2/2.2.13aa3/z-bigmem-rawio-2.2.13aa2-1.gz

The above patch includes all the necessary stuff to make rawio working fine on bigmem pages.

Basically the code uses regular pages as bounce buffers to do the I/O on bigmem pages.

Quoted 3 lines

assuming its very similar to 2.3 ... where brw_kiovec() refuses to accept PageHighMem pages. I didn't see anything in z-bigmem-2.2.13aa3-7

No. The z-bigmem-rawio-2.2.13aa2-1.gz in 2.2.13aa3 allows brw_kiovec to do I/O on bigmem pages.

Quoted 1 line

that tinkers either with fs/buffer.c.

I take the bigmem stuff separated from rawio. The rawio patch (pointed out above) included in 2.2.13aa3 is an incremental patch that goes on the top of bigmem. I take all the patches separated to allow everybody out there to merge easily my stuff and to see the only related necessary changes on topic.

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/
#11 lore raw

Re: [RFC] mapping parts of shared memory

In reply to a message not in the archive
Quoted 11 lines · [email protected] (Kanoj Sarcar) writes:
Quoted 10 lines

Hi,

I was investigating for some time about the possibility to create some object which allows me to map and unmap parts of it it in different processes. This would help to take advantage of the high memory systems with applications like SAP R/3 which uses a small number of processes to server many clients. It is now limited by the available address space for one process.

Quoted 5 lines

Lets see if I am understanding the problem right. Currently, you may have an ia32 box with 8G memory, unfortunately, your server can make use of at most (say) 3G worth of shared memory. Hence, you are worried about how to be able to use the other 5G, lets say with more server processes.

Yes that's right.

Quoted 4 lines

What prevents your app from creating say 2 shm segments, each around 2.5G or so? That will let you attach in and use about 5G between 2 server processes. What have you lost with this approach that you will get with the kernel approach?

I explain a little bit the different approaches of SAP R/3 with respect to user context memory:

1) All user requests are handled in a relatively small number of processes.
2) One user transaction can consist of more than one request and subsequent requests from one transaction do not need to be processed by the same workprocess.
3) So the workprocesses need a way to share the user contexts. To acomplish this we have three different implementations:
a) The classic Unix model: We map one really big area with mmap(ANON|SHARED) and use mprotect to 'attach' the actual user context. So all user data has to fit into the address space together (and we have easily more than 100 users on one server) This works fine on 64 bit architectures, but is very restricted on 32 bit.
b) The shm segments model (only used on AIX so far): We use big shm segments which cannot be shared between different user contexts. They have to be big because this implementation cannot merge multiple segments together. So the biggest single allocation is limited by the segment size. This implementation works basically under Linux but has two drawbacks:
1) For good performance we need a disclaim system call, which is not available on Linux. Imagine the following (really usual)
situation: Every user first allocates on small variable and a big chunk of memory for some internal table. Then this internal table is freed but the transaction still persists (which is normal for readonly transactions) So we do not have a chance to free this memory against the OS since we only can free the complete segment and there is still a small item in this segment.
2) We do not want to support this model any longer since AIX is now 64 bit and can use model a. Also many administrators know the mapping model c. So it would be more training effort if we would focus on this implementation.
c) The mapping model (the standard model NT and implemented for Unix using shm_open) works by reserving some unnamed file and mmaping the user context from this file descriptor. This can also handle more than one file. To be able to do this we need something like posix shm which gives you a fd with shm_open, which we then can use to mmmap parts of it into the process. This model does work with small blocks (normally 1MB) and can concatenate arbitrary blocks on the file to one contiguous memory area. So we are able to reuse freed memory from one context in another one and the problems described in b are not as bad as there. But probably disclaim does help here also.

I would like be able to use c) under Linux.

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/

#12 lore raw

Re: [RFC] [RFT] Shared /dev/zero mmaping feature

In reply to a message not in the archive

Hi Kanoj,

Quoted 11 lines · [email protected] (Kanoj Sarcar) writes:

This is a patch against 2.3.47 that tries to implement shared /dev/zero mappings. This is just a first cut attempt, I am hoping I will find a few people to apply the patch and throw some real life programs at it (preferably on low memory machines so that swapping is induced).

Currently, you will also need to turn on CONFIG_SYSVIPC, but most of the shm.c code can be split into a new ipc/shm_core.c file that is always compiled in, irrespective of CONFIG_SYSVIPC. Linus, do you think this is the proper direction to follow?

Thanks. Comments and feedback welcome ...

Why do you use this special zero_id stuff? It clutters up the whole code.

If you would simply open a normal shm segment with key IPC_PRIVATE and directly remove it nobody can attach to it and it will be released on exit and everything. No special handling needed any more. BTW that's exectly what we do in user space to circumvent the missing MAP_ANON | MAP_SHARED.

I would also prefer to be able to see the allocated segments with the ipc* commands.

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://www.linux.eu.org/Linux-MM/

#13 lore raw

Re: [RFC] [RFT] Shared /dev/zero mmaping feature

Quoted 2 lines

Why do you use this special zero_id stuff? It clutters up the whole code.

The zero_id stuff is required to differentiate between the struct shmid_kernel of a "real" shared memory segment and one that represents a /dev/zero mapping. This is used in shm_swap_core(), for accounting purposes, but that can be changed by adding a new flag to shm_swap_core. The more important use is in shm_nopage().

Quoted 6 lines

If you would simply open a normal shm segment with key IPC_PRIVATE and directly remove it nobody can attach to it and it will be released on exit and everything. No special handling needed any more. BTW that's exectly what we do in user space to circumvent the missing MAP_ANON | MAP_SHARED.

Would this need to be done for each /dev/zero mapping? If so, then I prefer the way the code is right now, since the interference with "real" shared memory is minimal. I was also trying to look for a way to prevent the zshmid_kernel hacks in shmat/shmctl (including setting strict permissions), but couldn't come up with one ... Tell me in more detail what you are suggesting here.

Quoted 4 lines

I would also prefer to be able to see the allocated segments with the ipc* commands.

I do not believe there is any good reason to expose the special shared memory segment used as a place holder for all /dev/zero mappings to users via ipc* commands. This special segment exists only because we want to reduce kernel code duplication, and all the zshmid_kernel/ zero_id checks just make sure that regular shared memory works pretty much the way it did before. (One thing I am unhappy about is that this special segment eats up a shm id, but that's probably not too bad).

Thanks.

Kanoj
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#14 lore raw

Re: [RFC] [RFT] Shared /dev/zero mmaping feature

In reply to a message not in the archive

Hi Kanoj and Linus,

Quoted 10 lines · [email protected] (Kanoj Sarcar) writes:

[snip]

I do not believe there is any good reason to expose the special shared memory segment used as a place holder for all /dev/zero mappings to users via ipc* commands. This special segment exists only because we want to reduce kernel code duplication, and all the zshmid_kernel/ zero_id checks just make sure that regular shared memory works pretty much the way it did before. (One thing I am unhappy about is that this special segment eats up a shm id, but that's probably not too bad).

The appended proposal reduces code duplication and complexity a lot. (The diff47 needs your patches against other files added.)

I would vote to apply diff48 to the standard kernel. For me the whole solution is still a workaround.

Greetings
Christoph

ipc/shm.c +22 -0
@@ -11,6 +11,7 @@
  * HIGHMEM support, Ingo Molnar <[email protected]>
  * avoid vmalloc and make shmmax, shmall, shmmni sysctl'able,
  *                         Christoph Rohland <[email protected]>
+ * Shared /dev/zero support, Kanoj Sarcar <[email protected]>
  */
 
 #include <linux/config.h>
@@ -1100,3 +1101,24 @@
 	return len;
 }
 #endif
+
+int map_zero_setup(struct vm_area_struct *vma)
+{
+        int shmid;
+	struct shmid_kernel *shp;
+
+	down(&shm_ids.sem);
+	shmid = newseg(IPC_PRIVATE, S_IRWXUGO, vma->vm_end - vma->vm_start);
+        up(&shm_ids.sem);
+        if (shmid < 0)
+                return shmid;
+
+        if (!(shp = shm_lock (shmid)))
+                BUG();
+        shp->shm_perm.mode |= SHM_DEST;
+        shm_unlock (shmid);
+	vma->vm_private_data = shp;
+	vma->vm_ops = &shm_vm_ops;
+	shm_open (vma);
+	return 0;
+}
ipc/shm.c renamed from ipc/shm.c.48 +109 -304

596 lines not on this page · raw message

#15 lore raw

Re: [RFC] [RFT] Shared /dev/zero mmaping feature

Quoted 16 lines

Hi Kanoj and Linus,

Quoted 10 lines · [email protected] (Kanoj Sarcar) writes:

[snip]

I do not believe there is any good reason to expose the special shared memory segment used as a place holder for all /dev/zero mappings to users via ipc* commands. This special segment exists only because we want to reduce kernel code duplication, and all the zshmid_kernel/ zero_id checks just make sure that regular shared memory works pretty much the way it did before. (One thing I am unhappy about is that this special segment eats up a shm id, but that's probably not too bad).

Quoted 3 lines

The appended proposal reduces code duplication and complexity a lot. (The diff47 needs your patches against other files added.)

What you have sent is what I used as a first draft for the implementation. The good part of it is that it reduces code duplication. The _really_ bad part is that it penalizes users in terms of numbers of shared memory segments, max size of /dev/zero mappings, and limitations imposed by shm_ctlmax/shm_ctlall/shm_ctlmni etc. I do not think taking up a shmid for each /dev/zero mapping is a good idea ...

Furthermore, I did not want to change behavior of information returned by ipc* and various procfs commands, as well as swapout behavior, thus the creation of the zmap_list. I decided a few lines of special case checking in a handful of places was a much better option.

If the current /dev/zero stuff hampers any plans you have with shm code (eg page cachification), I would be willing to talk about it ...

Kanoj

Quoted 5 lines

I would vote to apply diff48 to the standard kernel. For me the whole solution is still a workaround.

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://www.linux.eu.org/Linux-MM/

#16 lore raw

Re: [RFC] [RFT] Shared /dev/zero mmaping feature

In reply to a message not in the archive
Quoted 6 lines · [email protected] (Kanoj Sarcar) writes:

What you have sent is what I used as a first draft for the implementation. The good part of it is that it reduces code duplication. The _really_ bad part is that it penalizes users in terms of numbers of shared memory segments, max size of /dev/zero mappings, and limitations imposed by shm_ctlmax/shm_ctlall/shm_ctlmni etc. I do not think taking up a shmid for each /dev/zero mapping is a good idea ...

We can tune all these parameters at runtime. This should not be a reason.

Quoted 4 lines

Furthermore, I did not want to change behavior of information returned by ipc* and various procfs commands, as well as swapout behavior, thus the creation of the zmap_list. I decided a few lines of special case checking in a handful of places was a much better option.

IMHO all this SYSV ipc stuff is a totally broken API and many agree with me. I do not care to clutter up the output of it a little bit for this feature.

Nobody can know who is creating private IPC segments. So nobody should be irritated by some more segments displayed/used.

In the contrary: I like the ability to restrict the usage of these segments with the ipc parameters. Keep in mind you can stack a lot of segments for a DOS attack. and all the segments will use the whole memory.

Quoted 2 lines

If the current /dev/zero stuff hampers any plans you have with shm code (eg page cachification), I would be willing to talk about it ...

It makes shm fs a lot more work. And the special handling slows down shm handling.

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://www.linux.eu.org/Linux-MM/

#17 lore raw

Re: [RFC] [RFT] Shared /dev/zero mmaping feature

Quoted 10 lines
Quoted 6 lines · [email protected] (Kanoj Sarcar) writes:

What you have sent is what I used as a first draft for the implementation. The good part of it is that it reduces code duplication. The _really_ bad part is that it penalizes users in terms of numbers of shared memory segments, max size of /dev/zero mappings, and limitations imposed by shm_ctlmax/shm_ctlall/shm_ctlmni etc. I do not think taking up a shmid for each /dev/zero mapping is a good idea ...

Quoted 2 lines

We can tune all these parameters at runtime. This should not be a reason.

Show me the patch ... by the time you are done, you _probably_ would have complicated the code more than the current /dev/zero tweaks.

Quoted 9 lines
Quoted 5 lines

Furthermore, I did not want to change behavior of information returned by ipc* and various procfs commands, as well as swapout behavior, thus the creation of the zmap_list. I decided a few lines of special case checking in a handful of places was a much better option.

IMHO all this SYSV ipc stuff is a totally broken API and many agree with me. I do not care to clutter up the output of it a little bit for this feature.

In reality, /dev/zero should have nothing to do with SYSV. Currently, its that way because I wanted to minimize code duplication. Most of the *_core() routines can be taken into ipc/shm_core.c, and together with util.c, will let /dev/zero be decoupled from SYSV.

Quoted 3 lines

Nobody can know who is creating private IPC segments. So nobody should be irritated by some more segments displayed/used.

The problem is more with the limits, much less with the output ...

Quoted 5 lines

In the contrary: I like the ability to restrict the usage of these segments with the ipc parameters. Keep in mind you can stack a lot of segments for a DOS attack. and all the segments will use the whole memory.

Not sure what you are talking about here ... /dev/zero mmaps are subject to the same vm-resource checking as other mmaps, and this checking is a little different for "real" shm creation.

Quoted 6 lines
Quoted 3 lines

If the current /dev/zero stuff hampers any plans you have with shm code (eg page cachification), I would be willing to talk about it ...

It makes shm fs a lot more work. And the special handling slows down shm handling.

The shm handling slow down is minimal. Most of this is an extra check in shm_nopage(), but that _only_ happens for /dev/zero segments, not for "real" shm segments.

As to why shm fs is a lot more work, we can talk. Linus/Ingo did bring this up, at a general level, we think that adding an extra inode or other data structure in map_zero_setup() would be able to handle this.

If a small amount of special case code is the problem, I would suggest keep the code as it is for now. Once you have the shm fs work done for "real" shm segments, I can look at how to handle /dev/zero segments.

Kanoj

Quoted 8 lines

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://www.linux.eu.org/Linux-MM/

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#18 lore raw

Re: [RFC] [RFT] Shared /dev/zero mmaping feature

In reply to a message not in the archive

Hi Kanoj,

Quoted 10 lines · [email protected] (Kanoj Sarcar) writes:
Quoted 10 lines
Quoted 7 lines · [email protected] (Kanoj Sarcar) writes:

What you have sent is what I used as a first draft for the implementation. The good part of it is that it reduces code duplication. The _really_ bad part is that it penalizes users in terms of numbers of shared memory segments, max size of /dev/zero mappings, and limitations imposed by shm_ctlmax/shm_ctlall/shm_ctlmni etc. I do not think taking up a shmid for each /dev/zero mapping is a good idea ...

Quoted 5 lines
Quoted 2 lines

We can tune all these parameters at runtime. This should not be a reason.

Show me the patch ... by the time you are done, you _probably_ would have complicated the code more than the current /dev/zero tweaks.

It _is_ tunable in the current code.

Quoted 10 lines
Quoted 9 lines
Quoted 5 lines

Furthermore, I did not want to change behavior of information returned by ipc* and various procfs commands, as well as swapout behavior, thus the creation of the zmap_list. I decided a few lines of special case checking in a handful of places was a much better option.

IMHO all this SYSV ipc stuff is a totally broken API and many agree with me. I do not care to clutter up the output of it a little bit for this feature.

Quoted 5 lines

In reality, /dev/zero should have nothing to do with SYSV. Currently, its that way because I wanted to minimize code duplication. Most of the *_core() routines can be taken into ipc/shm_core.c, and together with util.c, will let /dev/zero be decoupled from SYSV.

That would be the best case and thus your proposal is a workaround until the pagecache can handle it.

Quoted 4 lines
Quoted 2 lines

Nobody can know who is creating private IPC segments. So nobody should be irritated by some more segments displayed/used.

The problem is more with the limits, much less with the output ...

And they are tunable...

Quoted 8 lines
Quoted 4 lines

In the contrary: I like the ability to restrict the usage of these segments with the ipc parameters. Keep in mind you can stack a lot of segments for a DOS attack. and all the segments will use the whole memory.

Not sure what you are talking about here ... /dev/zero mmaps are subject to the same vm-resource checking as other mmaps, and this checking is a little different for "real" shm creation.

Think about first mmaping an anonymous shared segment, touching all the pages, unmapping most of it. Then start over again. You end up with loads of pages used and not freed and no longer accessible.

Quoted 9 lines
Quoted 5 lines
Quoted 2 lines

If the current /dev/zero stuff hampers any plans you have with shm code (eg page cachification), I would be willing to talk about it ...

It makes shm fs a lot more work. And the special handling slows down shm handling.

The shm handling slow down is minimal. Most of this is an extra check in shm_nopage(), but that _only_ happens for /dev/zero segments, not for "real" shm segments.

The check happens for _all_ segments and shm_nopage can be called very often on big machines under heavy load.

Quoted 8 lines

As to why shm fs is a lot more work, we can talk. Linus/Ingo did bring this up, at a general level, we think that adding an extra inode or other data structure in map_zero_setup() would be able to handle this.

If a small amount of special case code is the problem, I would suggest keep the code as it is for now. Once you have the shm fs work done for "real" shm segments, I can look at how to handle /dev/zero segments.

shm fs is working. I will send a patch against 2.3.48 soon.

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://www.linux.eu.org/Linux-MM/

#19 lore raw

Re: [RFC] [RFT] Shared /dev/zero mmaping feature

Quoted 15 lines

Hi Kanoj,

Quoted 10 lines · [email protected] (Kanoj Sarcar) writes:
Quoted 10 lines
Quoted 7 lines · [email protected] (Kanoj Sarcar) writes:

What you have sent is what I used as a first draft for the implementation. The good part of it is that it reduces code duplication. The _really_ bad part is that it penalizes users in terms of numbers of shared memory segments, max size of /dev/zero mappings, and limitations imposed by shm_ctlmax/shm_ctlall/shm_ctlmni etc. I do not think taking up a shmid for each /dev/zero mapping is a good idea ...

Quoted 7 lines
Quoted 5 lines
Quoted 2 lines

We can tune all these parameters at runtime. This should not be a reason.

Show me the patch ... by the time you are done, you _probably_ would have complicated the code more than the current /dev/zero tweaks.

It _is_ tunable in the current code.

Oh, you are talking about asking administrators to do this tuning, which is unfair. I was talking about automatic in-kernel tuning whenever a new /dev/zero segment is created/destroyed etc ...

Quoted 20 lines
Quoted 11 lines
Quoted 10 lines
Quoted 6 lines

Furthermore, I did not want to change behavior of information returned by ipc* and various procfs commands, as well as swapout behavior, thus the creation of the zmap_list. I decided a few lines of special case checking in a handful of places was a much better option.

IMHO all this SYSV ipc stuff is a totally broken API and many agree with me. I do not care to clutter up the output of it a little bit for this feature.

Quoted 5 lines

In reality, /dev/zero should have nothing to do with SYSV. Currently, its that way because I wanted to minimize code duplication. Most of the *_core() routines can be taken into ipc/shm_core.c, and together with util.c, will let /dev/zero be decoupled from SYSV.

That would be the best case and thus your proposal is a workaround until the pagecache can handle it.

Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

Nobody can know who is creating private IPC segments. So nobody should be irritated by some more segments displayed/used.

The problem is more with the limits, much less with the output ...

And they are tunable...

See above ...

Quoted 6 lines
Quoted 6 lines
Quoted 5 lines

In the contrary: I like the ability to restrict the usage of these segments with the ipc parameters. Keep in mind you can stack a lot of segments for a DOS attack. and all the segments will use the whole memory.

Quoted 7 lines
Quoted 3 lines

Not sure what you are talking about here ... /dev/zero mmaps are subject to the same vm-resource checking as other mmaps, and this checking is a little different for "real" shm creation.

Think about first mmaping an anonymous shared segment, touching all the pages, unmapping most of it. Then start over again. You end up with loads of pages used and not freed and no longer accessible.

True ... and this can be independently handled via a shmzero_unmap() type operation in shmzero_vm_ops (I never claimed the /dev/zero stuff is complete :-)) Even in the absence of that, vm_enough_memory() should in theory be able to prevent deadlocks, with all its known caveats ...

Quoted 7 lines
Quoted 7 lines
Quoted 6 lines
Quoted 3 lines

If the current /dev/zero stuff hampers any plans you have with shm code (eg page cachification), I would be willing to talk about it ...

It makes shm fs a lot more work. And the special handling slows down shm handling.

Quoted 6 lines
Quoted 3 lines

The shm handling slow down is minimal. Most of this is an extra check in shm_nopage(), but that _only_ happens for /dev/zero segments, not for "real" shm segments.

The check happens for _all_ segments and shm_nopage can be called very often on big machines under heavy load.

I was talking about the

	if ((shp != shm_lock(shp->id)) && (is_shmzero == 0))

checks in shm_nopage.

Quoted 11 lines
Quoted 9 lines

As to why shm fs is a lot more work, we can talk. Linus/Ingo did bring this up, at a general level, we think that adding an extra inode or other data structure in map_zero_setup() would be able to handle this.

If a small amount of special case code is the problem, I would suggest keep the code as it is for now. Once you have the shm fs work done for "real" shm segments, I can look at how to handle /dev/zero segments.

shm fs is working. I will send a patch against 2.3.48 soon.

Great, we can see what makes sense for /dev/zero wrt shmfs ...

Kanoj

Quoted 4 lines

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://www.linux.eu.org/Linux-MM/

#20 lore raw

Re: [RFC] [RFT] Shared /dev/zero mmaping feature

Hi,

Quoted 1 line · On Wed, 1 Mar 2000 12:09:11 -0800 (PST), [email protected] (Kanoj…

Great, we can see what makes sense for /dev/zero wrt shmfs ...

In principle, there is no reason why we need any special support for this sort of thing. The swap cache already does very nearly all we need.

The swap cache maintains links between swap locations on disk and (potentially shared) anonymous pages in memory. It was designed so that even if you fork, as long as the resulting COW pages remain unchanged, the two processes will share the same pages of physical memory or swap no matter what.

Basically, as soon as you try to swap out an anonymous page from one process, a swap entry is allocated and a swap cache entry is set up. Only once the last process swaps out does the physical page in memory get released. Until that happens, any lookup of the swap entry from a swapped-out process will find the page already in memory.

To make this work for shared anonymous pages, we need two changes to the swap cache. We need to teach the swap cache about writable anonymous pages, and we need to be able to defer the physical writing of the page to swap until the last reference to the swap cache frees up the page. Do that, and shared /dev/zero maps will Just Work.

The mechanics of this are probably a little too subtle to get right for 2.4 at this stage (in particular you need to know when to write the page back to disk: we don't have the necessary PAGE_DIRTY infrastructure in place for anonymous pages), but I definitely think this is the right way to do things in the long term.

--Stephen
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#21 lore raw

Re: [RFC] [RFT] Shared /dev/zero mmaping feature

Quoted 7 lines

To make this work for shared anonymous pages, we need two changes to the swap cache. We need to teach the swap cache about writable anonymous pages, and we need to be able to defer the physical writing of the page to swap until the last reference to the swap cache frees up the page. Do that, and shared /dev/zero maps will Just Work.

The current implementation of /dev/zero shared memory is to treat the mapping as similarly as possible to a shared memory segment. The common code handles the swap cache interactions, and both cases qualify as shared anonymous mappings. While its not well tested, in theory it should work. We are currently agonizing over how to integrate the /dev/zero code with shmfs patch.

Kanoj
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#22 lore raw

Re: [RFC] [RFT] Shared /dev/zero mmaping feature

In reply to a message not in the archive

Hi Kanoj,

Quoted 7 lines · [email protected] (Kanoj Sarcar) writes:
Quoted 6 lines

To make this work for shared anonymous pages, we need two changes to the swap cache. We need to teach the swap cache about writable anonymous pages, and we need to be able to defer the physical writing of the page to swap until the last reference to the swap cache frees up the page. Do that, and shared /dev/zero maps will Just Work.

Quoted 6 lines

The current implementation of /dev/zero shared memory is to treat the mapping as similarly as possible to a shared memory segment. The common code handles the swap cache interactions, and both cases qualify as shared anonymous mappings. While its not well tested, in theory it should work. We are currently agonizing over how to integrate the /dev/zero code with shmfs patch.

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Since this is not as easy as you thought, wouldn't it be better to do the /dev/zero shared maps in the swap cache instead of this workaround over shm? Thus we would get the mechanisms to redo all shm stuff wrt swap cache.

At the same time we would not hinder the development of normal shm code to use file semantics (aka shm fs) which will give us posix shm.

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://www.linux.eu.org/Linux-MM/

#23 lore raw

Re: [RFC] [RFT] Shared /dev/zero mmaping feature

Quoted 24 lines

Hi Kanoj,

Quoted 7 lines · [email protected] (Kanoj Sarcar) writes:
Quoted 6 lines

To make this work for shared anonymous pages, we need two changes to the swap cache. We need to teach the swap cache about writable anonymous pages, and we need to be able to defer the physical writing of the page to swap until the last reference to the swap cache frees up the page. Do that, and shared /dev/zero maps will Just Work.

Quoted 6 lines

The current implementation of /dev/zero shared memory is to treat the mapping as similarly as possible to a shared memory segment. The common code handles the swap cache interactions, and both cases qualify as shared anonymous mappings. While its not well tested, in theory it should work. We are currently agonizing over how to integrate the /dev/zero code with shmfs patch.

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Since this is not as easy as you thought, wouldn't it be better to do the /dev/zero shared maps in the swap cache instead of this workaround over shm? Thus we would get the mechanisms to redo all shm stuff wrt swap cache.

Quoted 6 lines

At the same time we would not hinder the development of normal shm code to use file semantics (aka shm fs) which will give us posix shm.

Greetings
Christoph

I am not sure why you think the /dev/zero code is a workaround on top of shm. A lot of code and mechanisms are easily sharable between shm and /dev/zero, since they are, as I pointed out, anonymous shared pages. The only differences are when the data structures are torn down, and which processes may attach to the segments.

Btw, implementing /dev/zero using shm code mostly is _quite_ easy, that's how the code has been since 2.3.48. Even integrating with shmfs has been pretty easy, as you have seen in the patches I have CCed you on. The harder part is to look towards the future and do what Linus suggested, namely associate each mapping with an inode so in the future the inodecache might possibly be used to manage the shm pages. As you know, I sent out a patch for that yesterday.

Its completely okay by me to take in a dev-zero/shmfs integration patch that is not perfect wrt /dev/zero, as I have indicated to you and Linus, just so that the shmfs work gets in. I can fix minor problems with the /dev/zero code as they come up.

What sct suggests is quite involved, as he himself mentions. Just implementing /dev/zero is probably not a good reason to undertake it.

Hope this makes sense.

Kanoj
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#24 lore raw

Re: [RFC] [RFT] Shared /dev/zero mmaping feature

Quoted 5 lines · [email protected] (Kanoj Sarcar) writes:

I am not sure why you think the /dev/zero code is a workaround on top of shm. A lot of code and mechanisms are easily sharable between shm and /dev/zero, since they are, as I pointed out, anonymous shared pages. The only differences are when the data structures are torn down, and which processes may attach to the segments.

Because I think the current shm code should be redone in a way that shared anonymous pages live in the swap cache. You could say the shm code is a workaround :-)

Quoted 7 lines

Btw, implementing /dev/zero using shm code mostly is _quite_ easy, that's how the code has been since 2.3.48. Even integrating with shmfs has been pretty easy, as you have seen in the patches I have CCed you on. The harder part is to look towards the future and do what Linus suggested, namely associate each mapping with an inode so in the future the inodecache might possibly be used to manage the shm pages. As you know, I sent out a patch for that yesterday.

In my opinion this is one of two orthogonal steps. shm fs targets the better integration in the file system semantics.

Quoted 8 lines

Its completely okay by me to take in a dev-zero/shmfs integration patch that is not perfect wrt /dev/zero, as I have indicated to you and Linus, just so that the shmfs work gets in. I can fix minor problems with the /dev/zero code as they come up.

What sct suggests is quite involved, as he himself mentions. Just implementing /dev/zero is probably not a good reason to undertake it.

But IMHO reworking shm based on the /dev/zero stuff would be a good reason to do the /dev/zero stuff right. That's all I wanted to say in my last mail.

Perhaps I am a little bit too opposed to these changes because I have seen too many patches thrown on the shm code during the 2.3 cycle which were plain buggy and nobody cared. Most of my kernel work since some time is doing quite stupid tests on the shm code.

BTW: I am just running these tests on your patch and it seems to work quite well. (I will let it run over night) If it survives that I will also throw some quite complicated /dev/zero tests on it later.

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://www.linux.eu.org/Linux-MM/

#25 lore raw

Re: [RFC] [RFT] Shared /dev/zero mmaping feature

Quoted 4 lines · Christoph Rohland

Because I think the current shm code should be redone in a way that shared anonymous pages live in the swap cache. You could say the shm code is a workaround :-)

Note that this is true of both shm AND /dev/zero.

Whether it is done in the current really clunky manner (ugly special shm tables) or in the RightWay(tm) (page cache), shm and /dev/zero should always basically be the same. The only difference between shm and /dev/zero is how you access and set up mappings, not how the actual mapping then works.

Linus

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#26 lore raw

Re: [RFC] [RFT] Shared /dev/zero mmaping feature

In reply to Christoph Rohland
Quoted 9 lines
Quoted 5 lines · [email protected] (Kanoj Sarcar) writes:

I am not sure why you think the /dev/zero code is a workaround on top of shm. A lot of code and mechanisms are easily sharable between shm and /dev/zero, since they are, as I pointed out, anonymous shared pages. The only differences are when the data structures are torn down, and which processes may attach to the segments.

Quoted 4 lines

Because I think the current shm code should be redone in a way that shared anonymous pages live in the swap cache. You could say the shm code is a workaround :-)

No arguments there :-) But it seems a little ambitious to me to implement shmfs, dev-zero and rework the swapcache at the same time. We are probably on the right track, having done /dev/zero, getting done with shmfs. Then, if we want to take the risk, we can improve the core shm/swapcache interactions in 2.3/2.4/2.5.

Quoted 24 lines
Quoted 7 lines

Btw, implementing /dev/zero using shm code mostly is _quite_ easy, that's how the code has been since 2.3.48. Even integrating with shmfs has been pretty easy, as you have seen in the patches I have CCed you on. The harder part is to look towards the future and do what Linus suggested, namely associate each mapping with an inode so in the future the inodecache might possibly be used to manage the shm pages. As you know, I sent out a patch for that yesterday.

In my opinion this is one of two orthogonal steps. shm fs targets the better integration in the file system semantics.

Quoted 8 lines

Its completely okay by me to take in a dev-zero/shmfs integration patch that is not perfect wrt /dev/zero, as I have indicated to you and Linus, just so that the shmfs work gets in. I can fix minor problems with the /dev/zero code as they come up.

What sct suggests is quite involved, as he himself mentions. Just implementing /dev/zero is probably not a good reason to undertake it.

But IMHO reworking shm based on the /dev/zero stuff would be a good reason to do the /dev/zero stuff right. That's all I wanted to say in my last mail.

Quoted 8 lines

Perhaps I am a little bit too opposed to these changes because I have seen too many patches thrown on the shm code during the 2.3 cycle which were plain buggy and nobody cared. Most of my kernel work since some time is doing quite stupid tests on the shm code.

BTW: I am just running these tests on your patch and it seems to work quite well. (I will let it run over night) If it survives that I will also throw some quite complicated /dev/zero tests on it later.

Great! Is there a way to capture tests written by individual developers and testers and have them be shared, so everyone can use them (when there are no licensing/copyright issues)? I would definitely like to get your test programs and throw them at the kernel myself. Lets talk offline if you are willing to share your tests.

Kanoj

Quoted 8 lines

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://www.linux.eu.org/Linux-MM/

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#27 lore raw

Re: [RFC] [RFT] Shared /dev/zero mmaping feature

Quoted 9 lines · [email protected] (Kanoj Sarcar) writes:
Quoted 3 lines

Because I think the current shm code should be redone in a way that shared anonymous pages live in the swap cache. You could say the shm code is a workaround :-)

No arguments there :-) But it seems a little ambitious to me to implement shmfs, dev-zero and rework the swapcache at the same time. We are probably on the right track, having done /dev/zero, getting done with shmfs. Then, if we want to take the risk, we can improve the core shm/swapcache interactions in 2.3/2.4/2.5.

O.K. I would really like to work on that further.

Quoted 10 lines
Quoted 3 lines

BTW: I am just running these tests on your patch and it seems to work quite well. (I will let it run over night) If it survives that I will also throw some quite complicated /dev/zero tests on it later.

Great! Is there a way to capture tests written by individual developers and testers and have them be shared, so everyone can use them (when there are no licensing/copyright issues)? I would definitely like to get your test programs and throw them at the kernel myself. Lets talk offline if you are willing to share your tests.

Unfortunately I do not have web/ftp space to put the programs on, but they are in the attachments. I normally run them in two steps:
1) Many processes runing against a nunber of segments which fit into the main memory.
2) 2 processes wich access more segments so they get it swapping. All processes run with 20% probability for deletion.

My tests with your patch went so far mostly well. The machine locks up after some while or kills init, but this is AFAICS stock behaviour.

One bug was introduced by your patch. On swapoff we get an oops:

ksymoops 0.7c on i686 2.3.50. Options used

     -V (default)
     -K (specified)
     -l /proc/modules (default)
     -o /lib/modules/2.3.50/ (default)
     -m /boot/System.map-2.3.50 (specified)

No modules in ksyms, skipping objects
No ksyms, skipping lsmod

Unable to handle kernel NULL pointer dereference at virtual address 00000000
*pde = 21118001
Oops: 0000
CPU:    7
EIP:    0010:[<c0185d17>]

Using defaults from ksymoops -t elf32-i386 -a i386
EFLAGS: 00010246
eax: 00000000 ebx: 00000000 ecx: 00000000 edx: 00000000
esi: 00000000 edi: c029ac74 ebp: c0185474 esp: d1c63f24
ds: 0018 es: 0018 ss: 0018
Process swapoff (pid: 624, stackpage=d1c63000)

Stack: c029ac74 c032cb74 c19daa94 02944c00 00000000 c0186889 c029ac74 02944c00 
       c19daa94 00000001 c19daa94 02944c00 0002944c c0185e62 02944c00 c19daa94 
       c02aa000 c19daa94 02944c00 c013baa7 02944c00 c19daa94 d1c62000 00000000 
Call Trace: [<c0186889>] [<c0185e62>] [<c013baa7>] [<c013bec9>] [<c010b49c>] 
Code: 8b 14 91 8b 04 da 89 44 24 10 0b 44 da 04 74 3e 8b 04 da 8b 
Quoted 1 line
Quoted 1 line

EIP; c0185d17 <shm_unuse_core+33/90> <=====

Trace; c0186889 <zmap_unuse+121/1d8>
Trace; c0185e62 <shm_unuse+ee/f8>
Trace; c013baa7 <try_to_unuse+1fb/3a0>
Trace; c013bec9 <sys_swapoff+27d/4b8>
Trace; c010b49c <system_call+34/38>
Code; c0185d17 <shm_unuse_core+33/90>
00000000 <_EIP>:
Code; c0185d17 <shm_unuse_core+33/90> <=====
0: 8b 14 91 movl (%ecx,%edx,4),%edx <=====
Code; c0185d1a <shm_unuse_core+36/90>
3: 8b 04 da movl (%edx,%ebx,8),%eax
Code; c0185d1d <shm_unuse_core+39/90>
6: 89 44 24 10 movl %eax,0x10(%esp,1)
Code; c0185d21 <shm_unuse_core+3d/90>
a: 0b 44 da 04 orl 0x4(%edx,%ebx,8),%eax
Code; c0185d25 <shm_unuse_core+41/90>
e: 74 3e je 4e <_EIP+0x4e> c0185d65 <shm_unuse_core+81/90>
Code; c0185d27 <shm_unuse_core+43/90>
10: 8b 04 da movl (%edx,%ebx,8),%eax
Code; c0185d2a <shm_unuse_core+46/90>
13: 8b 00 movl (%eax),%eax

Greetings
Christoph

#include <stdlib.h>
#include <stdio.h>

#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int main (int ac, char **av) {

	int segs, size, proc, rmpr;
	unsigned long long iter;
	struct shmid_ds buf;
	pid_t pid;

	if (ac < 6) {
		printf ("usage: shmtst segs size proc iter rm%%\n");
		exit (1);
	}
	segs = atoi (av[1]);
	size = atoi (av[2]);
	proc = atoi (av[3]);
	iter = atoi (av[4]);
	rmpr = atoi (av[5]);

	iter = 1 << iter;
	printf ("using %d segs of size %d (%llu iterations)\n", 
		segs, size, iter);
	while (-- proc) {
		if ((pid = fork()) > 0) {
			printf ("started process %d\n", (int) pid);
		} else {
			break;
		}
	}
	srandom (getpid());
	while (iter--) {
		key_t key;
		int seg, i;
		unsigned char c, *ptr;
		volatile unsigned char *p;

		key = random() % segs +1;
		if ((seg = shmget (key, size, IPC_CREAT| 0600)) == -1) {
			perror("shmget");
			if (errno != EIDRM)
				exit (1);
			continue;
		}
		if (0) sched_yield();
		if ((ptr = shmat (seg, 0, 0)) == (unsigned char *) -1) {
			perror ("shmat");
			continue;
		}
		for (p = ptr; p < ptr + size; p += 4097)
			*p = (unsigned char) (p - ptr);
		for (p = ptr; p < ptr + size; p += 4097) {
			c = *p;
			if (c == (unsigned char)(p-ptr)) 
				continue;
			shmctl (seg, IPC_STAT, &buf);
			printf ("n=%i, m = %i: %i != %i", (int) buf.shm_nattch,
				(int)buf.shm_perm.mode,
				(int)(unsigned char)(p-ptr), (int) c);
			for (i = 0 ; i < 5; i++) {
				printf (", %i", (int)*p);
				sched_yield();
			}
			printf ("\n");
		}

		if (shmdt (ptr) != 0) {
			perror("shmdt");
			exit (1);
		}
		if (random () % 100 < rmpr &&
		    shmctl (seg, IPC_RMID, NULL) == -1) 
			perror("shmctl IPC_RMID");
	}
}	

#include <stdlib.h>
#include <stdio.h>

#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>

int main (int ac, char **av) {

	int segs, size, proc, rmpr;
	unsigned long long iter;
	pid_t pid;
	struct stat buf;

	if (ac < 6) {
		printf ("usage: shmtst segs size proc iter rm%%\n");
		exit (1);
	}
	segs = atoi (av[1]);
	size = atoi (av[2]);
	proc = atoi (av[3]);
	iter = atoi (av[4]);
	rmpr = atoi (av[5]);

	iter = 1 << iter;
	printf ("using %d segs of size %d (%llu iterations)\n", 
		segs, size, iter);
	while (-- proc) {
		if ((pid = fork()) > 0) {
			printf ("started process %d\n", (int) pid);
		} else {
			break;
		}
	}
	srandom (getpid());
	while (iter--) {
		int seg, key;
		char name[20];
		char *ptr, *p;

		key = random() % segs;
		sprintf (name, "my%d", key);
		if ((seg = shm_open (name, O_CREAT| O_RDWR , 0666)) == -1) {
			perror("shm_open");
			exit (1);
		}
	        if (ftruncate (seg, size) == -1) {
			perror ("ftruncate");
			exit (2);
		}
	        if ((ptr = mmap (0, size, PROT_READ|PROT_WRITE,MAP_SHARED,
				 seg, 0)) == MAP_FAILED) {	
			perror ("mmap");
			exit (3);
		}
		for (p = ptr; p < ptr + size; p += 4097)
			*p = (char) p;
		for (p = ptr; p < ptr + size; p += 4097)
			if (*p != (char)p)
				printf ("*p(%i) != p(%i)\n", (int)*p, (int)p & 0xff);

	    	if (munmap (ptr, size) == -1)
			perror ("munmap");

	    	if (close(seg) == -1)
			perror ("close");

		if (random () % 100 < rmpr &&
		    shm_unlink (name) == -1) 
			perror("shm_unlink");
	}
}	

#include <asm/unistd.h>
#include <errno.h>

#define PREFIX "/var/shm"
int shm_open (const char *pathname, int flags, int mode) {

	char name[strlen(pathname) + sizeof(PREFIX)];
	sprintf (name, PREFIX "/%s", pathname);
	return open (name, flags, mode);
}
int shm_unlink(const char *pathname){
	char name[strlen(pathname) + sizeof(PREFIX)];
	sprintf (name, PREFIX "/%s", pathname);
	return unlink (name);
}
#28 lore raw

Re: [PATCH] Re: kswapd

In reply to a message not in the archive
Quoted 9 lines · [email protected] (Kanoj Sarcar) writes:

What is the problem that your patch is fixing?

                do {
                        /* kswapd is critical to provide GFP_ATOMIC
                           allocations (not GFP_HIGHMEM ones). */
                        if (nr_free_pages() - nr_free_highpages() >=

freepages.high)

Quoted 8 lines
                                break;
                        if (!do_try_to_free_pages(GFP_KSWAPD, 0))
                                break;
                        run_task_queue(&tq_disk);
                } while (!tsk->need_resched);
                tsk->state = TASK_INTERRUPTIBLE;
                interruptible_sleep_on(&kswapd_wait);
        }

Hmm. This loop runs until either
(a) it has free pages or
(b) it has used up it's time slice.

Quoted 27 lines
Quoted 27 lines
mm/vmscan.c renamed from mm/vmscan.c.orig +9 -10
@@ -499,19 +499,19 @@
 		 * the processes needing more memory will wake us
 		 * up on a more timely basis.
 		 */
-		do {
-			pgdat = pgdat_list;
-			while (pgdat) {
-				for (i = 0; i < MAX_NR_ZONES; i++) {
-					zone = pgdat->node_zones + i;
- if ((!zone->size) || (!zone->zone_wake_kswapd))
 
-						continue;
-					do_try_to_free_pages(GFP_KSWAPD, zone);
-				}
-				pgdat = pgdat->node_next;
+		pgdat = pgdat_list;
+		while (pgdat) {
+			for (i = 0; i < MAX_NR_ZONES; i++) {
+				zone = pgdat->node_zones + i;
+				if (tsk->need_resched)
+					schedule();
+				if ((!zone->size) || (!zone->zone_wake_kswapd))
+					continue;
+				do_try_to_free_pages(GFP_KSWAPD, zone);
 			}
Quoted 8 lines
Quoted 8 lines
mm/vmscan.c renamed from mm/vmscan.c.orig +3 -2
-			run_task_queue(&tq_disk);
-		} while (!tsk->need_resched);
+			pgdat = pgdat->node_next;
+		}
+		run_task_queue(&tq_disk);
 		tsk->state = TASK_INTERRUPTIBLE;
 		interruptible_sleep_on(&kswapd_wait);

}

The removed loop runs until a reschedule is needed. Having enough memory isn't sufficient to get out of the loop. So it can spin in run_task_queue(&tq_disk);

The added loop runs only while (pgdat). Running out of time slice will put it to sleep now.

Eric
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#29 lore raw

Re: [RFT] balancing patch

In reply to a message not in the archive
Quoted 4 lines · [email protected] (Kanoj Sarcar) writes:

People who are experiencing degraded performance in the latest 2.3 releases due to overactive kswapd can apply the attached patch to see whether it helps them. If you try the patch, and see that it helps, or hinders, your system performance, please let me know.

I did not see degraded performance but tested it anyway with my shm stress tests.

2.3.99-pre3 is the first release which handles 11.5GB shared mem trashing on my 8GB machine without choking.

But adding your patch leads again to random process killed and other oom situations when it has to go into swap.

Greetings
Christoph

Signature · 4 lines
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/
#30 lore raw

Re: The 4GB memory thing

Quoted 4 lines · [email protected] (Kanoj Sarcar) writes:

I have a 2.2 patch for 4Gb support, which has seen a lot of stress testing by now. The 2.3 >2gb support uses a different (and better approach), but last I checked, things like rawio did not work above

Quoted 1 line

2Gb. The 64Gb support is completely new ...

2.2.13aa3 includes both 4g bigmem support and rawio and you can do rawio on all the memory (bigmem included).

	ftp://ftp.*.kernel.org/pub/linux/kernel/people/andrea/kernels/v2.2/2.2.13aa3/

This is the README on how to go in sync with 2.2.13aa3:

ftp://ftp.*.kernel.org/pub/linux/kernel/people/andrea/tools/apply-patches/README.gz

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/
#31 lore raw

Re: The 4GB memory thing

Quoted 8 lines
Quoted 4 lines · [email protected] (Kanoj Sarcar) writes:

I have a 2.2 patch for 4Gb support, which has seen a lot of stress testing by now. The 2.3 >2gb support uses a different (and better approach), but last I checked, things like rawio did not work above

Quoted 1 line

2Gb. The 64Gb support is completely new ...

Quoted 12 lines

2.2.13aa3 includes both 4g bigmem support and rawio and you can do rawio on all the memory (bigmem included).

	ftp://ftp.*.kernel.org/pub/linux/kernel/people/andrea/kernels/v2.2/2.2.13aa3/

This is the README on how to go in sync with 2.2.13aa3:

ftp://ftp.*.kernel.org/pub/linux/kernel/people/andrea/tools/apply-patches/README.gz

Signature · 1 line
Andrea

I don't see a README.gz under
http://www.kernel.org/pub/linux/kernel/people/andrea/tools/apply-patches/

In any case, did you a have a small technical README on how rawio works on bigmem in 2.2.13aa3? Btw, I haven't seen the rawio 2.2 port, I am assuming its very similar to 2.3 ... where brw_kiovec() refuses to accept PageHighMem pages. I didn't see anything in z-bigmem-2.2.13aa3-7 that tinkers either with fs/buffer.c.

Thanks.

Kanoj
--
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/

#32 lore raw

Re: The 4GB memory thing

Quoted 2 lines · Kanoj Sarcar

assuming its very similar to 2.3 ... where brw_kiovec() refuses to accept PageHighMem pages. [...]

(btw, i have removed this limitation already in my tree, now that ll_rw_block() accepts highmem pages 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/

#33 lore raw

Re: The 4GB memory thing

Quoted 12 lines · Kanoj Sarcar
Quoted 3 lines

assuming its very similar to 2.3 ... where brw_kiovec() refuses to accept PageHighMem pages. [...]

(btw, i have removed this limitation already in my tree, now that ll_rw_block() accepts highmem pages as well.)

-- mingo

Ohh! Are you talking about ll_rw_block() in your tree, or in 2.3.25? If in 2.3.25, where was the bouncing added?

Kanoj
--
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/

#34 lore raw

Re: The 4GB memory thing

Quoted 8 lines · Kanoj Sarcar
Quoted 5 lines
Quoted 2 lines

assuming its very similar to 2.3 ... where brw_kiovec() refuses to accept PageHighMem pages. [...]

(btw, i have removed this limitation already in my tree, now that ll_rw_block() accepts highmem pages as well.)

Ohh! Are you talking about ll_rw_block() in your tree, or in 2.3.25? If in 2.3.25, where was the bouncing added?

my tree.

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/

#35 lore raw

RFC 1/1 mapping parts of shared memory

Hi,

I was investigating for some time about the possibility to create some object which allows me to map and unmap parts of it it in different processes. This would help to take advantage of the high memory systems with applications like SAP R/3 which uses a small number of processes to server many clients. It is now limited by the available address space for one process.

I see the following possibilties (in decreasing order of acceptance):

1) use posix shm (shm_open and mmap).
- This is not (yet?) implemented in Linux.
+ standard API which fits cleanly into the UNIX API

2) add a flag to mmap(2) which replaces the filedescriptor with a shm segment identifier.
- nonstandard API extension
+ easy to implement
+ consistent user API since you use /mmap/munmap like for shm_open

3) add a command to shmctl(2) which allows to map arbitrary page ranges out of a shm segment.
- nonstandard API extension
- inconsistent user API since you use shmctl for map and munmap() for unmap
+ easy to implement
+ less intrusive than 2) since it is local to shm

4) open a regular file and mmap(2).
+ works without changes
- It syncs on unmap which kills performance badly
- You have to reserve the same amount of disk space on your filesystem as you will ues memory. This is like the old UNIX swap behaviour.
- The user cannot tune the virtual memory space solely by adding swap space.

The appended a patch which implements 2) for i386. It can be easily extended for other architectures also.

I would really like to see 1), but I do not see how to implement this best:

a) eric biedermann is working on shmfs for some time. It seems to be a lot of work and not for the near future. It has also the drawback that you have to know where the filesystem is mounted.
b) We could extend sysv shm to add the call shm_open. This would be much less intrusive than the filesystem. It could be completely done in shm.c. I see the following possibilities:
i) This could be done in the same way like unix domain sockets allocate the sockets in the normal name space. But here we run into the same problems like unix domain sockets: stale files without a reflecting object.
ii) create your own name space without reflecting it in the
filesystem. But how do I provide a dentry for such a filedecriptor?

Any comments?
Christoph

arch/i386/kernel/sys_i386.c +15 -1
diff -uNr 2.3.28/arch/i386/kernel/sys_i386.c make28/arch/i386/kernel/sys_i386.c
@@ -73,7 +73,21 @@
 		file = fget(a.fd);
 		if (!file)
 			goto out;
-	}
+	} else if (a.flags & MAP_SYSV) {
+                int shmflg;
+                unsigned long raddr;
+                error = -EINVAL;
+                if (!(a.flags & MAP_SHARED))
+                        goto out;
+                
+                shmflg = (((a.flags | MAP_FIXED) ? 0 : SHM_RND) | 
+                          (a.addr ? SHM_REMAP : 0));
+                unlock_kernel();
+                error = shmmap (a.fd, a.addr, a.prot, shmflg, &raddr,
+                              1, a.len, a.offset);
+                return error ? error : raddr;
+        }
+
 	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 
 	error = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset);
include/asm-i386/mman.h +1 -0
diff -uNr 2.3.28/include/asm-i386/mman.h make28/include/asm-i386/mman.h
@@ -8,6 +8,7 @@
 
 #define MAP_SHARED	0x01		/* Share changes */
 #define MAP_PRIVATE	0x02		/* Changes are private */
+#define MAP_SYSV	0x04		/* Map SYSV shm segment */
 #define MAP_TYPE	0x0f		/* Mask for type of mapping */
 #define MAP_FIXED	0x10		/* Interpret addr exactly */
 #define MAP_ANONYMOUS	0x20		/* don't use a file */
include/linux/shm.h +2 -0
diff -uNr 2.3.28/include/linux/shm.h make28/include/linux/shm.h
@@ -74,6 +74,8 @@
 asmlinkage long sys_shmat (int shmid, char *shmaddr, int shmflg, unsigned long *addr);
 asmlinkage long sys_shmdt (char *shmaddr);
 asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds *buf);
+long shmmap (int shmid, unsigned long shmaddr, unsigned long prot, int shmflg,
+             ulong *raddr, int extended, size_t len, off_t off);
 extern void shm_unuse(swp_entry_t entry, struct page *page);
 
 #endif /* __KERNEL__ */
ipc/shm.c +40 -18

122 lines not on this page · raw message

--
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/

#36 lore raw

Re: [RFC] mapping parts of shared memory

Quoted 10 lines

Hi,

I was investigating for some time about the possibility to create some object which allows me to map and unmap parts of it it in different processes. This would help to take advantage of the high memory systems with applications like SAP R/3 which uses a small number of processes to server many clients. It is now limited by the available address space for one process.

Lets see if I am understanding the problem right. Currently, you may have an ia32 box with 8G memory, unfortunately, your server can make use of at most (say) 3G worth of shared memory. Hence, you are worried about how to be able to use the other 5G, lets say with more server processes.

What prevents your app from creating say 2 shm segments, each around 2.5G or so? That will let you attach in and use about 5G between 2 server processes. What have you lost with this approach that you will get with the kernel approach?

Kanoj

--
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/

#37 lore raw

RFC 1/1 Shared /dev/zero mmaping feature

Hi all,

This is a patch against 2.3.47 that tries to implement shared /dev/zero mappings. This is just a first cut attempt, I am hoping I will find a few people to apply the patch and throw some real life programs at it (preferably on low memory machines so that swapping is induced).

Currently, you will also need to turn on CONFIG_SYSVIPC, but most of the shm.c code can be split into a new ipc/shm_core.c file that is always compiled in, irrespective of CONFIG_SYSVIPC. Linus, do you think this is the proper direction to follow?

Thanks. Comments and feedback welcome ...

Kanoj

char/mem.c +5 -1
@@ -433,8 +433,12 @@
 
 static int mmap_zero(struct file * file, struct vm_area_struct * vma)
 {
+	int ret;
+	extern int map_zero_setup(struct vm_area_struct *);
+
 	if (vma->vm_flags & VM_SHARED)
-		return -EINVAL;
+		if (ret = map_zero_setup(vma))
+			return ret;
 	if (zeromap_page_range(vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot))
 		return -EAGAIN;
 	return 0;
shm.c +297 -96

545 lines not on this page · raw message

util.c +5 -0
@@ -317,4 +317,9 @@
 {
 }
 
+int map_zero_setup(struct vm_area_struct *vma)
+{
+	return -EINVAL;
+}
+
 #endif /* CONFIG_SYSVIPC */

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#38 lore raw

Re: [RFC] [RFT] Shared /dev/zero mmaping feature

Quoted 5 lines · Kanoj Sarcar

This is a patch against 2.3.47 that tries to implement shared /dev/zero mappings. This is just a first cut attempt, I am hoping I will find a few people to apply the patch and throw some real life programs at it (preferably on low memory machines so that swapping is induced).

I'd like to see the shm code use the page cache exclusively to track pages, and this is going to mess with that, I think. We'll need an inode (or at least a "struct address_space") to act as a "anchor" for the pages, and it mustn't be the "/dev/zero" inode.

Before that is done I'd be nervous about letting external things call into the shm subsystem, but maybe this is ok as-is (the only thing you really export is "map_zero_setup()", and I guess it can just be updated as required..)

However, whether that will be changed or not, the following looks really wrong:

char/mem.c line 443

Quoted 5 lines

if (vma->vm_flags & VM_SHARED)

		if (ret = map_zero_setup(vma))
			return ret;
char/mem.c +0 -0
 	if (zeromap_page_range(vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot))
 		return -EAGAIN;

I do NOT believe that it can ever be right to do a "zeromap_page_range()" on a shared memory area. I'll tell you why:

	mmap(/dev/zero, MAP_SHARED)
	child = fork();
	if (child) {
		..modify mapping..
	} else {
		..wait for modifications to show up..
	}

the "zeromap_page_range()" thing mapped the area with private NULL pages. The fork() copied the page tables. The modification of the private NULL page causes the child to get a real shared page, but the mother will never see that shared page if it only reads from the mapping because the mother will still see the private one.

So I suspect at the very least it would have to be

	if (vma->vm_flags & VM_SHARED)
		return map_zero_setup(vma);

and let the whole area be populated with shared pages by "nopage".

Comments?

Linus

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#39 lore raw

Re: [RFC] [RFT] Shared /dev/zero mmaping feature

Quoted 11 lines

I'd like to see the shm code use the page cache exclusively to track pages, and this is going to mess with that, I think. We'll need an inode (or at least a "struct address_space") to act as a "anchor" for the pages, and it mustn't be the "/dev/zero" inode.

Before that is done I'd be nervous about letting external things call into the shm subsystem, but maybe this is ok as-is (the only thing you really export is "map_zero_setup()", and I guess it can just be updated as required..)

Yes, as you point out, we can put in this code now. Whatever changes are made to the underlying routines that manage shm pages, should also be able to handle /dev/zero pages with minor tweaks. The chances that the /dev/zero code will be a big hindrance to the page cache effort are minimal ...

Quoted 8 lines

However, whether that will be changed or not, the following looks really wrong:

Quoted 5 lines

if (vma->vm_flags & VM_SHARED)

		if (ret = map_zero_setup(vma))
			return ret;
(quoted diff) +0 -0
 	if (zeromap_page_range(vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot))
 		return -EAGAIN;

Yes, you are right. I have made the change in the attached patch. I also added in some checks so that users can not shmctl/shmat to the shmid being used for /dev/zero.

Does this look ready for 2.3.48 then?

Kanoj

char/mem.c +4 -1
@@ -5,6 +5,7 @@
  *
  *  Added devfs support. 
  *    Jan-11-1998, C. Scott Ananian <[email protected]>
+ *  Shared /dev/zero mmaping support, Feb 2000, Kanoj Sarcar <[email protected]>
  */
 
 #include <linux/config.h>
@@ -433,8 +434,10 @@
 
 static int mmap_zero(struct file * file, struct vm_area_struct * vma)
 {
+	extern int map_zero_setup(struct vm_area_struct *);
+
 	if (vma->vm_flags & VM_SHARED)
-		return -EINVAL;
+		return(map_zero_setup(vma));
 	if (zeromap_page_range(vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot))
 		return -EAGAIN;
 	return 0;
shm.c +313 -96

591 lines not on this page · raw message

util.c +5 -0
@@ -317,4 +317,9 @@
 {
 }
 
+int map_zero_setup(struct vm_area_struct *vma)
+{
+	return -EINVAL;
+}
+
 #endif /* CONFIG_SYSVIPC */

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

A message that is not in the archive (sent off-list or not yet received): [email protected]

#41 lore raw

[PATCH] Re: kswapd

Quoted 1 line · Russell King

I think I've solved (very dirtily) my kswapd problem

Your patch is the correct one. I've added an extra reschedule point and cleaned up the code a little bit. I wonder who sent the brown-paper-bag patch with the superfluous while loop to
Linus ... (please raise your hand and/or buy rmk a beer)

Linus, could you please apply this patch ASAP? :)

regards,

Rik (PS. I'm still planning to implement the VM changes I posted to linux-mm earlier today, kswapd could be better and more efficient) --
The Internet is not a network of computers. It is a network of people. That is its real strength.

Wanna talk about the kernel? irc.openprojects.net / #kernelnewbies
http://www.conectiva.com/ http://www.surriel.com/

mm/vmscan.c renamed from mm/vmscan.c.orig +12 -12
@@ -499,19 +499,19 @@
 		 * the processes needing more memory will wake us
 		 * up on a more timely basis.
 		 */
-		do {
-			pgdat = pgdat_list;
-			while (pgdat) {
-				for (i = 0; i < MAX_NR_ZONES; i++) {
-					zone = pgdat->node_zones + i;
-					if ((!zone->size) || (!zone->zone_wake_kswapd))
-						continue;
-					do_try_to_free_pages(GFP_KSWAPD, zone);
-				}
-				pgdat = pgdat->node_next;
+		pgdat = pgdat_list;
+		while (pgdat) {
+			for (i = 0; i < MAX_NR_ZONES; i++) {
+				zone = pgdat->node_zones + i;
+				if (tsk->need_resched)
+					schedule();
+				if ((!zone->size) || (!zone->zone_wake_kswapd))
+					continue;
+				do_try_to_free_pages(GFP_KSWAPD, zone);
 			}
-			run_task_queue(&tq_disk);
-		} while (!tsk->need_resched);
+			pgdat = pgdat->node_next;
+		}
+		run_task_queue(&tq_disk);
 		tsk->state = TASK_INTERRUPTIBLE;
 		interruptible_sleep_on(&kswapd_wait);
 	}

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#42 lore raw

Re: [PATCH] Re: kswapd

Quoted 9 lines · Russell King
Quoted 2 lines

I think I've solved (very dirtily) my kswapd problem

Your patch is the correct one. I've added an extra reschedule point and cleaned up the code a little bit. I wonder who sent the brown-paper-bag patch with the superfluous while loop to
Linus ... (please raise your hand and/or buy rmk a beer)

That would be me ...

What is the problem that your patch is fixing? Other than the while loop cosmetic changes, the only thing I see is to do with rescheduling (ie, do not invoke do_try_to_free_pages or run_task_queue() if need_resched is set). Note that before this patch went in, as in 2.3.43 for example, the loop used to be:

                do {
                        /* kswapd is critical to provide GFP_ATOMIC
                           allocations (not GFP_HIGHMEM ones). */
                        if (nr_free_pages() - nr_free_highpages() >= freepages.high)
                                break;
                        if (!do_try_to_free_pages(GFP_KSWAPD, 0))
                                break;
                        run_task_queue(&tq_disk);
                } while (!tsk->need_resched);
                tsk->state = TASK_INTERRUPTIBLE;
                interruptible_sleep_on(&kswapd_wait);
        }

Which is the behavior I _tried_ to preserve. Oh, btw, I am not convinced that you should do a run_task_queue after _all_ pgdats have been scanned, rather than after each one.

Kanoj

Quoted 52 lines

Linus, could you please apply this patch ASAP? :)

regards,

Rik (PS. I'm still planning to implement the VM changes I posted to linux-mm earlier today, kswapd could be better and more efficient) --
The Internet is not a network of computers. It is a network of people. That is its real strength.

Wanna talk about the kernel? irc.openprojects.net / #kernelnewbies
http://www.conectiva.com/ http://www.surriel.com/

mm/vmscan.c renamed from mm/vmscan.c.orig +12 -13
@@ -499,19 +499,19 @@
 		 * the processes needing more memory will wake us
 		 * up on a more timely basis.
 		 */
-		do {
-			pgdat = pgdat_list;
-			while (pgdat) {
-				for (i = 0; i < MAX_NR_ZONES; i++) {
-					zone = pgdat->node_zones + i;
-					if ((!zone->size) || (!zone->zone_wake_kswapd))
-						continue;
-					do_try_to_free_pages(GFP_KSWAPD, zone);
-				}
-				pgdat = pgdat->node_next;
+		pgdat = pgdat_list;
+		while (pgdat) {
+			for (i = 0; i < MAX_NR_ZONES; i++) {
+				zone = pgdat->node_zones + i;
+				if (tsk->need_resched)
+					schedule();
+				if ((!zone->size) || (!zone->zone_wake_kswapd))
+					continue;
+				do_try_to_free_pages(GFP_KSWAPD, zone);
 			}
-			run_task_queue(&tq_disk);
-		} while (!tsk->need_resched);
+			pgdat = pgdat->node_next;
+		}
+		run_task_queue(&tq_disk);
 		tsk->state = TASK_INTERRUPTIBLE;
 		interruptible_sleep_on(&kswapd_wait);
 	}
 
--
Quoted 4 lines

To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#43 lore raw

Re: [PATCH] Re: kswapd

Quoted 4 lines · Kanoj Sarcar
Quoted 4 lines · Russell King
Quoted 2 lines

I think I've solved (very dirtily) my kswapd problem

Quoted 8 lines
Quoted 4 lines

Your patch is the correct one. I've added an extra reschedule point and cleaned up the code a little bit. I wonder who sent the brown-paper-bag patch with the superfluous while loop to
Linus ... (please raise your hand and/or buy rmk a beer)

That would be me ...

What is the problem that your patch is fixing?

Removing the superfluous while loop.

Without my patch kswapd uses between 50 and 70% CPU time in a particular workload. Now it uses between 3 and 5%. Oh, and the latency problem probably has been fixed too...

cheers,

Rik
--
The Internet is not a network of computers. It is a network of people. That is its real strength.

Wanna talk about the kernel? irc.openprojects.net / #kernelnewbies
http://www.conectiva.com/ http://www.surriel.com/

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#44 lore raw

Re: [PATCH] Re: kswapd

Quoted 11 lines · Kanoj Sarcar
Quoted 9 lines
Quoted 8 lines · Russell King
Quoted 2 lines

I think I've solved (very dirtily) my kswapd problem

Your patch is the correct one. I've added an extra reschedule point and cleaned up the code a little bit. I wonder who sent the brown-paper-bag patch with the superfluous while loop to
Linus ... (please raise your hand and/or buy rmk a beer)

Quoted 6 lines
Quoted 3 lines

That would be me ...

What is the problem that your patch is fixing?

Removing the superfluous while loop.

Maybe I am being stupid, but where is the superfluous loop? Remember, as I just pointed out, 2.3.43 had the same loop, are you claiming it was buggy even then?

Quoted 2 lines

Without my patch kswapd uses between 50 and 70% CPU time in a particular workload. Now it uses between 3 and 5%.

Can you explain how this is happening? I can see that in your patch, kswapd does not go thru the loop if need_resched is set, but with a single node, 3 zones, I would find it hard to explain such a difference.

Quoted 1 line

Oh, and the latency problem probably has been fixed too...

What latency problem? I still believe that the pre3 code is doing the right thing, assuming 2.3.43 was doing the right thing.

Kanoj

Quoted 11 lines

cheers,

Rik
--
The Internet is not a network of computers. It is a network of people. That is its real strength.

Wanna talk about the kernel? irc.openprojects.net / #kernelnewbies
http://www.conectiva.com/ http://www.surriel.com/

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#45 lore raw

Re: [PATCH] Re: kswapd

Quoted 7 lines · Kanoj Sarcar
Quoted 2 lines

Without my patch kswapd uses between 50 and 70% CPU time in a particular workload. Now it uses between 3 and 5%.

Can you explain how this is happening? I can see that in your patch, kswapd does not go thru the loop if need_resched is set, but with a single node, 3 zones, I would find it hard to explain such a difference.

kswapd was running until it had a quantum, whether or not it had to free any more pages.

Quoted 4 lines
Quoted 1 line

Oh, and the latency problem probably has been fixed too...

What latency problem? I still believe that the pre3 code is doing the right thing, assuming 2.3.43 was doing the right thing.

Check out the linux-kernel archives, specifically for my mails about NFS/sound problems - it is not good for processes (eg, rpciod) to be starved of CPU time up to 200-400ms. It was basically impossible to play mp3s without the playback basically "stopping" for that period.

(without the patch in, I see kswapd using 200ms-400ms. With the patch in, it only uses >10ms very very rarely).
_____

  |_____| ------------------------------------------------- ---+---+-
  |   |         Russell King        [email protected]      --- ---
  | | | |   http://www.arm.linux.org.uk/~rmk/aboutme.html    /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#46 lore raw

Re: [PATCH] Re: kswapd

In reply to Kanoj Sarcar
Quoted 2 lines · Kanoj Sarcar

What is the problem that your patch is fixing?

I agree with Rik's patch - the old behaviour kicked us out of the regular loop whenever "need_resched" was set, and that is not necessarily a good idea at all.

Quoted 1 line

From a conceptual standpoint, going to sleep when "need_resched" gets set

is not the right thing at all - the flag doesn't really have any bearing on whether kswapd should sleep, it only has meaning from a scheduling latency standpoint (ie "need_resched" does not mean "go to sleep", it means "let somebody else run now" - different things).

On the other hand you're definitely right that this is not a new bug introduced by you, Kanoj - this seems to be just a thinko that has been there for a long long time. And I suspect I may have been the original perpetrator of the crime.

The new code looks much saner: it reschedules when asked to, and it stops looping when it makes sense (ie when there is no longer any reason to free pages). Instead of mixing the two up.

Linus

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#47 lore raw

Re: [PATCH] Re: kswapd

Quoted 3 lines

On the other hand you're definitely right that this is not a new bug introduced by you, Kanoj - this seems to be just a thinko that has been

Whew, as long as I can keep that beer I was going to send to Russell on Rik's suggestion for myself! :-)

On a more serious note, I know too little about the application load that Rik/Russell is talking about to understand what's going on, but I have the vague suspicion that Rik's patch is just a part fix to the problem, and that maybe we might be doing too many kswapd wakes ups via the balancing code.

This is my reasoning: Rik's patch makes it so that before kswapd undertakes heavy weight work, it yields the cpu ... then it checks whether it has to do the work (via zone_wake_kswapd). This is the only difference over pre3. If this is improving things a lot, that makes me believe that the memory-low condition is subsiding (pages are being freed up) just after kswapd has yielded, and before it gets scheduled onto the cpu again. This depends on the app and its priority too, I guess. If there is an app load where the pages are not freed, Rik's patch would _probably_ not be able to help. Its better than nothing, but if you wanted to do the best you could, you need to add more yield points into the body of kswapd code (which I suspect will not be free of side effects possibly).

The other part about possibly doing too many kswapd wakeups is just a hunch, not directly related to this patch. I will forward a balancing patch on the mailing lists next for people to try.

Kanoj
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#48 lore raw

Re: [PATCH] Re: kswapd

Quoted 7 lines · Kanoj Sarcar

This is my reasoning: Rik's patch makes it so that before kswapd undertakes heavy weight work, it yields the cpu ... then it checks whether it has to do the work (via zone_wake_kswapd). This is the only difference over pre3. If this is improving things a lot, that makes me believe that the memory-low condition is subsiding (pages are being freed up) just after kswapd has yielded, and before it gets scheduled onto the cpu again.

This is not the case. CPU system time has decreased from 70% to 7% with the patch in. Kswapd uses about 5 of those 7%, so it is true that some of the work is done by the applications, but overall system time has decreased a lot.

Quoted 3 lines

This depends on the app and its priority too, I guess. If there is an app load where the pages are not freed, Rik's patch would _probably_ not be able to help.

In this case, nothing would help (except having your low-latency app completely free of memory allocations).

Quoted 4 lines

Its better than nothing, but if you wanted to do the best you could, you need to add more yield points into the body of kswapd code (which I suspect will not be free of side effects possibly).

One resched every do_try_to_free_pages() seems to be enough for most things, but it should be relatively easy to build some reschedule points into do_try_to_free_pages() (which can _only_ be called if current->state == TASK_RUNNING!!).

Quoted 3 lines

The other part about possibly doing too many kswapd wakeups is just a hunch, not directly related to this patch. I will forward a balancing patch on the mailing lists next for people to try.

Probably some hysteresis problem. Using all three freepages thresholds (min, low and high) solved the problem for zoneless MM, so it should probably work for a zoned VM too.

regards,

Rik
--
The Internet is not a network of computers. It is a network of people. That is its real strength.

Wanna talk about the kernel? irc.openprojects.net / #kernelnewbies
http://www.conectiva.com/ http://www.surriel.com/

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#49 lore raw

Re: [PATCH] Re: kswapd

In reply to Kanoj Sarcar
Quoted 5 lines · Kanoj Sarcar

This is my reasoning: Rik's patch makes it so that before kswapd undertakes heavy weight work, it yields the cpu ... then it checks whether it has to do the work (via zone_wake_kswapd). This is the only difference over pre3.

No, there's another difference: pre3 will loop forever, even if there is nothing to do - until something comes up that needs scheduling. Basically, the pre3 loop boils down to

	do {
		/* not interesting */
	} while (!tsk->need_resched);

when there is enough memory.

Which obviously causes excessive CPU to be wasted.

NOTE! The "obviously" is a bit strong. What happens is that kswapd is only woken up when needed, so most of the time it is sleeping. It's only when it is woken up and when it has done its work when the loop turns into a CPU-burner, but it can easily mean that kswapd will just spend CPU time for no good reason until its time-slice is exhausted.

So think of the bug as "kswapd will waste the final part of its timeslice doing nothing useful".

Linus

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#50 lore raw

Re: [PATCH] Re: kswapd

Quoted 2 lines

So think of the bug as "kswapd will waste the final part of its timeslice doing nothing useful".

yes! should it not look at the return from try_to_free_pages to find out whether further looping is needed? or something based on the current free pages level, hopefully with hysteresis like Rik mentioned?

regards, mark hahn.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#51 lore raw

Re: [PATCH] Re: kswapd

Quoted 5 lines · Mark Hahn

yes! should it not look at the return from try_to_free_pages to find out whether further looping is needed? or something based on the current free pages level, hopefully with hysteresis like Rik mentioned?

It does do that - that's what the "kswapd_wake_up" flag does for the loop. The problem was that the loop termination logic was a bit topsy-turvy.

Linus

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#52 lore raw

Re: [PATCH] Re: kswapd

In reply to Mark Hahn
Quoted 7 lines · Mark Hahn
Quoted 2 lines

So think of the bug as "kswapd will waste the final part of its timeslice doing nothing useful".

yes! should it not look at the return from try_to_free_pages to find out whether further looping is needed?
or something based on the current free pages level, hopefully with hysteresis like Rik mentioned?

It is looking at the current free page levels, on a zone-by-zone basis. Looking at the return value of try_to_free_pages() doesn't make much sense IMHO because that just means that normal processes will be doing the heavy work instead of kswapd (leading to poor interactive response and other trouble).

regards,

Rik
--
The Internet is not a network of computers. It is a network of people. That is its real strength.

Wanna talk about the kernel? irc.openprojects.net / #kernelnewbies
http://www.conectiva.com/ http://www.surriel.com/

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#53 lore raw

Re: [PATCH] Re: kswapd

In reply to Linus Torvalds
Quoted 4 lines

So think of the bug as "kswapd will waste the final part of its timeslice doing nothing useful".

Got it ... Thanks.

Makes you wonder whether the resched checking should be done for each zone, or once for the entire pgdat.

Kanoj
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#54 lore raw

Re: [PATCH] Re: kswapd

In reply to Kanoj Sarcar
Quoted 5 lines · Kanoj Sarcar

On a more serious note, I know too little about the application load that Rik/Russell is talking about to understand what's going on, but I have the vague suspicion that Rik's patch is just a part fix to the problem, and that maybe we might be doing too many kswapd wakes ups via the balancing code.

My situation is very simple - one copy of xaudio playing mp3s. Nothing else. No swapping. No nothing. Just one xaudio (and the occasional cron and atd running) playing mp3s from a NFS server. Load average < 1.
_____

  |_____| ------------------------------------------------- ---+---+-
  |   |         Russell King        [email protected]      --- ---
  | | | |   http://www.arm.linux.org.uk/~rmk/aboutme.html    /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#55 lore raw

[RFT] balancing patch

People who are experiencing degraded performance in the latest 2.3 releases due to overactive kswapd can apply the attached patch to see whether it helps them. If you try the patch, and see that it helps, or hinders, your system performance, please let me know.

Thanks.

Kanoj

page_alloc.c +7 -10
@@ -235,19 +235,16 @@
 		zone_t *z = *(zone++);
 		if (!z)
 			break;
-		if (z->free_pages > z->pages_low)
-			continue;
-
-		z->zone_wake_kswapd = 1;
-		wake_up_interruptible(&kswapd_wait);
 
 		/* Are we reaching the critical stage? */
-		if (!z->low_on_memory) {
-			/* Not yet critical, so let kswapd handle it.. */
-			if (z->free_pages > z->pages_min)
-				continue;
+		if (z->free_pages <= z->pages_min)
 			z->low_on_memory = 1;
+		if (z->free_pages <= z->pages_low) {
+			z->zone_wake_kswapd = 1;
+			wake_up_interruptible(&kswapd_wait);
 		}
+		if (!z->low_on_memory)
+			continue;
 		/*
 		 * In the atomic allocation case we only 'kick' the
 		 * state machine, but do not try to free pages
@@ -293,7 +290,7 @@
 			BUG();
 
 		/* Are we supposed to free memory? Don't make it worse.. */
-		if (!z->zone_wake_kswapd && z->free_pages > z->pages_low) {
+		if (!z->low_on_memory && z->free_pages > z->pages_min) {
 			struct page *page = rmqueue(z, order);
 			if (page)
 				return page;

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#56 lore raw

Re: [RFT] balancing patch

Quoted 2 lines

see whether it helps them. If you try the patch, and see that it helps, or hinders, your system performance, please let me know.

doesn't help: kswapd still wastes major CPU.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

#57 lore raw

Re: [RFT] balancing patch

Quoted 4 lines · Mark Hahn
Quoted 2 lines

see whether it helps them. If you try the patch, and see that it helps, or hinders, your system performance, please let me know.

doesn't help: kswapd still wastes major CPU.

I'm now testing Kanoj' balancing patch together with my kswapd infinite-loop-removal patch. The system seems to work quite well, I haven't seen any big strangeness in the VM load (the variance in the amount of free memory is a bit bigger, naturally, but that's to be expected) and interactive performance from the console seems unaffected.

It would be nice if a few more people tested the combination of 2.3.99-pre3 with Kanoj' balancing patch and my infinite-loop-
removal patch ... (because YMMV)

regards,

Rik
--
The Internet is not a network of computers. It is a network of people. That is its real strength.

Wanna talk about the kernel? irc.openprojects.net / #kernelnewbies
http://www.conectiva.com/ http://www.surriel.com/

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/