linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* Shared mmaps
@ 2001-03-04 21:10 Matthew Wilcox
  2001-03-05  0:59 ` Rik van Riel
  2001-03-05 10:52 ` Andi Kleen
  0 siblings, 2 replies; 6+ messages in thread
From: Matthew Wilcox @ 2001-03-04 21:10 UTC (permalink / raw)
  To: linux-mm

Sparc & IA64 use a flag in the task_struct to indicate that they're trying
to allocate an mmap which is shared.  That's really ugly, let's just pass
the flags in to the get_mapped_area function instead.  I had to invent a
new flag for this because mremap's flags are different to mmap's (bah!)

Comments?

----- Forwarded message from Matthew Wilcox <willy@ldl.fc.hp.com> -----

Index: arch/ia64/kernel/sys_ia64.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/ia64/kernel/sys_ia64.c,v
retrieving revision 1.5
diff -u -p -r1.5 sys_ia64.c
--- sys_ia64.c	2001/01/24 23:58:50	1.5
+++ sys_ia64.c	2001/03/04 20:09:48
@@ -22,7 +22,7 @@
 #define COLOR_ALIGN(addr)	(((addr) + SHMLBA - 1) & ~(SHMLBA - 1))
 
 unsigned long
-get_unmapped_area (unsigned long addr, unsigned long len)
+get_unmapped_area (unsigned long addr, unsigned long len, unsigned long flags)
 {
 	struct vm_area_struct * vmm;
 
@@ -31,7 +31,7 @@ get_unmapped_area (unsigned long addr, u
 	if (!addr)
 		addr = TASK_UNMAPPED_BASE;
 
-	if (current->thread.flags & IA64_THREAD_MAP_SHARED)
+	if (flags & _MAP_ALIGN)
 		addr = COLOR_ALIGN(addr);
 	else
 		addr = PAGE_ALIGN(addr);
@@ -45,6 +45,8 @@ get_unmapped_area (unsigned long addr, u
 		if (!vmm || addr + len <= vmm->vm_start)
 			return addr;
 		addr = vmm->vm_end;
+		if (flags & _MAP_ALIGN)
+			addr = COLOR_ALIGN(addr);
 	}
 }
 
@@ -198,13 +200,11 @@ do_mmap2 (unsigned long addr, unsigned l
 	}
 
 	if (flags & MAP_SHARED)
-		current->thread.flags |= IA64_THREAD_MAP_SHARED;
+		flags |= _MAP_ALIGN;
 
 	down(&current->mm->mmap_sem);
 	addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
 	up(&current->mm->mmap_sem);
-
-	current->thread.flags &= ~IA64_THREAD_MAP_SHARED;
 
 	if (file)
 		fput(file);
Index: arch/parisc/kernel/sys_parisc.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/sys_parisc.c,v
retrieving revision 1.8
diff -u -p -r1.8 sys_parisc.c
--- sys_parisc.c	2001/03/04 04:48:53	1.8
+++ sys_parisc.c	2001/03/04 20:09:48
@@ -1,7 +1,7 @@
 /*
  * linux/arch/parisc/kernel/sys_parisc.c
  *
- * this implements the missing syscalls.
+ * this implements syscalls which are handled per-arch.
  */
 
 #include <asm/uaccess.h>
@@ -10,8 +10,37 @@
 #include <linux/linkage.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
+#include <linux/shm.h>
 #include <linux/smp_lock.h>
 
+#define COLOUR_ALIGN(addr)      (((addr)+SHMLBA-1)&~(SHMLBA-1))
+
+unsigned long get_unmapped_area(unsigned long addr, unsigned long len, unsigned long flags)
+{
+	struct vm_area_struct * vmm;
+
+	if (len > TASK_SIZE)
+		return 0;
+	if (!addr)
+		addr = TASK_UNMAPPED_BASE;
+
+	if (flags & _MAP_ALIGN)
+		addr = COLOUR_ALIGN(addr);
+	else
+		addr = PAGE_ALIGN(addr);
+
+	for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
+		/* At this point:  (!vmm || addr < vmm->vm_end). */
+		if (TASK_SIZE - len < addr)
+			return 0;
+		if (!vmm || addr + len <= vmm->vm_start)
+			return addr;
+		addr = vmm->vm_end;
+		if (flags & _MAP_ALIGN)
+			addr = COLOUR_ALIGN(addr);
+	}
+}
+
 int sys_pipe(int *fildes)
 {
 	int fd[2];
@@ -46,6 +75,9 @@ int sys_mmap(unsigned long addr, unsigne
 	}
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 
+	if (flags & MAP_SHARED)
+		flags |= _MAP_ALIGN;
+
 	down(&current->mm->mmap_sem);
 	error = do_mmap(file, addr, len, prot, flags, offset);
 	up(&current->mm->mmap_sem);
@@ -56,10 +88,8 @@ out:
 	return error;
 }
 
-long sys_shmat_wrapper(int shmid, void *shmaddr, int shmflag)
+long sys_shmat_wrapper(int shmid, char *shmaddr, int shmflag)
 {
-	extern int sys_shmat(int shmid, char *shmaddr, int shmflg,
-			     unsigned long * raddr);
 	unsigned long raddr;
 	int r;
 
Index: arch/sparc/kernel/sys_sparc.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/sparc/kernel/sys_sparc.c,v
retrieving revision 1.5
diff -u -p -r1.5 sys_sparc.c
--- sys_sparc.c	2001/01/25 00:00:10	1.5
+++ sys_sparc.c	2001/03/04 20:09:48
@@ -36,7 +36,7 @@ asmlinkage unsigned long sys_getpagesize
 
 #define COLOUR_ALIGN(addr)      (((addr)+SHMLBA-1)&~(SHMLBA-1))
 
-unsigned long get_unmapped_area(unsigned long addr, unsigned long len)
+unsigned long get_unmapped_area(unsigned long addr, unsigned long len, unsigned long flags)
 {
 	struct vm_area_struct * vmm;
 
@@ -48,7 +48,7 @@ unsigned long get_unmapped_area(unsigned
 	if (!addr)
 		addr = TASK_UNMAPPED_BASE;
 
-	if (current->thread.flags & SPARC_FLAG_MMAPSHARED)
+	if (flags & _MAP_ALIGN)
 		addr = COLOUR_ALIGN(addr);
 	else
 		addr = PAGE_ALIGN(addr);
@@ -64,7 +64,7 @@ unsigned long get_unmapped_area(unsigned
 		if (!vmm || addr + len <= vmm->vm_start)
 			return addr;
 		addr = vmm->vm_end;
-		if (current->thread.flags & SPARC_FLAG_MMAPSHARED)
+		if (flags & _MAP_ALIGN)
 			addr = COLOUR_ALIGN(addr);
 	}
 }
@@ -234,14 +234,12 @@ static unsigned long do_mmap2(unsigned l
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 
 	if (flags & MAP_SHARED)
-		current->thread.flags |= SPARC_FLAG_MMAPSHARED;
+		flags |= _MAP_ALIGN;
 
 	down(&current->mm->mmap_sem);
 	retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
 	up(&current->mm->mmap_sem);
 
-	current->thread.flags &= ~(SPARC_FLAG_MMAPSHARED);
-
 out_putf:
 	if (file)
 		fput(file);
@@ -287,7 +285,7 @@ asmlinkage unsigned long sparc_mremap(un
 	down(&current->mm->mmap_sem);
 	vma = find_vma(current->mm, addr);
 	if (vma && (vma->vm_flags & VM_SHARED))
-		current->thread.flags |= SPARC_FLAG_MMAPSHARED;
+		flags |= _MAP_ALIGN;
 	if (flags & MREMAP_FIXED) {
 		if (ARCH_SUN4C_SUN4 &&
 		    new_addr < 0xe0000000 &&
@@ -301,14 +299,13 @@ asmlinkage unsigned long sparc_mremap(un
 		ret = -ENOMEM;
 		if (!(flags & MREMAP_MAYMOVE))
 			goto out_sem;
-		new_addr = get_unmapped_area (addr, new_len);
+		new_addr = get_unmapped_area (addr, new_len, flags);
 		if (!new_addr)
 			goto out_sem;
 		flags |= MREMAP_FIXED;
 	}
 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
 out_sem:
-	current->thread.flags &= ~(SPARC_FLAG_MMAPSHARED);
 	up(&current->mm->mmap_sem);
 out:
 	return ret;       
Index: arch/sparc64/kernel/sys_sparc.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/sparc64/kernel/sys_sparc.c,v
retrieving revision 1.7
diff -u -p -r1.7 sys_sparc.c
--- sys_sparc.c	2001/01/25 00:00:16	1.7
+++ sys_sparc.c	2001/03/04 20:09:48
@@ -42,7 +42,7 @@ asmlinkage unsigned long sys_getpagesize
 
 #define COLOUR_ALIGN(addr)	(((addr)+SHMLBA-1)&~(SHMLBA-1))
 
-unsigned long get_unmapped_area(unsigned long addr, unsigned long len)
+unsigned long get_unmapped_area(unsigned long addr, unsigned long len, unsigned long flags)
 {
 	struct vm_area_struct * vmm;
 	unsigned long task_size = TASK_SIZE;
@@ -54,7 +54,7 @@ unsigned long get_unmapped_area(unsigned
 	if (!addr)
 		addr = TASK_UNMAPPED_BASE;
 
-	if (current->thread.flags & SPARC_FLAG_MMAPSHARED)
+	if (flags & _MAP_ALIGN)
 		addr = COLOUR_ALIGN(addr);
 	else
 		addr = PAGE_ALIGN(addr);
@@ -72,7 +72,7 @@ unsigned long get_unmapped_area(unsigned
 		if (!vmm || addr + len <= vmm->vm_start)
 			return addr;
 		addr = vmm->vm_end;
-		if (current->thread.flags & SPARC_FLAG_MMAPSHARED)
+		if (flags & _MAP_ALIGN)
 			addr = COLOUR_ALIGN(addr);
 	}
 }
@@ -241,14 +241,12 @@ asmlinkage unsigned long sys_mmap(unsign
 	}
 
 	if (flags & MAP_SHARED)
-		current->thread.flags |= SPARC_FLAG_MMAPSHARED;
+		flags |= _MAP_ALIGN;
 
 	down(&current->mm->mmap_sem);
 	retval = do_mmap(file, addr, len, prot, flags, off);
 	up(&current->mm->mmap_sem);
 
-	current->thread.flags &= ~(SPARC_FLAG_MMAPSHARED);
-
 out_putf:
 	if (file)
 		fput(file);
@@ -288,7 +286,7 @@ asmlinkage unsigned long sys64_mremap(un
 	down(&current->mm->mmap_sem);
 	vma = find_vma(current->mm, addr);
 	if (vma && (vma->vm_flags & VM_SHARED))
-		current->thread.flags |= SPARC_FLAG_MMAPSHARED;
+		flags |= _MAP_ALIGN;
 	if (flags & MREMAP_FIXED) {
 		if (new_addr < PAGE_OFFSET &&
 		    new_addr + new_len > -PAGE_OFFSET)
@@ -297,14 +295,13 @@ asmlinkage unsigned long sys64_mremap(un
 		ret = -ENOMEM;
 		if (!(flags & MREMAP_MAYMOVE))
 			goto out_sem;
-		new_addr = get_unmapped_area(addr, new_len);
+		new_addr = get_unmapped_area(addr, new_len, flags);
 		if (!new_addr)
 			goto out_sem;
 		flags |= MREMAP_FIXED;
 	}
 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
 out_sem:
-	current->thread.flags &= ~(SPARC_FLAG_MMAPSHARED);
 	up(&current->mm->mmap_sem);
 out:
 	return ret;       
Index: arch/sparc64/kernel/sys_sparc32.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/sparc64/kernel/sys_sparc32.c,v
retrieving revision 1.9
diff -u -p -r1.9 sys_sparc32.c
--- sys_sparc32.c	2001/02/02 03:35:43	1.9
+++ sys_sparc32.c	2001/03/04 20:09:48
@@ -4139,7 +4139,7 @@ asmlinkage unsigned long sys32_mremap(un
 	down(&current->mm->mmap_sem);
 	vma = find_vma(current->mm, addr);
 	if (vma && (vma->vm_flags & VM_SHARED))
-		current->thread.flags |= SPARC_FLAG_MMAPSHARED;
+		flags |= _MAP_ALIGN;
 	if (flags & MREMAP_FIXED) {
 		if (new_addr > 0xf0000000UL - new_len)
 			goto out_sem;
@@ -4147,14 +4147,13 @@ asmlinkage unsigned long sys32_mremap(un
 		ret = -ENOMEM;
 		if (!(flags & MREMAP_MAYMOVE))
 			goto out_sem;
-		new_addr = get_unmapped_area(addr, new_len);
+		new_addr = get_unmapped_area(addr, new_len, flags);
 		if (!new_addr)
 			goto out_sem;
 		flags |= MREMAP_FIXED;
 	}
 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
 out_sem:
-	current->thread.flags &= ~(SPARC_FLAG_MMAPSHARED);
 	up(&current->mm->mmap_sem);
 out:
 	return ret;       
Index: include/asm-parisc/processor.h
===================================================================
RCS file: /home/cvs/parisc/linux/include/asm-parisc/processor.h,v
retrieving revision 1.41
diff -u -p -r1.41 processor.h
--- processor.h	2001/03/02 08:28:56	1.41
+++ processor.h	2001/03/04 20:09:48
@@ -324,4 +324,7 @@ extern inline unsigned long get_wchan(st
 #define init_task (init_task_union.task) 
 #define init_stack (init_task_union.stack)
 
+/* We provide our own get_unmapped_area to cope with dcache aliasing */
+#define HAVE_ARCH_UNMAPPED_AREA
+
 #endif /* __ASM_PARISC_PROCESSOR_H */
Index: include/asm-sparc/processor.h
===================================================================
RCS file: /home/cvs/parisc/linux/include/asm-sparc/processor.h,v
retrieving revision 1.3
diff -u -p -r1.3 processor.h
--- processor.h	2001/01/25 00:03:14	1.3
+++ processor.h	2001/03/04 20:09:48
@@ -90,7 +90,6 @@ struct thread_struct {
 
 #define SPARC_FLAG_KTHREAD      0x1    /* task is a kernel thread */
 #define SPARC_FLAG_UNALIGNED    0x2    /* is allowed to do unaligned accesses */
-#define SPARC_FLAG_MMAPSHARED	0x4    /* task wants a shared mmap */
 
 #define INIT_MMAP { &init_mm, (0), (0), \
 		    NULL, __pgprot(0x0) , VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
Index: include/asm-sparc64/processor.h
===================================================================
RCS file: /home/cvs/parisc/linux/include/asm-sparc64/processor.h,v
retrieving revision 1.5
diff -u -p -r1.5 processor.h
--- processor.h	2001/01/25 00:03:15	1.5
+++ processor.h	2001/03/04 20:09:48
@@ -80,7 +80,6 @@ struct thread_struct {
 #define SPARC_FLAG_32BIT        0x04    /* task is older 32-bit binary		*/
 #define SPARC_FLAG_NEWCHILD     0x08    /* task is just-spawned child process	*/
 #define SPARC_FLAG_PERFCTR	0x10    /* task has performance counters active	*/
-#define SPARC_FLAG_MMAPSHARED	0x20    /* task wants a shared mmap             */
 
 #define FAULT_CODE_WRITE	0x01	/* Write access, implies D-TLB		*/
 #define FAULT_CODE_DTLB		0x02	/* Miss happened in D-TLB		*/
Index: include/linux/mm.h
===================================================================
RCS file: /home/cvs/parisc/linux/include/linux/mm.h,v
retrieving revision 1.16
diff -u -p -r1.16 mm.h
--- mm.h	2001/02/08 22:39:19	1.16
+++ mm.h	2001/03/04 20:09:48
@@ -423,7 +423,7 @@ extern void insert_vm_struct(struct mm_s
 extern void __insert_vm_struct(struct mm_struct *, struct vm_area_struct *);
 extern void build_mmap_avl(struct mm_struct *);
 extern void exit_mmap(struct mm_struct *);
-extern unsigned long get_unmapped_area(unsigned long, unsigned long);
+extern unsigned long get_unmapped_area(unsigned long, unsigned long, unsigned long);
 
 extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
 	unsigned long len, unsigned long prot,
Index: include/linux/mman.h
===================================================================
RCS file: /home/cvs/parisc/linux/include/linux/mman.h,v
retrieving revision 1.2
diff -u -p -r1.2 mman.h
--- mman.h	2000/02/08 20:34:36	1.2
+++ mman.h	2001/03/04 20:09:48
@@ -5,5 +5,6 @@
 
 #define MREMAP_MAYMOVE	1
 #define MREMAP_FIXED	2
+#define _MAP_ALIGN	0x80000000		/* Align as required */
 
 #endif /* _LINUX_MMAN_H */
Index: mm/mmap.c
===================================================================
RCS file: /home/cvs/parisc/linux/mm/mmap.c,v
retrieving revision 1.19
diff -u -p -r1.19 mmap.c
--- mmap.c	2001/02/02 03:37:18	1.19
+++ mmap.c	2001/03/04 20:09:48
@@ -254,7 +254,7 @@ unsigned long do_mmap_pgoff(struct file 
 		if (addr & ~PAGE_MASK)
 			return -EINVAL;
 	} else {
-		addr = get_unmapped_area(addr, len);
+		addr = get_unmapped_area(addr, len, flags);
 		if (!addr)
 			return -ENOMEM;
 	}
@@ -376,7 +376,7 @@ free_vma:
  * Return value 0 means ENOMEM.
  */
 #ifndef HAVE_ARCH_UNMAPPED_AREA
-unsigned long get_unmapped_area(unsigned long addr, unsigned long len)
+unsigned long get_unmapped_area(unsigned long addr, unsigned long len, unsigned long flags)
 {
 	struct vm_area_struct * vmm;
 
Index: mm/mremap.c
===================================================================
RCS file: /home/cvs/parisc/linux/mm/mremap.c,v
retrieving revision 1.7
diff -u -p -r1.7 mremap.c
--- mremap.c	2001/01/25 00:03:36	1.7
+++ mremap.c	2001/03/04 20:09:48
@@ -276,7 +276,7 @@ unsigned long do_mremap(unsigned long ad
 	ret = -ENOMEM;
 	if (flags & MREMAP_MAYMOVE) {
 		if (!(flags & MREMAP_FIXED)) {
-			new_addr = get_unmapped_area(0, new_len);
+			new_addr = get_unmapped_area(0, new_len, flags);
 			if (!new_addr)
 				goto out;
 		}


_______________________________________________
parisc-linux-cvs mailing list
parisc-linux-cvs@lists.parisc-linux.org
http://lists.parisc-linux.org/cgi-bin/mailman/listinfo/parisc-linux-cvs

----- End forwarded message -----

-- 
Revolutions do not require corporate support.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Shared mmaps
  2001-03-04 21:10 Shared mmaps Matthew Wilcox
@ 2001-03-05  0:59 ` Rik van Riel
  2001-03-05 10:52 ` Andi Kleen
  1 sibling, 0 replies; 6+ messages in thread
From: Rik van Riel @ 2001-03-05  0:59 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: linux-mm

On Sun, 4 Mar 2001, Matthew Wilcox wrote:

> Sparc & IA64 use a flag in the task_struct to indicate that they're trying
> to allocate an mmap which is shared.  That's really ugly, let's just pass
> the flags in to the get_mapped_area function instead.  I had to invent a
> 
> Comments?

Looks a lot cleaner than the task->flags hack that sparc is
using at the moment...

regards,

Rik
--
Virtual memory is like a game you can't win;
However, without VM there's truly nothing to lose...

		http://www.surriel.com/
http://www.conectiva.com/	http://distro.conectiva.com.br/

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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Shared mmaps
  2001-03-04 21:10 Shared mmaps Matthew Wilcox
  2001-03-05  0:59 ` Rik van Riel
@ 2001-03-05 10:52 ` Andi Kleen
  2001-03-05 17:50   ` Matthew Wilcox
  1 sibling, 1 reply; 6+ messages in thread
From: Andi Kleen @ 2001-03-05 10:52 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: linux-mm

On Sun, Mar 04, 2001 at 10:10:53PM +0100, Matthew Wilcox wrote:
> Sparc & IA64 use a flag in the task_struct to indicate that they're trying
> to allocate an mmap which is shared.  That's really ugly, let's just pass
> the flags in to the get_mapped_area function instead.  I had to invent a
> new flag for this because mremap's flags are different to mmap's (bah!)
> 
> Comments?

With some extensions I would also find it useful for x86-64 for the 32bit
mmap emulation (currently it's using a current-> hack)
For that flags would need to be passed to TASK_UNMAPPED_BASE.


-Andi

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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Shared mmaps
  2001-03-05 10:52 ` Andi Kleen
@ 2001-03-05 17:50   ` Matthew Wilcox
  2001-03-05 22:52     ` Andi Kleen
  0 siblings, 1 reply; 6+ messages in thread
From: Matthew Wilcox @ 2001-03-05 17:50 UTC (permalink / raw)
  To: Andi Kleen; +Cc: Matthew Wilcox, linux-mm

On Mon, Mar 05, 2001 at 11:52:19AM +0100, Andi Kleen wrote:
> With some extensions I would also find it useful for x86-64 for the 32bit
> mmap emulation (currently it's using a current-> hack)
> For that flags would need to be passed to TASK_UNMAPPED_BASE.

Don't you simply check current->personality to determine whether or not
this is a 32-bit task?

get_unmapped_area is already (optionally) an arch-specific function, so
you can make all the changes you need to that function.

-- 
Revolutions do not require corporate support.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Shared mmaps
  2001-03-05 17:50   ` Matthew Wilcox
@ 2001-03-05 22:52     ` Andi Kleen
  0 siblings, 0 replies; 6+ messages in thread
From: Andi Kleen @ 2001-03-05 22:52 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: Andi Kleen, linux-mm

On Mon, Mar 05, 2001 at 06:50:01PM +0100, Matthew Wilcox wrote:
> On Mon, Mar 05, 2001 at 11:52:19AM +0100, Andi Kleen wrote:
> > With some extensions I would also find it useful for x86-64 for the 32bit
> > mmap emulation (currently it's using a current-> hack)
> > For that flags would need to be passed to TASK_UNMAPPED_BASE.
> 
> Don't you simply check current->personality to determine whether or not
> this is a 32-bit task?

ATM yes, but LinuxThreads will eventually need to allocate memory blocks
<4GB too (due to the way the x86-64 context switch works it is much cheaper
to put thread local data pointed to by fs in <4GB) 


-Andi
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Shared mmaps
@ 2001-03-05  0:20 Matthew Wilcox
  0 siblings, 0 replies; 6+ messages in thread
From: Matthew Wilcox @ 2001-03-05  0:20 UTC (permalink / raw)
  To: linux-mm

I don't think the hack that Sparc uses works.

The problem exists on machines with virtual addressed dcaches and no
physical tags.  This applies to at least some models of MIPS, Sparc
& PA-RISC.  if you have shared mmaps which don't map to the same cache
line, they're not coherent.  This breaks stuff.

The sparc hack involves aligning all shared mmaps on a cache aliasing
boundary.  Unfortunately, this has two problems, one performance and
one correctness.  The implementation also had an uglyness problem,
but that's a different matter.

The performance problem is that _all_ shared mmaps get mapped to the
same start address, so we're not using the caches as well as we could.

The correctness problem is that the start offset of the mmap is not
taken into account.  So if you mmap a file starting at 0k length 8k and
another starting at 4k, the changes you make to one mmap will not get
reflected in the other in a deterministic way.

I think I can fix this in a sane manner... but it's going to mean
adding a field (mmap_off) to struct inode (struct address_space?)
then do_mmap_pgoff has code something like:

#define DCACHE_ALIGN_MASK (4 * 1024 * 1024 - 1) /* Example */
#define DCACHE_ALIGN(addr, offset) \
	((addr - offset) & DCACHE_ALIGN_MASK) + offset

	if (flags & MAP_SHARED) {
		if (inode->i_mmap_off == -1) {
			addr = get_unmapped_area(addr, len);
			inode->i_mmap_off = (addr - (pgoff << PAGE_SHIFT))
					& DCACHE_ALIGN_MASK;
		} else {
			addr = get_unmapped_aligned_area(addr, len,
	(inode->i_mmap_off + (pgoff << PAGE_SHIFT)) & DCACHE_ALIGN_MASK);
		}
	} else {
		addr = get_unmapped_area(addr, len);
	}

u_long get_unmapped_aligned_area(u_long addr, u_long len, u_long offset) {
	struct vm_area_struct * vmm;

	if (len > TASK_SIZE)
		return 0;
	if (!addr)
		addr = TASK_UNMAPPED_BASE;
	addr = DCACHE_ALIGN(addr, offset);

	for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
		/* At this point:  (!vmm || addr < vmm->vm_end). */
		if (TASK_SIZE - len < addr)
			return 0;
		if (!vmm || addr + len <= vmm->vm_start)
			return addr;
		addr = DCACHE_ALIGN(vmm->vm_end, offset);
	}
}

Thoughts?  I'm particularly interested in knowing whether people think
about where the mmap_off should go.  inode or address_space?

-- 
Revolutions do not require corporate support.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2001-03-05 22:52 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-03-04 21:10 Shared mmaps Matthew Wilcox
2001-03-05  0:59 ` Rik van Riel
2001-03-05 10:52 ` Andi Kleen
2001-03-05 17:50   ` Matthew Wilcox
2001-03-05 22:52     ` Andi Kleen
2001-03-05  0:20 Matthew Wilcox

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox