linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: David Howells <dhowells@redhat.com>
To: Linus Torvalds <torvalds@transmeta.com>
Cc: David Howells <dhowells@redhat.com>,
	Manfred Spraul <manfred@colorfullife.com>,
	Andrea Arcangeli <andrea@suse.de>,
	Ulrich.Weigand@de.ibm.com, linux-kernel@vger.kernel.org
Subject: Re: Deadlock on the mm->mmap_sem
Date: Wed, 19 Sep 2001 15:51:34 +0100	[thread overview]
Message-ID: <5063.1000911094@warthog.cambridge.redhat.com> (raw)
In-Reply-To: Message from Linus Torvalds <torvalds@transmeta.com>  of "Tue, 18 Sep 2001 09:49:42 PDT." <Pine.LNX.4.33.0109180948260.2077-100000@penguin.transmeta.com>


Linus Torvalds <torvalds@transmeta.com> wrote:
> On Tue, 18 Sep 2001, David Howells wrote:
> >
> > Okay preliminary as-yet-untested patch to cure coredumping of the need
> > to hold the mm semaphore:
> >
> > 	- kernel/fork.c: function to partially copy an mm_struct and attach it
> > 			 to the task_struct in place of the old.
> 
> Oh, please no.
> 
> If the choice is between a hack to do strange and incomprehensible things
> for a special case, and just making the semaphores do the same thing
> rw-spinlocks do and make the problem go away naturally, Ill take #2 any
> day. The patches already exist, after all.

But surely giving rw-semaphores this behaviour is even worse... It introduces
the possibility of livelock, and so DoS attacks, and it affects more than just
access to the mm_struct.

Also comparing them to rw-spinlocks isn't really fair IMHO since they have
different restrictions. Things inside spinlocks aren't allowed to sleep, and
mustn't incur pagefaults.

I also don't think the hack is that bad. All it's doing is taking a copy of
the process's VM decription so that it knows that nobody is going to modify it
whilst a coredump is in progress. Furthermore, it _only_ affects the coredump
path, and the coredump path is just about the last thing on the agenda for a
dying process.

However, if you don't like that, how about just changing the lock on mm_struct
to a special mm_struct-only type lock that has a recursive lock operation for
use by the pagefault handler (and _only_ the pagefault handler)? I've attached
a patch to do just that. This introduces five operations:

	- mm_lock_shared()		- get shared lock fairly
	- mm_lock_shared_recursive()	- get shared lock unfairly
	- mm_unlock_shared()		- release shared lock
	- mm_lock_exclusive()		- get exclusive lock
	- mm_unlock_exclusive()		- release exclusive lock

David


diff -uNr linux-2.4.10-pre12/arch/alpha/kernel/osf_sys.c linux-mmsem/arch/alpha/kernel/osf_sys.c
--- linux-2.4.10-pre12/arch/alpha/kernel/osf_sys.c	Tue Sep 18 08:45:58 2001
+++ linux-mmsem/arch/alpha/kernel/osf_sys.c	Wed Sep 19 12:57:04 2001
@@ -241,9 +241,9 @@
 			goto out;
 	}
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	ret = do_mmap(file, addr, len, prot, flags, off);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	if (file)
 		fput(file);
 out:
diff -uNr linux-2.4.10-pre12/arch/alpha/mm/fault.c linux-mmsem/arch/alpha/mm/fault.c
--- linux-2.4.10-pre12/arch/alpha/mm/fault.c	Wed Sep 19 10:39:05 2001
+++ linux-mmsem/arch/alpha/mm/fault.c	Wed Sep 19 13:55:13 2001
@@ -113,7 +113,7 @@
 		goto vmalloc_fault;
 #endif
 
-	down_read(&mm->mmap_sem);
+	mm_lock_shared_recursive(mm);
 	vma = find_vma(mm, address);
 	if (!vma)
 		goto bad_area;
@@ -147,7 +147,7 @@
 	 * the fault.
 	 */
 	fault = handle_mm_fault(mm, vma, address, cause > 0);
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 
 	if (fault < 0)
 		goto out_of_memory;
@@ -161,7 +161,7 @@
  * Fix it, but check if it's kernel or user first..
  */
 bad_area:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 
 	if (user_mode(regs)) {
 		force_sig(SIGSEGV, current);
@@ -198,7 +198,7 @@
 	if (current->pid == 1) {
 		current->policy |= SCHED_YIELD;
 		schedule();
-		down_read(&mm->mmap_sem);
+		mm_lock_shared_recursive(mm);
 		goto survive;
 	}
 	printk(KERN_ALERT "VM: killing process %s(%d)\n",
diff -uNr linux-2.4.10-pre12/arch/arm/kernel/sys_arm.c linux-mmsem/arch/arm/kernel/sys_arm.c
--- linux-2.4.10-pre12/arch/arm/kernel/sys_arm.c	Tue Sep 18 08:46:39 2001
+++ linux-mmsem/arch/arm/kernel/sys_arm.c	Wed Sep 19 12:57:09 2001
@@ -74,9 +74,9 @@
 			goto out;
 	}
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 
 	if (file)
 		fput(file);
@@ -125,9 +125,9 @@
 	    vectors_base() == 0)
 		goto out;
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 
 out:
 	return ret;
diff -uNr linux-2.4.10-pre12/arch/arm/mm/fault-common.c linux-mmsem/arch/arm/mm/fault-common.c
--- linux-2.4.10-pre12/arch/arm/mm/fault-common.c	Tue Sep 18 08:46:39 2001
+++ linux-mmsem/arch/arm/mm/fault-common.c	Wed Sep 19 13:56:39 2001
@@ -251,9 +251,9 @@
 	if (in_interrupt() || !mm)
 		goto no_context;
 
-	down_read(&mm->mmap_sem);
+	mm_lock_shared_recursive(mm);
 	fault = __do_page_fault(mm, addr, error_code, tsk);
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 
 	/*
 	 * Handle the "normal" case first
diff -uNr linux-2.4.10-pre12/arch/cris/kernel/sys_cris.c linux-mmsem/arch/cris/kernel/sys_cris.c
--- linux-2.4.10-pre12/arch/cris/kernel/sys_cris.c	Tue Sep 18 08:46:43 2001
+++ linux-mmsem/arch/cris/kernel/sys_cris.c	Wed Sep 19 12:57:13 2001
@@ -59,9 +59,9 @@
                         goto out;
         }
 
-        down_write(&current->mm->mmap_sem);
+        mm_lock_exclusive(current->mm);
         error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-        up_write(&current->mm->mmap_sem);
+        mm_unlock_exclusive(current->mm);
 
         if (file)
                 fput(file);
diff -uNr linux-2.4.10-pre12/arch/cris/mm/fault.c linux-mmsem/arch/cris/mm/fault.c
--- linux-2.4.10-pre12/arch/cris/mm/fault.c	Tue Sep 18 08:46:43 2001
+++ linux-mmsem/arch/cris/mm/fault.c	Wed Sep 19 13:57:18 2001
@@ -266,7 +266,7 @@
 	if (in_interrupt() || !mm)
 		goto no_context;
 
-	down_read(&mm->mmap_sem);
+	mm_lock_shared_recursive(mm);
 	vma = find_vma(mm, address);
 	if (!vma)
 		goto bad_area;
@@ -324,7 +324,7 @@
                 goto out_of_memory;
 	}
 
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	return;
 	
 	/*
@@ -334,7 +334,7 @@
 
  bad_area:
 
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 
  bad_area_nosemaphore:
 	DPG(show_registers(regs));
@@ -397,14 +397,14 @@
 	 */
 
  out_of_memory:
-        up_read(&mm->mmap_sem);
+        mm_unlock_shared(mm);
 	printk("VM: killing process %s\n", tsk->comm);
 	if(user_mode(regs))
 		do_exit(SIGKILL);
 	goto no_context;
 
  do_sigbus:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 
 	/*
          * Send a sigbus, regardless of whether we were in kernel
diff -uNr linux-2.4.10-pre12/arch/i386/kernel/ldt.c linux-mmsem/arch/i386/kernel/ldt.c
--- linux-2.4.10-pre12/arch/i386/kernel/ldt.c	Tue Sep 18 08:45:58 2001
+++ linux-mmsem/arch/i386/kernel/ldt.c	Wed Sep 19 12:57:03 2001
@@ -73,7 +73,7 @@
 	 * the GDT index of the LDT is allocated dynamically, and is
 	 * limited by MAX_LDT_DESCRIPTORS.
 	 */
-	down_write(&mm->mmap_sem);
+	mm_lock_exclusive(mm);
 	if (!mm->context.segments) {
 		void * segments = vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE);
 		error = -ENOMEM;
@@ -124,7 +124,7 @@
 	error = 0;
 
 out_unlock:
-	up_write(&mm->mmap_sem);
+	mm_unlock_exclusive(mm);
 out:
 	return error;
 }
diff -uNr linux-2.4.10-pre12/arch/i386/kernel/sys_i386.c linux-mmsem/arch/i386/kernel/sys_i386.c
--- linux-2.4.10-pre12/arch/i386/kernel/sys_i386.c	Tue Sep 18 08:45:58 2001
+++ linux-mmsem/arch/i386/kernel/sys_i386.c	Wed Sep 19 12:57:03 2001
@@ -55,9 +55,9 @@
 			goto out;
 	}
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 
 	if (file)
 		fput(file);
diff -uNr linux-2.4.10-pre12/arch/i386/mm/fault.c linux-mmsem/arch/i386/mm/fault.c
--- linux-2.4.10-pre12/arch/i386/mm/fault.c	Wed Sep 19 10:39:06 2001
+++ linux-mmsem/arch/i386/mm/fault.c	Wed Sep 19 13:55:18 2001
@@ -191,7 +191,7 @@
 	if (in_interrupt() || !mm)
 		goto no_context;
 
-	down_read(&mm->mmap_sem);
+	mm_lock_shared_recursive(mm);
 
 	vma = find_vma(mm, address);
 	if (!vma)
@@ -265,7 +265,7 @@
 		if (bit < 32)
 			tsk->thread.screen_bitmap |= 1 << bit;
 	}
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	return;
 
 /*
@@ -273,7 +273,7 @@
  * Fix it, but check if it's kernel or user first..
  */
 bad_area:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 
 	/* User mode accesses just cause a SIGSEGV */
 	if (error_code & 4) {
@@ -341,11 +341,11 @@
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	if (tsk->pid == 1) {
 		tsk->policy |= SCHED_YIELD;
 		schedule();
-		down_read(&mm->mmap_sem);
+		mm_lock_shared_recursive(mm);
 		goto survive;
 	}
 	printk("VM: killing process %s\n", tsk->comm);
@@ -354,7 +354,7 @@
 	goto no_context;
 
 do_sigbus:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 
 	/*
 	 * Send a sigbus, regardless of whether we were in kernel
diff -uNr linux-2.4.10-pre12/arch/ia64/ia32/sys_ia32.c linux-mmsem/arch/ia64/ia32/sys_ia32.c
--- linux-2.4.10-pre12/arch/ia64/ia32/sys_ia32.c	Tue Sep 18 08:46:41 2001
+++ linux-mmsem/arch/ia64/ia32/sys_ia32.c	Wed Sep 19 12:57:11 2001
@@ -245,9 +245,9 @@
 		}
 		__copy_user(back, (char *)addr + len, PAGE_SIZE - ((addr + len) & ~PAGE_MASK));
 	}
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	r = do_mmap(0, baddr, len + (addr - baddr), prot, flags | MAP_ANONYMOUS, 0);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	if (r < 0)
 		return(r);
 	if (addr == 0)
@@ -291,9 +291,9 @@
 		poff = offset & PAGE_MASK;
 		len += offset - poff;
 
-		down_write(&current->mm->mmap_sem);
+		mm_lock_exclusive(current->mm);
 		error = do_mmap_pgoff(file, addr, len, prot, flags, poff >> PAGE_SHIFT);
-		up_write(&current->mm->mmap_sem);
+		mm_unlock_exclusive(current->mm);
 
 		if (!IS_ERR((void *) error))
 			error += offset - poff;
@@ -338,9 +338,9 @@
 	if ((a.offset & ~PAGE_MASK) != 0)
 		return -EINVAL;
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	retval = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, a.offset >> PAGE_SHIFT);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 #else
 	retval = ia32_do_mmap(file, a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
 #endif
@@ -2605,11 +2605,11 @@
 		return(-EFAULT);
 	}
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	addr = do_mmap_pgoff(file, IA32_IOBASE,
 			     IOLEN, PROT_READ|PROT_WRITE, MAP_SHARED,
 			     (ia64_iobase & ~PAGE_OFFSET) >> PAGE_SHIFT);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 
 	if (addr >= 0) {
 		ia64_set_kr(IA64_KR_IO_BASE, addr);
diff -uNr linux-2.4.10-pre12/arch/ia64/kernel/sys_ia64.c linux-mmsem/arch/ia64/kernel/sys_ia64.c
--- linux-2.4.10-pre12/arch/ia64/kernel/sys_ia64.c	Tue Sep 18 08:46:41 2001
+++ linux-mmsem/arch/ia64/kernel/sys_ia64.c	Wed Sep 19 12:57:11 2001
@@ -106,7 +106,7 @@
 	 * check and the clearing of r8.  However, we can't call sys_brk() because we need
 	 * to acquire the mmap_sem before we can do the test...
 	 */
-	down_write(&mm->mmap_sem);
+	mm_lock_exclusive(mm);
 
 	if (brk < mm->end_code)
 		goto out;
@@ -146,7 +146,7 @@
 	mm->brk = brk;
 out:
 	retval = mm->brk;
-	up_write(&mm->mmap_sem);
+	mm_unlock_exclusive(mm);
 	regs->r8 = 0;		/* ensure large retval isn't mistaken as error code */
 	return retval;
 }
@@ -205,9 +205,9 @@
 	if (rgn_index(addr) != rgn_index(addr + len))
 		return -EINVAL;
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 
 	if (file)
 		fput(file);
diff -uNr linux-2.4.10-pre12/arch/ia64/mm/fault.c linux-mmsem/arch/ia64/mm/fault.c
--- linux-2.4.10-pre12/arch/ia64/mm/fault.c	Tue Sep 18 08:46:41 2001
+++ linux-mmsem/arch/ia64/mm/fault.c	Wed Sep 19 13:56:55 2001
@@ -60,7 +60,7 @@
 	if (in_interrupt() || !mm)
 		goto no_context;
 
-	down_read(&mm->mmap_sem);
+	mm_lock_shared_recursive(mm);
 
 	vma = find_vma_prev(mm, address, &prev_vma);
 	if (!vma)
@@ -112,7 +112,7 @@
 	      default:
 		goto out_of_memory;
 	}
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	return;
 
   check_expansion:
@@ -135,7 +135,7 @@
 	goto good_area;
 
   bad_area:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	if (isr & IA64_ISR_SP) {
 		/*
 		 * This fault was due to a speculative load set the "ed" bit in the psr to
@@ -184,7 +184,7 @@
 	return;
 
   out_of_memory:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	printk("VM: killing process %s\n", current->comm);
 	if (user_mode(regs))
 		do_exit(SIGKILL);
diff -uNr linux-2.4.10-pre12/arch/m68k/kernel/sys_m68k.c linux-mmsem/arch/m68k/kernel/sys_m68k.c
--- linux-2.4.10-pre12/arch/m68k/kernel/sys_m68k.c	Tue Sep 18 08:46:05 2001
+++ linux-mmsem/arch/m68k/kernel/sys_m68k.c	Wed Sep 19 12:57:08 2001
@@ -59,9 +59,9 @@
 			goto out;
 	}
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 
 	if (file)
 		fput(file);
@@ -146,9 +146,9 @@
 	}
 	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	if (file)
 		fput(file);
 out:
diff -uNr linux-2.4.10-pre12/arch/m68k/mm/fault.c linux-mmsem/arch/m68k/mm/fault.c
--- linux-2.4.10-pre12/arch/m68k/mm/fault.c	Tue Sep 18 08:46:05 2001
+++ linux-mmsem/arch/m68k/mm/fault.c	Wed Sep 19 13:56:17 2001
@@ -101,7 +101,7 @@
 	if (in_interrupt() || !mm)
 		goto no_context;
 
-	down_read(&mm->mmap_sem);
+	mm_lock_shared_recursive(mm);
 
 	vma = find_vma(mm, address);
 	if (!vma)
@@ -168,7 +168,7 @@
 	#warning should be obsolete now...
 	if (CPU_IS_040_OR_060)
 		flush_tlb_page(vma, address);
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	return 0;
 
 /*
@@ -203,6 +203,6 @@
 	current->thread.faddr = address;
 
 send_sig:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	return send_fault_sig(regs);
 }
diff -uNr linux-2.4.10-pre12/arch/mips/kernel/irixelf.c linux-mmsem/arch/mips/kernel/irixelf.c
--- linux-2.4.10-pre12/arch/mips/kernel/irixelf.c	Tue Sep 18 08:45:59 2001
+++ linux-mmsem/arch/mips/kernel/irixelf.c	Wed Sep 19 12:57:05 2001
@@ -314,12 +314,12 @@
 		   (unsigned long) elf_prot, (unsigned long) elf_type,
 		   (unsigned long) (eppnt->p_offset & 0xfffff000));
 #endif
-	    down_write(&current->mm->mmap_sem);
+	    mm_lock_exclusive(current->mm);
 	    error = do_mmap(interpreter, vaddr,
 			    eppnt->p_filesz + (eppnt->p_vaddr & 0xfff),
 			    elf_prot, elf_type,
 			    eppnt->p_offset & 0xfffff000);
-	    up_write(&current->mm->mmap_sem);
+	    mm_unlock_exclusive(current->mm);
 
 	    if(error < 0 && error > -1024) {
 		    printk("Aieee IRIX interp mmap error=%d\n", error);
@@ -498,12 +498,12 @@
 		prot  = (epp->p_flags & PF_R) ? PROT_READ : 0;
 		prot |= (epp->p_flags & PF_W) ? PROT_WRITE : 0;
 		prot |= (epp->p_flags & PF_X) ? PROT_EXEC : 0;
-	        down_write(&current->mm->mmap_sem);
+	        mm_lock_exclusive(current->mm);
 		(void) do_mmap(fp, (epp->p_vaddr & 0xfffff000),
 			       (epp->p_filesz + (epp->p_vaddr & 0xfff)),
 			       prot, EXEC_MAP_FLAGS,
 			       (epp->p_offset & 0xfffff000));
-	        up_write(&current->mm->mmap_sem);
+	        mm_unlock_exclusive(current->mm);
 
 		/* Fixup location tracking vars. */
 		if((epp->p_vaddr & 0xfffff000) < *estack)
@@ -762,10 +762,10 @@
 	 * Since we do not have the power to recompile these, we
 	 * emulate the SVr4 behavior.  Sigh.
 	 */
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	(void) do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC,
 		       MAP_FIXED | MAP_PRIVATE, 0);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 #endif
 
 	start_thread(regs, elf_entry, bprm->p);
@@ -837,14 +837,14 @@
 	while(elf_phdata->p_type != PT_LOAD) elf_phdata++;
 	
 	/* Now use mmap to map the library into memory. */
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	error = do_mmap(file,
 			elf_phdata->p_vaddr & 0xfffff000,
 			elf_phdata->p_filesz + (elf_phdata->p_vaddr & 0xfff),
 			PROT_READ | PROT_WRITE | PROT_EXEC,
 			MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
 			elf_phdata->p_offset & 0xfffff000);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 
 	k = elf_phdata->p_vaddr + elf_phdata->p_filesz;
 	if (k > elf_bss) elf_bss = k;
@@ -916,12 +916,12 @@
 		prot  = (hp->p_flags & PF_R) ? PROT_READ : 0;
 		prot |= (hp->p_flags & PF_W) ? PROT_WRITE : 0;
 		prot |= (hp->p_flags & PF_X) ? PROT_EXEC : 0;
-		down_write(&current->mm->mmap_sem);
+		mm_lock_exclusive(current->mm);
 		retval = do_mmap(filp, (hp->p_vaddr & 0xfffff000),
 				 (hp->p_filesz + (hp->p_vaddr & 0xfff)),
 				 prot, (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
 				 (hp->p_offset & 0xfffff000));
-		up_write(&current->mm->mmap_sem);
+		mm_unlock_exclusive(current->mm);
 
 		if(retval != (hp->p_vaddr & 0xfffff000)) {
 			printk("irix_mapelf: do_mmap fails with %d!\n", retval);
diff -uNr linux-2.4.10-pre12/arch/mips/kernel/syscall.c linux-mmsem/arch/mips/kernel/syscall.c
--- linux-2.4.10-pre12/arch/mips/kernel/syscall.c	Tue Sep 18 08:45:59 2001
+++ linux-mmsem/arch/mips/kernel/syscall.c	Wed Sep 19 12:57:05 2001
@@ -69,9 +69,9 @@
 			goto out;
 	}
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 
 	if (file)
 		fput(file);
diff -uNr linux-2.4.10-pre12/arch/mips/kernel/sysirix.c linux-mmsem/arch/mips/kernel/sysirix.c
--- linux-2.4.10-pre12/arch/mips/kernel/sysirix.c	Tue Sep 18 08:45:59 2001
+++ linux-mmsem/arch/mips/kernel/sysirix.c	Wed Sep 19 12:57:05 2001
@@ -471,7 +471,7 @@
 		if (retval)
 			return retval;
 
-		down_read(&mm->mmap_sem);
+		mm_lock_shared(mm);
 		pgdp = pgd_offset(mm, addr);
 		pmdp = pmd_offset(pgdp, addr);
 		ptep = pte_offset(pmdp, addr);
@@ -484,7 +484,7 @@
 				                   PAGE_SHIFT, pageno);
 			}
 		}
-		up_read(&mm->mmap_sem);
+		mm_unlock_shared(mm);
 		break;
 	}
 
@@ -534,7 +534,7 @@
 	struct mm_struct *mm = current->mm;
 	int ret;
 
-	down_write(&mm->mmap_sem);
+	mm_lock_exclusive(mm);
 	if (brk < mm->end_code) {
 		ret = -ENOMEM;
 		goto out;
@@ -592,7 +592,7 @@
 	ret = 0;
 
 out:
-	up_write(&mm->mmap_sem);
+	mm_unlock_exclusive(mm);
 	return ret;
 }
 
@@ -1082,9 +1082,9 @@
 
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	retval = do_mmap(file, addr, len, prot, flags, offset);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	if (file)
 		fput(file);
 
@@ -1642,9 +1642,9 @@
 
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 
 	if (file)
 		fput(file);
diff -uNr linux-2.4.10-pre12/arch/mips/mm/fault.c linux-mmsem/arch/mips/mm/fault.c
--- linux-2.4.10-pre12/arch/mips/mm/fault.c	Tue Sep 18 08:45:59 2001
+++ linux-mmsem/arch/mips/mm/fault.c	Wed Sep 19 13:55:33 2001
@@ -72,7 +72,7 @@
 	printk("[%s:%d:%08lx:%ld:%08lx]\n", current->comm, current->pid,
 	       address, write, regs->cp0_epc);
 #endif
-	down_read(&mm->mmap_sem);
+	mm_lock_shared_recursive(mm);
 	vma = find_vma(mm, address);
 	if (!vma)
 		goto bad_area;
@@ -115,7 +115,7 @@
 		goto out_of_memory;
 	}
 
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	return;
 
 /*
@@ -123,7 +123,7 @@
  * Fix it, but check if it's kernel or user first..
  */
 bad_area:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 
 bad_area_nosemaphore:
 	/* User mode accesses just cause a SIGSEGV */
@@ -177,14 +177,14 @@
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	printk("VM: killing process %s\n", tsk->comm);
 	if (user_mode(regs))
 		do_exit(SIGKILL);
 	goto no_context;
 
 do_sigbus:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 
 	/*
 	 * Send a sigbus, regardless of whether we were in kernel
diff -uNr linux-2.4.10-pre12/arch/mips64/kernel/linux32.c linux-mmsem/arch/mips64/kernel/linux32.c
--- linux-2.4.10-pre12/arch/mips64/kernel/linux32.c	Wed Sep 19 10:39:07 2001
+++ linux-mmsem/arch/mips64/kernel/linux32.c	Wed Sep 19 12:57:12 2001
@@ -443,10 +443,10 @@
 	 *  `execve' frees all current memory we only have to do an
 	 *  `munmap' if the `execve' failes.
 	 */
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	av = (char **) do_mmap_pgoff(0, 0, len, PROT_READ | PROT_WRITE,
 				     MAP_PRIVATE | MAP_ANONYMOUS, 0);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 
 	if (IS_ERR(av))
 		return (long) av;
diff -uNr linux-2.4.10-pre12/arch/mips64/kernel/syscall.c linux-mmsem/arch/mips64/kernel/syscall.c
--- linux-2.4.10-pre12/arch/mips64/kernel/syscall.c	Wed Sep 19 10:39:07 2001
+++ linux-mmsem/arch/mips64/kernel/syscall.c	Wed Sep 19 12:57:12 2001
@@ -65,9 +65,9 @@
 	}
         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
         error = do_mmap(file, addr, len, prot, flags, offset);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
         if (file)
                 fput(file);
 out:
diff -uNr linux-2.4.10-pre12/arch/mips64/mm/fault.c linux-mmsem/arch/mips64/mm/fault.c
--- linux-2.4.10-pre12/arch/mips64/mm/fault.c	Wed Sep 19 10:39:07 2001
+++ linux-mmsem/arch/mips64/mm/fault.c	Wed Sep 19 13:57:01 2001
@@ -124,7 +124,7 @@
 	printk("Cpu%d[%s:%d:%08lx:%ld:%08lx]\n", smp_processor_id(), current->comm,
 		current->pid, address, write, regs->cp0_epc);
 #endif
-	down_read(&mm->mmap_sem);
+	mm_lock_shared_recursive(mm);
 	vma = find_vma(mm, address);
 	if (!vma)
 		goto bad_area;
@@ -167,7 +167,7 @@
 		goto out_of_memory;
 	}
 
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	return;
 
 /*
@@ -175,7 +175,7 @@
  * Fix it, but check if it's kernel or user first..
  */
 bad_area:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 
 bad_area_nosemaphore:
 	if (user_mode(regs)) {
@@ -233,14 +233,14 @@
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	printk("VM: killing process %s\n", tsk->comm);
 	if (user_mode(regs))
 		do_exit(SIGKILL);
 	goto no_context;
 
 do_sigbus:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 
 	/*
 	 * Send a sigbus, regardless of whether we were in kernel
diff -uNr linux-2.4.10-pre12/arch/parisc/kernel/sys_parisc.c linux-mmsem/arch/parisc/kernel/sys_parisc.c
--- linux-2.4.10-pre12/arch/parisc/kernel/sys_parisc.c	Tue Sep 18 08:46:43 2001
+++ linux-mmsem/arch/parisc/kernel/sys_parisc.c	Wed Sep 19 12:57:13 2001
@@ -51,7 +51,7 @@
 	struct file * file = NULL;
 	int error;
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	lock_kernel();
 	if (!(flags & MAP_ANONYMOUS)) {
 		error = -EBADF;
@@ -65,7 +65,7 @@
 		fput(file);
 out:
 	unlock_kernel();
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	return error;
 }
 
diff -uNr linux-2.4.10-pre12/arch/parisc/mm/fault.c linux-mmsem/arch/parisc/mm/fault.c
--- linux-2.4.10-pre12/arch/parisc/mm/fault.c	Tue Sep 18 08:46:43 2001
+++ linux-mmsem/arch/parisc/mm/fault.c	Wed Sep 19 13:57:13 2001
@@ -175,7 +175,7 @@
 	if (in_interrupt() || !mm)
 		goto no_context;
 
-	down_read(&mm->mmap_sem);
+	mm_lock_shared_recursive(mm);
 	vma = pa_find_vma(mm, address);
 	if (!vma)
 		goto bad_area;
@@ -218,14 +218,14 @@
 	      default:
 		goto out_of_memory;
 	}
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	return;
 
 /*
  * Something tried to access memory that isn't in our memory map..
  */
 bad_area:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 
 	if (user_mode(regs)) {
 		struct siginfo si;
@@ -275,7 +275,7 @@
 	parisc_terminate("Bad Address (null pointer deref?)",regs,code,address);
 
   out_of_memory:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	printk("VM: killing process %s\n", current->comm);
 	if (user_mode(regs))
 		do_exit(SIGKILL);
diff -uNr linux-2.4.10-pre12/arch/ppc/kernel/syscalls.c linux-mmsem/arch/ppc/kernel/syscalls.c
--- linux-2.4.10-pre12/arch/ppc/kernel/syscalls.c	Tue Sep 18 08:46:01 2001
+++ linux-mmsem/arch/ppc/kernel/syscalls.c	Wed Sep 19 12:57:06 2001
@@ -202,9 +202,9 @@
 			goto out;
 	}
 	
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	if (file)
 		fput(file);
 out:
diff -uNr linux-2.4.10-pre12/arch/ppc/mm/fault.c linux-mmsem/arch/ppc/mm/fault.c
--- linux-2.4.10-pre12/arch/ppc/mm/fault.c	Tue Sep 18 08:46:01 2001
+++ linux-mmsem/arch/ppc/mm/fault.c	Wed Sep 19 13:55:48 2001
@@ -103,7 +103,7 @@
 		bad_page_fault(regs, address, SIGSEGV);
 		return;
 	}
-	down_read(&mm->mmap_sem);
+	mm_lock_shared_recursive(mm);
 	vma = find_vma(mm, address);
 	if (!vma)
 		goto bad_area;
@@ -163,7 +163,7 @@
                 goto out_of_memory;
 	}
 
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	/*
 	 * keep track of tlb+htab misses that are good addrs but
 	 * just need pte's created via handle_mm_fault()
@@ -173,7 +173,7 @@
 	return;
 
 bad_area:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	pte_errors++;	
 
 	/* User mode accesses cause a SIGSEGV */
@@ -194,7 +194,7 @@
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	printk("VM: killing process %s\n", current->comm);
 	if (user_mode(regs))
 		do_exit(SIGKILL);
@@ -202,7 +202,7 @@
 	return;
 
 do_sigbus:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	info.si_signo = SIGBUS;
 	info.si_errno = 0;
 	info.si_code = BUS_ADRERR;
diff -uNr linux-2.4.10-pre12/arch/s390/kernel/sys_s390.c linux-mmsem/arch/s390/kernel/sys_s390.c
--- linux-2.4.10-pre12/arch/s390/kernel/sys_s390.c	Tue Sep 18 08:46:42 2001
+++ linux-mmsem/arch/s390/kernel/sys_s390.c	Wed Sep 19 12:57:12 2001
@@ -61,9 +61,9 @@
 			goto out;
 	}
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 
 	if (file)
 		fput(file);
diff -uNr linux-2.4.10-pre12/arch/s390/mm/fault.c linux-mmsem/arch/s390/mm/fault.c
--- linux-2.4.10-pre12/arch/s390/mm/fault.c	Tue Sep 18 08:46:43 2001
+++ linux-mmsem/arch/s390/mm/fault.c	Wed Sep 19 13:57:08 2001
@@ -113,7 +113,7 @@
 	 * task's user address space, so we search the VMAs
 	 */
 
-        down_read(&mm->mmap_sem);
+        mm_lock_shared_recursive(mm);
 
         vma = find_vma(mm, address);
         if (!vma)
@@ -164,7 +164,7 @@
 		goto out_of_memory;
 	}
 
-        up_read(&mm->mmap_sem);
+        mm_unlock_shared(mm);
         return;
 
 /*
@@ -172,7 +172,7 @@
  * Fix it, but check if it's kernel or user first..
  */
 bad_area:
-        up_read(&mm->mmap_sem);
+        mm_unlock_shared(mm);
 
         /* User mode accesses just cause a SIGSEGV */
         if (regs->psw.mask & PSW_PROBLEM_STATE) {
@@ -231,14 +231,14 @@
  * us unable to handle the page fault gracefully.
 */
 out_of_memory:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	printk("VM: killing process %s\n", tsk->comm);
 	if (regs->psw.mask & PSW_PROBLEM_STATE)
 		do_exit(SIGKILL);
 	goto no_context;
 
 do_sigbus:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 
 	/*
 	 * Send a sigbus, regardless of whether we were in kernel
diff -uNr linux-2.4.10-pre12/arch/s390x/kernel/binfmt_elf32.c linux-mmsem/arch/s390x/kernel/binfmt_elf32.c
--- linux-2.4.10-pre12/arch/s390x/kernel/binfmt_elf32.c	Tue Sep 18 08:46:43 2001
+++ linux-mmsem/arch/s390x/kernel/binfmt_elf32.c	Wed Sep 19 12:57:13 2001
@@ -194,11 +194,11 @@
 	if(!addr)
 		addr = 0x40000000;
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	map_addr = do_mmap(filep, ELF_PAGESTART(addr),
 			   eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr), prot, type,
 			   eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr));
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	return(map_addr);
 }
 
diff -uNr linux-2.4.10-pre12/arch/s390x/kernel/exec32.c linux-mmsem/arch/s390x/kernel/exec32.c
--- linux-2.4.10-pre12/arch/s390x/kernel/exec32.c	Tue Sep 18 08:46:43 2001
+++ linux-mmsem/arch/s390x/kernel/exec32.c	Wed Sep 19 12:57:13 2001
@@ -54,7 +54,7 @@
 	if (!mpnt) 
 		return -ENOMEM; 
 	
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	{
 		mpnt->vm_mm = current->mm;
 		mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
@@ -77,7 +77,7 @@
 		}
 		stack_base += PAGE_SIZE;
 	}
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	
 	return 0;
 }
diff -uNr linux-2.4.10-pre12/arch/s390x/kernel/linux32.c linux-mmsem/arch/s390x/kernel/linux32.c
--- linux-2.4.10-pre12/arch/s390x/kernel/linux32.c	Tue Sep 18 08:46:43 2001
+++ linux-mmsem/arch/s390x/kernel/linux32.c	Wed Sep 19 12:57:13 2001
@@ -4186,14 +4186,14 @@
 			goto out;
 	}
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
 	if (!IS_ERR((void *) error) && error + len >= 0x80000000ULL) {
 		/* Result is out of bounds.  */
 		do_munmap(current->mm, addr, len);
 		error = -ENOMEM;
 	}
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 
 	if (file)
 		fput(file);
diff -uNr linux-2.4.10-pre12/arch/s390x/kernel/sys_s390.c linux-mmsem/arch/s390x/kernel/sys_s390.c
--- linux-2.4.10-pre12/arch/s390x/kernel/sys_s390.c	Tue Sep 18 08:46:44 2001
+++ linux-mmsem/arch/s390x/kernel/sys_s390.c	Wed Sep 19 12:57:13 2001
@@ -61,9 +61,9 @@
 			goto out;
 	}
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 
 	if (file)
 		fput(file);
diff -uNr linux-2.4.10-pre12/arch/s390x/mm/fault.c linux-mmsem/arch/s390x/mm/fault.c
--- linux-2.4.10-pre12/arch/s390x/mm/fault.c	Tue Sep 18 08:46:44 2001
+++ linux-mmsem/arch/s390x/mm/fault.c	Wed Sep 19 13:57:25 2001
@@ -141,7 +141,7 @@
 	 * task's user address space, so we search the VMAs
 	 */
 
-        down_read(&mm->mmap_sem);
+        mm_lock_shared_recursive(mm);
 
         vma = find_vma(mm, address);
         if (!vma) {
@@ -195,7 +195,7 @@
 		goto out_of_memory;
 	}
 
-        up_read(&mm->mmap_sem);
+        mm_unlock_shared(mm);
         return;
 
 /*
@@ -203,7 +203,7 @@
  * Fix it, but check if it's kernel or user first..
  */
 bad_area:
-        up_read(&mm->mmap_sem);
+        mm_unlock_shared(mm);
 
         /* User mode accesses just cause a SIGSEGV */
         if (regs->psw.mask & PSW_PROBLEM_STATE) {
@@ -262,14 +262,14 @@
  * us unable to handle the page fault gracefully.
 */
 out_of_memory:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	printk("VM: killing process %s\n", tsk->comm);
 	if (regs->psw.mask & PSW_PROBLEM_STATE)
 		do_exit(SIGKILL);
 	goto no_context;
 
 do_sigbus:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 
 	/*
 	 * Send a sigbus, regardless of whether we were in kernel
diff -uNr linux-2.4.10-pre12/arch/sh/kernel/sys_sh.c linux-mmsem/arch/sh/kernel/sys_sh.c
--- linux-2.4.10-pre12/arch/sh/kernel/sys_sh.c	Wed Sep 19 10:39:08 2001
+++ linux-mmsem/arch/sh/kernel/sys_sh.c	Wed Sep 19 12:57:10 2001
@@ -96,9 +96,9 @@
 			goto out;
 	}
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 
 	if (file)
 		fput(file);
diff -uNr linux-2.4.10-pre12/arch/sh/mm/fault.c linux-mmsem/arch/sh/mm/fault.c
--- linux-2.4.10-pre12/arch/sh/mm/fault.c	Wed Sep 19 10:39:08 2001
+++ linux-mmsem/arch/sh/mm/fault.c	Wed Sep 19 13:56:46 2001
@@ -105,7 +105,7 @@
 	if (in_interrupt() || !mm)
 		goto no_context;
 
-	down_read(&mm->mmap_sem);
+	mm_lock_shared_recursive(mm);
 
 	vma = find_vma(mm, address);
 	if (!vma)
@@ -147,7 +147,7 @@
 		goto out_of_memory;
 	}
 
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	return;
 
 /*
@@ -155,7 +155,7 @@
  * Fix it, but check if it's kernel or user first..
  */
 bad_area:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 
 	if (user_mode(regs)) {
 		tsk->thread.address = address;
@@ -204,14 +204,14 @@
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	printk("VM: killing process %s\n", tsk->comm);
 	if (user_mode(regs))
 		do_exit(SIGKILL);
 	goto no_context;
 
 do_sigbus:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 
 	/*
 	 * Send a sigbus, regardless of whether we were in kernel
diff -uNr linux-2.4.10-pre12/arch/sparc/kernel/sys_sparc.c linux-mmsem/arch/sparc/kernel/sys_sparc.c
--- linux-2.4.10-pre12/arch/sparc/kernel/sys_sparc.c	Tue Sep 18 08:45:59 2001
+++ linux-mmsem/arch/sparc/kernel/sys_sparc.c	Wed Sep 19 12:57:04 2001
@@ -242,9 +242,9 @@
 
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 
 out_putf:
 	if (file)
@@ -288,7 +288,7 @@
 	if (old_len > TASK_SIZE - PAGE_SIZE ||
 	    new_len > TASK_SIZE - PAGE_SIZE)
 		goto out;
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	if (flags & MREMAP_FIXED) {
 		if (ARCH_SUN4C_SUN4 &&
 		    new_addr < 0xe0000000 &&
@@ -323,7 +323,7 @@
 	}
 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
 out_sem:
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 out:
 	return ret;       
 }
diff -uNr linux-2.4.10-pre12/arch/sparc/kernel/sys_sunos.c linux-mmsem/arch/sparc/kernel/sys_sunos.c
--- linux-2.4.10-pre12/arch/sparc/kernel/sys_sunos.c	Tue Sep 18 08:45:59 2001
+++ linux-mmsem/arch/sparc/kernel/sys_sunos.c	Wed Sep 19 12:57:04 2001
@@ -116,9 +116,9 @@
 	}
 
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	retval = do_mmap(file, addr, len, prot, flags, off);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	if(!ret_type)
 		retval = ((retval < PAGE_OFFSET) ? 0 : retval);
 
@@ -145,7 +145,7 @@
 	unsigned long rlim;
 	unsigned long newbrk, oldbrk;
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	if(ARCH_SUN4C_SUN4) {
 		if(brk >= 0x20000000 && brk < 0xe0000000) {
 			goto out;
@@ -208,7 +208,7 @@
 	do_brk(oldbrk, newbrk-oldbrk);
 	retval = 0;
 out:
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	return retval;
 }
 
diff -uNr linux-2.4.10-pre12/arch/sparc/mm/fault.c linux-mmsem/arch/sparc/mm/fault.c
--- linux-2.4.10-pre12/arch/sparc/mm/fault.c	Tue Sep 18 08:45:59 2001
+++ linux-mmsem/arch/sparc/mm/fault.c	Wed Sep 19 12:57:05 2001
@@ -222,7 +222,7 @@
         if (in_interrupt() || !mm)
                 goto no_context;
 
-	down_read(&mm->mmap_sem);
+	mm_lock_shared(mm);
 
 	/*
 	 * The kernel referencing a bad kernel pointer can lock up
@@ -272,7 +272,7 @@
 	default:
 		goto out_of_memory;
 	}
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	return;
 
 	/*
@@ -280,7 +280,7 @@
 	 * Fix it, but check if it's kernel or user first..
 	 */
 bad_area:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 
 bad_area_nosemaphore:
 	/* User mode accesses just cause a SIGSEGV */
@@ -336,14 +336,14 @@
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	printk("VM: killing process %s\n", tsk->comm);
 	if (from_user)
 		do_exit(SIGKILL);
 	goto no_context;
 
 do_sigbus:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	info.si_signo = SIGBUS;
 	info.si_errno = 0;
 	info.si_code = BUS_ADRERR;
@@ -477,7 +477,7 @@
 	printk("wf<pid=%d,wr=%d,addr=%08lx>\n",
 	       tsk->pid, write, address);
 #endif
-	down_read(&mm->mmap_sem);
+	mm_lock_shared(mm);
 	vma = find_vma(mm, address);
 	if(!vma)
 		goto bad_area;
@@ -498,10 +498,10 @@
 	}
 	if (!handle_mm_fault(mm, vma, address, write))
 		goto do_sigbus;
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	return;
 bad_area:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 #if 0
 	printk("Window whee %s [%d]: segfaults at %08lx\n",
 	       tsk->comm, tsk->pid, address);
@@ -516,7 +516,7 @@
 	return;
 
 do_sigbus:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	info.si_signo = SIGBUS;
 	info.si_errno = 0;
 	info.si_code = BUS_ADRERR;
diff -uNr linux-2.4.10-pre12/arch/sparc64/kernel/binfmt_aout32.c linux-mmsem/arch/sparc64/kernel/binfmt_aout32.c
--- linux-2.4.10-pre12/arch/sparc64/kernel/binfmt_aout32.c	Tue Sep 18 08:46:07 2001
+++ linux-mmsem/arch/sparc64/kernel/binfmt_aout32.c	Wed Sep 19 12:57:09 2001
@@ -277,24 +277,24 @@
 			goto beyond_if;
 		}
 
-	        down_write(&current->mm->mmap_sem);
+	        mm_lock_exclusive(current->mm);
 		error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
 			PROT_READ | PROT_EXEC,
 			MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
 			fd_offset);
-	        up_write(&current->mm->mmap_sem);
+	        mm_unlock_exclusive(current->mm);
 
 		if (error != N_TXTADDR(ex)) {
 			send_sig(SIGKILL, current, 0);
 			return error;
 		}
 
-	        down_write(&current->mm->mmap_sem);
+	        mm_lock_exclusive(current->mm);
  		error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
 				PROT_READ | PROT_WRITE | PROT_EXEC,
 				MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
 				fd_offset + ex.a_text);
-	        up_write(&current->mm->mmap_sem);
+	        mm_unlock_exclusive(current->mm);
 		if (error != N_DATADDR(ex)) {
 			send_sig(SIGKILL, current, 0);
 			return error;
@@ -369,12 +369,12 @@
 	start_addr =  ex.a_entry & 0xfffff000;
 
 	/* Now use mmap to map the library into memory. */
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
 			PROT_READ | PROT_WRITE | PROT_EXEC,
 			MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
 			N_TXTOFF(ex));
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	retval = error;
 	if (error != start_addr)
 		goto out;
diff -uNr linux-2.4.10-pre12/arch/sparc64/kernel/sys_sparc.c linux-mmsem/arch/sparc64/kernel/sys_sparc.c
--- linux-2.4.10-pre12/arch/sparc64/kernel/sys_sparc.c	Tue Sep 18 08:46:06 2001
+++ linux-mmsem/arch/sparc64/kernel/sys_sparc.c	Wed Sep 19 12:57:09 2001
@@ -292,9 +292,9 @@
 			goto out_putf;
 	}
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	retval = do_mmap(file, addr, len, prot, flags, off);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 
 out_putf:
 	if (file)
@@ -310,9 +310,9 @@
 	if (len > -PAGE_OFFSET ||
 	    (addr < PAGE_OFFSET && addr + len > -PAGE_OFFSET))
 		return -EINVAL;
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	ret = do_munmap(current->mm, addr, len);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	return ret;
 }
 
@@ -332,7 +332,7 @@
 		goto out;
 	if (addr < PAGE_OFFSET && addr + old_len > -PAGE_OFFSET)
 		goto out;
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	if (flags & MREMAP_FIXED) {
 		if (new_addr < PAGE_OFFSET &&
 		    new_addr + new_len > -PAGE_OFFSET)
@@ -363,7 +363,7 @@
 	}
 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
 out_sem:
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 out:
 	return ret;       
 }
diff -uNr linux-2.4.10-pre12/arch/sparc64/kernel/sys_sparc32.c linux-mmsem/arch/sparc64/kernel/sys_sparc32.c
--- linux-2.4.10-pre12/arch/sparc64/kernel/sys_sparc32.c	Tue Sep 18 08:46:06 2001
+++ linux-mmsem/arch/sparc64/kernel/sys_sparc32.c	Wed Sep 19 12:57:09 2001
@@ -4141,7 +4141,7 @@
 		goto out;
 	if (addr > 0xf0000000UL - old_len)
 		goto out;
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	if (flags & MREMAP_FIXED) {
 		if (new_addr > 0xf0000000UL - new_len)
 			goto out_sem;
@@ -4171,7 +4171,7 @@
 	}
 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
 out_sem:
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 out:
 	return ret;       
 }
diff -uNr linux-2.4.10-pre12/arch/sparc64/kernel/sys_sunos32.c linux-mmsem/arch/sparc64/kernel/sys_sunos32.c
--- linux-2.4.10-pre12/arch/sparc64/kernel/sys_sunos32.c	Tue Sep 18 08:46:08 2001
+++ linux-mmsem/arch/sparc64/kernel/sys_sunos32.c	Wed Sep 19 12:57:09 2001
@@ -100,12 +100,12 @@
 	flags &= ~_MAP_NEW;
 
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	retval = do_mmap(file,
 			 (unsigned long) addr, (unsigned long) len,
 			 (unsigned long) prot, (unsigned long) flags,
 			 (unsigned long) off);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	if(!ret_type)
 		retval = ((retval < 0xf0000000) ? 0 : retval);
 out_putf:
@@ -126,7 +126,7 @@
 	unsigned long rlim;
 	unsigned long newbrk, oldbrk, brk = (unsigned long) baddr;
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	if (brk < current->mm->end_code)
 		goto out;
 	newbrk = PAGE_ALIGN(brk);
@@ -170,7 +170,7 @@
 	do_brk(oldbrk, newbrk-oldbrk);
 	retval = 0;
 out:
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	return retval;
 }
 
diff -uNr linux-2.4.10-pre12/arch/sparc64/mm/fault.c linux-mmsem/arch/sparc64/mm/fault.c
--- linux-2.4.10-pre12/arch/sparc64/mm/fault.c	Wed Sep 19 10:39:08 2001
+++ linux-mmsem/arch/sparc64/mm/fault.c	Wed Sep 19 12:57:09 2001
@@ -306,7 +306,7 @@
 		address &= 0xffffffff;
 	}
 
-	down_read(&mm->mmap_sem);
+	mm_lock_shared(mm);
 	vma = find_vma(mm, address);
 	if (!vma)
 		goto bad_area;
@@ -378,7 +378,7 @@
 		goto out_of_memory;
 	}
 
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	goto fault_done;
 
 	/*
@@ -387,7 +387,7 @@
 	 */
 bad_area:
 	insn = get_fault_insn(regs, insn);
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 
 handle_kernel_fault:
 	do_kernel_fault(regs, si_code, fault_code, insn, address);
@@ -400,7 +400,7 @@
  */
 out_of_memory:
 	insn = get_fault_insn(regs, insn);
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	printk("VM: killing process %s\n", current->comm);
 	if (!(regs->tstate & TSTATE_PRIV))
 		do_exit(SIGKILL);
@@ -412,7 +412,7 @@
 
 do_sigbus:
 	insn = get_fault_insn(regs, insn);
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 
 	/*
 	 * Send a sigbus, regardless of whether we were in kernel
diff -uNr linux-2.4.10-pre12/arch/sparc64/solaris/misc.c linux-mmsem/arch/sparc64/solaris/misc.c
--- linux-2.4.10-pre12/arch/sparc64/solaris/misc.c	Wed Sep 19 10:39:08 2001
+++ linux-mmsem/arch/sparc64/solaris/misc.c	Wed Sep 19 12:57:09 2001
@@ -92,12 +92,12 @@
 	ret_type = flags & _MAP_NEW;
 	flags &= ~_MAP_NEW;
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 	retval = do_mmap(file,
 			 (unsigned long) addr, (unsigned long) len,
 			 (unsigned long) prot, (unsigned long) flags, off);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	if(!ret_type)
 		retval = ((retval < 0xf0000000) ? 0 : retval);
 	                        
diff -uNr linux-2.4.10-pre12/drivers/char/mem.c linux-mmsem/drivers/char/mem.c
--- linux-2.4.10-pre12/drivers/char/mem.c	Wed Sep 19 10:39:10 2001
+++ linux-mmsem/drivers/char/mem.c	Wed Sep 19 12:58:59 2001
@@ -350,7 +350,7 @@
 
 	mm = current->mm;
 	/* Oops, this was forgotten before. -ben */
-	down_read(&mm->mmap_sem);
+	mm_lock_shared(mm);
 
 	/* For private mappings, just map in zero pages. */
 	for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) {
@@ -374,7 +374,7 @@
 			goto out_up;
 	}
 
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	
 	/* The shared case is hard. Let's do the conventional zeroing. */ 
 	do {
@@ -389,7 +389,7 @@
 
 	return size;
 out_up:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	return size;
 }
 
diff -uNr linux-2.4.10-pre12/drivers/sgi/char/graphics.c linux-mmsem/drivers/sgi/char/graphics.c
--- linux-2.4.10-pre12/drivers/sgi/char/graphics.c	Wed Sep 19 10:39:17 2001
+++ linux-mmsem/drivers/sgi/char/graphics.c	Wed Sep 19 12:59:13 2001
@@ -152,11 +152,11 @@
 		 * sgi_graphics_mmap
 		 */
 		disable_gconsole ();
-		down_write(&current->mm->mmap_sem);
+		mm_lock_exclusive(current->mm);
 		r = do_mmap (file, (unsigned long)vaddr,
 			     cards[board].g_regs_size, PROT_READ|PROT_WRITE,
 			     MAP_FIXED|MAP_PRIVATE, 0);
-		up_write(&current->mm->mmap_sem);
+		mm_unlock_exclusive(current->mm);
 		if (r)
 			return r;
 	}
diff -uNr linux-2.4.10-pre12/drivers/sgi/char/shmiq.c linux-mmsem/drivers/sgi/char/shmiq.c
--- linux-2.4.10-pre12/drivers/sgi/char/shmiq.c	Wed Sep 19 10:39:17 2001
+++ linux-mmsem/drivers/sgi/char/shmiq.c	Wed Sep 19 12:59:13 2001
@@ -285,11 +285,11 @@
 			s = req.arg * sizeof (struct shmqevent) +
 			    sizeof (struct sharedMemoryInputQueue);
 			v = sys_munmap (vaddr, s);
-			down_write(&current->mm->mmap_sem);
+			mm_lock_exclusive(current->mm);
 			do_munmap(current->mm, vaddr, s);
 			do_mmap(filp, vaddr, s, PROT_READ | PROT_WRITE,
 			        MAP_PRIVATE|MAP_FIXED, 0);
-			up_write(&current->mm->mmap_sem);
+			mm_unlock_exclusive(current->mm);
 			shmiqs[minor].events = req.arg;
 			shmiqs[minor].mapped = 1;
 
diff -uNr linux-2.4.10-pre12/fs/binfmt_aout.c linux-mmsem/fs/binfmt_aout.c
--- linux-2.4.10-pre12/fs/binfmt_aout.c	Wed Sep 19 10:39:20 2001
+++ linux-mmsem/fs/binfmt_aout.c	Wed Sep 19 11:42:59 2001
@@ -377,24 +377,24 @@
 			goto beyond_if;
 		}
 
-		down_write(&current->mm->mmap_sem);
+		mm_lock_exclusive(current->mm);
 		error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
 			PROT_READ | PROT_EXEC,
 			MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
 			fd_offset);
-		up_write(&current->mm->mmap_sem);
+		mm_unlock_exclusive(current->mm);
 
 		if (error != N_TXTADDR(ex)) {
 			send_sig(SIGKILL, current, 0);
 			return error;
 		}
 
-		down_write(&current->mm->mmap_sem);
+		mm_lock_exclusive(current->mm);
  		error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
 				PROT_READ | PROT_WRITE | PROT_EXEC,
 				MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
 				fd_offset + ex.a_text);
-		up_write(&current->mm->mmap_sem);
+		mm_unlock_exclusive(current->mm);
 		if (error != N_DATADDR(ex)) {
 			send_sig(SIGKILL, current, 0);
 			return error;
@@ -476,12 +476,12 @@
 		goto out;
 	}
 	/* Now use mmap to map the library into memory. */
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
 			PROT_READ | PROT_WRITE | PROT_EXEC,
 			MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
 			N_TXTOFF(ex));
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	retval = error;
 	if (error != start_addr)
 		goto out;
diff -uNr linux-2.4.10-pre12/fs/binfmt_elf.c linux-mmsem/fs/binfmt_elf.c
--- linux-2.4.10-pre12/fs/binfmt_elf.c	Wed Sep 19 10:39:20 2001
+++ linux-mmsem/fs/binfmt_elf.c	Wed Sep 19 11:43:48 2001
@@ -224,11 +224,11 @@
 {
 	unsigned long map_addr;
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	map_addr = do_mmap(filep, ELF_PAGESTART(addr),
 			   eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr), prot, type,
 			   eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr));
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	return(map_addr);
 }
 
@@ -743,10 +743,10 @@
 		   Since we do not have the power to recompile these, we
 		   emulate the SVr4 behavior.  Sigh.  */
 		/* N.B. Shouldn't the size here be PAGE_SIZE?? */
-		down_write(&current->mm->mmap_sem);
+		mm_lock_exclusive(current->mm);
 		error = do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC,
 				MAP_FIXED | MAP_PRIVATE, 0);
-		up_write(&current->mm->mmap_sem);
+		mm_unlock_exclusive(current->mm);
 	}
 
 #ifdef ELF_PLAT_INIT
@@ -827,7 +827,7 @@
 	while (elf_phdata->p_type != PT_LOAD) elf_phdata++;
 
 	/* Now use mmap to map the library into memory. */
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	error = do_mmap(file,
 			ELF_PAGESTART(elf_phdata->p_vaddr),
 			(elf_phdata->p_filesz +
@@ -836,7 +836,7 @@
 			MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
 			(elf_phdata->p_offset -
 			 ELF_PAGEOFFSET(elf_phdata->p_vaddr)));
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	if (error != ELF_PAGESTART(elf_phdata->p_vaddr))
 		goto out_free_ph;
 
diff -uNr linux-2.4.10-pre12/fs/exec.c linux-mmsem/fs/exec.c
--- linux-2.4.10-pre12/fs/exec.c	Wed Sep 19 10:39:20 2001
+++ linux-mmsem/fs/exec.c	Wed Sep 19 11:44:38 2001
@@ -307,7 +307,7 @@
 	if (!mpnt) 
 		return -ENOMEM; 
 	
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	{
 		mpnt->vm_mm = current->mm;
 		mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
@@ -330,7 +330,7 @@
 		}
 		stack_base += PAGE_SIZE;
 	}
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	
 	return 0;
 }
@@ -969,9 +969,9 @@
 	if (do_truncate(file->f_dentry, 0) != 0)
 		goto close_fail;
 
-	down_read(&current->mm->mmap_sem);
+	mm_lock_shared(current->mm);
 	retval = binfmt->core_dump(signr, regs, file);
-	up_read(&current->mm->mmap_sem);
+	mm_unlock_shared(current->mm);
 
 close_fail:
 	filp_close(file, NULL);
diff -uNr linux-2.4.10-pre12/fs/proc/array.c linux-mmsem/fs/proc/array.c
--- linux-2.4.10-pre12/fs/proc/array.c	Tue Sep 18 08:45:09 2001
+++ linux-mmsem/fs/proc/array.c	Wed Sep 19 11:47:34 2001
@@ -181,7 +181,7 @@
 	unsigned long data = 0, stack = 0;
 	unsigned long exec = 0, lib = 0;
 
-	down_read(&mm->mmap_sem);
+	mm_lock_shared(mm);
 	for (vma = mm->mmap; vma; vma = vma->vm_next) {
 		unsigned long len = (vma->vm_end - vma->vm_start) >> 10;
 		if (!vma->vm_file) {
@@ -212,7 +212,7 @@
 		mm->rss << (PAGE_SHIFT-10),
 		data - stack, stack,
 		exec - lib, lib);
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	return buffer;
 }
 
@@ -317,7 +317,7 @@
 	task_unlock(task);
 	if (mm) {
 		struct vm_area_struct *vma;
-		down_read(&mm->mmap_sem);
+		mm_lock_shared(mm);
 		vma = mm->mmap;
 		while (vma) {
 			vsize += vma->vm_end - vma->vm_start;
@@ -325,7 +325,7 @@
 		}
 		eip = KSTK_EIP(task);
 		esp = KSTK_ESP(task);
-		up_read(&mm->mmap_sem);
+		mm_unlock_shared(mm);
 	}
 
 	wchan = get_wchan(task);
@@ -479,7 +479,7 @@
 	task_unlock(task);
 	if (mm) {
 		struct vm_area_struct * vma;
-		down_read(&mm->mmap_sem);
+		mm_lock_shared(mm);
 		vma = mm->mmap;
 		while (vma) {
 			pgd_t *pgd = pgd_offset(mm, vma->vm_start);
@@ -500,7 +500,7 @@
 				drs += pages;
 			vma = vma->vm_next;
 		}
-		up_read(&mm->mmap_sem);
+		mm_unlock_shared(mm);
 		mmput(mm);
 	}
 	return sprintf(buffer,"%d %d %d %d %d %d %d\n",
@@ -577,7 +577,7 @@
 	column = *ppos & (MAPS_LINE_LENGTH-1);
 
 	/* quickly go to line lineno */
-	down_read(&mm->mmap_sem);
+	mm_lock_shared(mm);
 	for (map = mm->mmap, i = 0; map && (i < lineno); map = map->vm_next, i++)
 		continue;
 
@@ -658,7 +658,7 @@
 		if (volatile_task)
 			break;
 	}
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 
 	/* encode f_pos */
 	*ppos = (lineno << MAPS_LINE_SHIFT) + column;
diff -uNr linux-2.4.10-pre12/fs/proc/base.c linux-mmsem/fs/proc/base.c
--- linux-2.4.10-pre12/fs/proc/base.c	Tue Sep 18 08:45:09 2001
+++ linux-mmsem/fs/proc/base.c	Wed Sep 19 11:47:49 2001
@@ -64,7 +64,7 @@
 	task_unlock(task);
 	if (!mm)
 		goto out;
-	down_read(&mm->mmap_sem);
+	mm_lock_shared(mm);
 	vma = mm->mmap;
 	while (vma) {
 		if ((vma->vm_flags & VM_EXECUTABLE) && 
@@ -76,7 +76,7 @@
 		}
 		vma = vma->vm_next;
 	}
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	mmput(mm);
 out:
 	return result;
diff -uNr linux-2.4.10-pre12/include/linux/sched.h linux-mmsem/include/linux/sched.h
--- linux-2.4.10-pre12/include/linux/sched.h	Wed Sep 19 10:39:23 2001
+++ linux-mmsem/include/linux/sched.h	Wed Sep 19 13:07:34 2001
@@ -209,7 +209,9 @@
 	atomic_t mm_users;			/* How many users with user space? */
 	atomic_t mm_count;			/* How many references to "struct mm_struct" (users count as 1) */
 	int map_count;				/* number of VMAs */
-	struct rw_semaphore mmap_sem;
+	spinlock_t mmsem_lock;			/* protects access to mmsem stuff */
+	int mmsem_activity;			/* 0 inactive, +n active readers, -1 active writer */
+	struct list_head mmsem_waiters;
 	spinlock_t page_table_lock;		/* Protects task page tables and mm->rss */
 
 	struct list_head mmlist;		/* List of all active mm's.  These are globally strung
@@ -233,15 +235,70 @@
 
 extern int mmlist_nr;
 
-#define INIT_MM(name) \
-{			 				\
-	mm_rb:		RB_ROOT,			\
-	pgd:		swapper_pg_dir, 		\
-	mm_users:	ATOMIC_INIT(2), 		\
-	mm_count:	ATOMIC_INIT(1), 		\
-	mmap_sem:	__RWSEM_INITIALIZER(name.mmap_sem), \
-	page_table_lock: SPIN_LOCK_UNLOCKED, 		\
-	mmlist:		LIST_HEAD_INIT(name.mmlist),	\
+#define INIT_MM(name)						\
+{								\
+	mm_rb:		RB_ROOT,				\
+	pgd:		swapper_pg_dir,				\
+	mm_users:	ATOMIC_INIT(2),				\
+	mm_count:	ATOMIC_INIT(1),				\
+	mmsem_lock:	SPIN_LOCK_UNLOCKED,			\
+	mmsem_activity:	0,					\
+	mmsem_waiters:	LIST_HEAD_INIT(name.mmsem_waiters),	\
+	page_table_lock: SPIN_LOCK_UNLOCKED,			\
+	mmlist:		LIST_HEAD_INIT(name.mmlist),		\
+}
+
+extern void __mm_lock_wait(struct mm_struct *mm, int bias);
+extern void __mm_lock_wake(struct mm_struct *mm);
+
+static inline void mm_lock_shared(struct mm_struct *mm)
+{
+	spin_lock(&mm->mmsem_lock);
+	if (mm->mmsem_activity>=0 && list_empty(&mm->mmsem_waiters)) {
+		mm->mmsem_activity++;
+		spin_unlock(&mm->mmsem_lock);
+	}
+	else
+		__mm_lock_wait(mm,1);
+}
+
+static inline void mm_lock_shared_recursive(struct mm_struct *mm)
+{
+	spin_lock(&mm->mmsem_lock);
+	if (mm->mmsem_activity>=0) {
+		mm->mmsem_activity++;
+		spin_unlock(&mm->mmsem_lock);
+	}
+	else
+		__mm_lock_wait(mm,1);
+}
+
+static inline void mm_unlock_shared(struct mm_struct *mm)
+{
+	spin_lock(&mm->mmsem_lock);
+	if (!--mm->mmsem_activity && !list_empty(&mm->mmsem_waiters))
+		__mm_lock_wake(mm);
+	spin_unlock(&mm->mmsem_lock);
+}
+
+static inline void mm_lock_exclusive(struct mm_struct *mm)
+{
+	spin_lock(&mm->mmsem_lock);
+	if (mm->mmsem_activity==0) {
+		mm->mmsem_activity--;
+		spin_unlock(&mm->mmsem_lock);
+	}
+	else
+		__mm_lock_wait(mm,-1);
+}
+
+static inline void mm_unlock_exclusive(struct mm_struct *mm)
+{
+	spin_lock(&mm->mmsem_lock);
+	mm->mmsem_activity++;
+	if (!list_empty(&mm->mmsem_waiters))
+		__mm_lock_wake(mm);
+	spin_unlock(&mm->mmsem_lock);
 }
 
 struct signal_struct {
diff -uNr linux-2.4.10-pre12/ipc/shm.c linux-mmsem/ipc/shm.c
--- linux-2.4.10-pre12/ipc/shm.c	Wed Sep 19 10:39:23 2001
+++ linux-mmsem/ipc/shm.c	Wed Sep 19 12:32:57 2001
@@ -619,9 +619,9 @@
 	shp->shm_nattch++;
 	shm_unlock(shmid);
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	user_addr = (void *) do_mmap (file, addr, file->f_dentry->d_inode->i_size, prot, flags, 0);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 
 	down (&shm_ids.sem);
 	if(!(shp = shm_lock(shmid)))
@@ -650,14 +650,14 @@
 	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *shmd, *shmdnext;
 
-	down_write(&mm->mmap_sem);
+	mm_lock_exclusive(mm);
 	for (shmd = mm->mmap; shmd; shmd = shmdnext) {
 		shmdnext = shmd->vm_next;
 		if (shmd->vm_ops == &shm_vm_ops
 		    && shmd->vm_start - (shmd->vm_pgoff << PAGE_SHIFT) == (ulong) shmaddr)
 			do_munmap(mm, shmd->vm_start, shmd->vm_end - shmd->vm_start);
 	}
-	up_write(&mm->mmap_sem);
+	mm_unlock_exclusive(mm);
 	return 0;
 }
 
diff -uNr linux-2.4.10-pre12/kernel/acct.c linux-mmsem/kernel/acct.c
--- linux-2.4.10-pre12/kernel/acct.c	Tue Sep 18 08:45:11 2001
+++ linux-mmsem/kernel/acct.c	Wed Sep 19 11:38:59 2001
@@ -315,13 +315,13 @@
 	vsize = 0;
 	if (current->mm) {
 		struct vm_area_struct *vma;
-		down_read(&current->mm->mmap_sem);
+		mm_lock_shared(current->mm);
 		vma = current->mm->mmap;
 		while (vma) {
 			vsize += vma->vm_end - vma->vm_start;
 			vma = vma->vm_next;
 		}
-		up_read(&current->mm->mmap_sem);
+		mm_unlock_shared(current->mm);
 	}
 	vsize = vsize / 1024;
 	ac.ac_mem = encode_comp_t(vsize);
diff -uNr linux-2.4.10-pre12/kernel/fork.c linux-mmsem/kernel/fork.c
--- linux-2.4.10-pre12/kernel/fork.c	Wed Sep 19 10:39:23 2001
+++ linux-mmsem/kernel/fork.c	Wed Sep 19 11:41:48 2001
@@ -216,7 +216,9 @@
 {
 	atomic_set(&mm->mm_users, 1);
 	atomic_set(&mm->mm_count, 1);
-	init_rwsem(&mm->mmap_sem);
+	spin_lock_init(&mm->mmsem_lock);
+	mm->mmsem_activity = 0;
+	INIT_LIST_HEAD(&mm->mmsem_waiters);
 	mm->page_table_lock = SPIN_LOCK_UNLOCKED;
 	mm->pgd = pgd_alloc(mm);
 	if (mm->pgd)
@@ -333,9 +335,9 @@
 	if (!mm_init(mm))
 		goto fail_nomem;
 
-	down_write(&oldmm->mmap_sem);
+	mm_lock_exclusive(oldmm);
 	retval = dup_mmap(mm);
-	up_write(&oldmm->mmap_sem);
+	mm_unlock_exclusive(oldmm);
 
 	if (retval)
 		goto free_pt;
diff -uNr linux-2.4.10-pre12/kernel/ksyms.c linux-mmsem/kernel/ksyms.c
--- linux-2.4.10-pre12/kernel/ksyms.c	Wed Sep 19 10:39:23 2001
+++ linux-mmsem/kernel/ksyms.c	Wed Sep 19 14:13:42 2001
@@ -87,6 +87,8 @@
 EXPORT_SYMBOL(exit_files);
 EXPORT_SYMBOL(exit_fs);
 EXPORT_SYMBOL(exit_sighand);
+EXPORT_SYMBOL(__mm_lock_wait);
+EXPORT_SYMBOL(__mm_lock_wake);
 
 /* internal kernel memory management */
 EXPORT_SYMBOL(_alloc_pages);
diff -uNr linux-2.4.10-pre12/kernel/ptrace.c linux-mmsem/kernel/ptrace.c
--- linux-2.4.10-pre12/kernel/ptrace.c	Wed Sep 19 10:39:23 2001
+++ linux-mmsem/kernel/ptrace.c	Wed Sep 19 11:40:34 2001
@@ -208,13 +208,13 @@
 	if (!mm)
 		return 0;
 
-	down_read(&mm->mmap_sem);
+	mm_lock_shared(mm);
 	vma = find_extend_vma(mm, addr);
 	copied = 0;
 	if (vma)
 		copied = access_mm(mm, vma, addr, buf, len, write);
 
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	mmput(mm);
 	return copied;
 }
diff -uNr linux-2.4.10-pre12/mm/filemap.c linux-mmsem/mm/filemap.c
--- linux-2.4.10-pre12/mm/filemap.c	Wed Sep 19 10:39:24 2001
+++ linux-mmsem/mm/filemap.c	Wed Sep 19 11:33:14 2001
@@ -1949,7 +1949,7 @@
 	struct vm_area_struct * vma;
 	int unmapped_error, error = -EINVAL;
 
-	down_read(&current->mm->mmap_sem);
+	mm_lock_shared(current->mm);
 	if (start & ~PAGE_MASK)
 		goto out;
 	len = (len + ~PAGE_MASK) & PAGE_MASK;
@@ -1995,7 +1995,7 @@
 		vma = vma->vm_next;
 	}
 out:
-	up_read(&current->mm->mmap_sem);
+	mm_unlock_shared(current->mm);
 	return error;
 }
 
@@ -2298,7 +2298,7 @@
 	int unmapped_error = 0;
 	int error = -EINVAL;
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 
 	if (start & ~PAGE_MASK)
 		goto out;
@@ -2349,7 +2349,7 @@
 	}
 
 out:
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	return error;
 }
 
@@ -2451,7 +2451,7 @@
 	int unmapped_error = 0;
 	long error = -EINVAL;
 
-	down_read(&current->mm->mmap_sem);
+	mm_lock_shared(current->mm);
 
 	if (start & ~PAGE_CACHE_MASK)
 		goto out;
@@ -2503,7 +2503,7 @@
 	}
 
 out:
-	up_read(&current->mm->mmap_sem);
+	mm_unlock_shared(current->mm);
 	return error;
 }
 
diff -uNr linux-2.4.10-pre12/mm/memory.c linux-mmsem/mm/memory.c
--- linux-2.4.10-pre12/mm/memory.c	Wed Sep 19 10:39:24 2001
+++ linux-mmsem/mm/memory.c	Wed Sep 19 11:33:28 2001
@@ -464,7 +464,7 @@
 	if (err)
 		return err;
 
-	down_read(&mm->mmap_sem);
+	mm_lock_shared(mm);
 
 	err = -EFAULT;
 	iobuf->locked = 0;
@@ -522,12 +522,12 @@
 		ptr += PAGE_SIZE;
 	}
 
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	dprintk ("map_user_kiobuf: end OK\n");
 	return 0;
 
  out_unlock:
-	up_read(&mm->mmap_sem);
+	mm_unlock_shared(mm);
 	unmap_kiobuf(iobuf);
 	dprintk ("map_user_kiobuf: end %d\n", err);
 	return err;
diff -uNr linux-2.4.10-pre12/mm/mlock.c linux-mmsem/mm/mlock.c
--- linux-2.4.10-pre12/mm/mlock.c	Wed Sep 19 10:39:24 2001
+++ linux-mmsem/mm/mlock.c	Wed Sep 19 11:35:27 2001
@@ -198,7 +198,7 @@
 	unsigned long lock_limit;
 	int error = -ENOMEM;
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	len = PAGE_ALIGN(len + (start & ~PAGE_MASK));
 	start &= PAGE_MASK;
 
@@ -219,7 +219,7 @@
 
 	error = do_mlock(start, len, 1);
 out:
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	return error;
 }
 
@@ -227,11 +227,11 @@
 {
 	int ret;
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	len = PAGE_ALIGN(len + (start & ~PAGE_MASK));
 	start &= PAGE_MASK;
 	ret = do_mlock(start, len, 0);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	return ret;
 }
 
@@ -268,7 +268,7 @@
 	unsigned long lock_limit;
 	int ret = -EINVAL;
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	if (!flags || (flags & ~(MCL_CURRENT | MCL_FUTURE)))
 		goto out;
 
@@ -286,7 +286,7 @@
 
 	ret = do_mlockall(flags);
 out:
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	return ret;
 }
 
@@ -294,8 +294,8 @@
 {
 	int ret;
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	ret = do_mlockall(0);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	return ret;
 }
diff -uNr linux-2.4.10-pre12/mm/mmap.c linux-mmsem/mm/mmap.c
--- linux-2.4.10-pre12/mm/mmap.c	Wed Sep 19 10:39:24 2001
+++ linux-mmsem/mm/mmap.c	Wed Sep 19 13:24:42 2001
@@ -149,7 +149,7 @@
 	unsigned long newbrk, oldbrk;
 	struct mm_struct *mm = current->mm;
 
-	down_write(&mm->mmap_sem);
+	mm_lock_exclusive(mm);
 
 	if (brk < mm->end_code)
 		goto out;
@@ -185,7 +185,7 @@
 	mm->brk = brk;
 out:
 	retval = mm->brk;
-	up_write(&mm->mmap_sem);
+	mm_unlock_exclusive(mm);
 	return retval;
 }
 
@@ -995,9 +995,9 @@
 	int ret;
 	struct mm_struct *mm = current->mm;
 
-	down_write(&mm->mmap_sem);
+	mm_lock_exclusive(mm);
 	ret = do_munmap(mm, addr, len);
-	up_write(&mm->mmap_sem);
+	mm_unlock_exclusive(mm);
 	return ret;
 }
 
@@ -1172,4 +1172,86 @@
 		BUG();
 	vma_link(mm, vma, prev, rb_link, rb_parent);
 	validate_mm(mm);
+}
+
+
+struct mm_waiter {
+	struct list_head	list;
+	struct task_struct	*task;
+	unsigned int		flags;
+#define MM_WAITING_FOR_READ	0x00000001
+#define MM_WAITING_FOR_WRITE	0x00000002
+};
+
+/*
+ * handle the lock being released whilst there are processes blocked on it that can now run
+ * - if we come here, then:
+ *   - the 'active count' _reached_ zero
+ *   - the 'waiting count' is non-zero
+ * - the spinlock must be held by the caller
+ * - woken process blocks are discarded from the list after having flags zeroised
+ */
+void __mm_lock_wake(struct mm_struct *mm)
+{
+	struct mm_waiter *waiter;
+	int woken;
+
+	waiter = list_entry(mm->mmsem_waiters.next,struct mm_waiter,list);
+
+	/* try to grant a single write lock if there's a writer at the front of the queue
+	 * - we leave the 'waiting count' incremented to signify potential contention
+	 */
+	if (waiter->flags & MM_WAITING_FOR_WRITE) {
+		mm->mmsem_activity = -1;
+		list_del(&waiter->list);
+		waiter->flags = 0;
+		wake_up_process(waiter->task);
+		return;
+	}
+
+	/* grant an infinite number of read locks to the readers at the front of the queue */
+	woken = 0;
+	do {
+		list_del(&waiter->list);
+		waiter->flags = 0;
+		wake_up_process(waiter->task);
+		woken++;
+		if (list_empty(&mm->mmsem_waiters))
+			break;
+		waiter = list_entry(mm->mmsem_waiters.next,struct mm_waiter,list);
+	} while (waiter->flags&MM_WAITING_FOR_READ);
+
+	mm->mmsem_activity += woken;
+}
+
+/*
+ * wait for a lock on the mm_struct
+ * - must be entered with the mmsem_lock spinlock held
+ */
+void __mm_lock_wait(struct mm_struct *mm, int bias)
+{
+	struct mm_waiter waiter;
+	struct task_struct *tsk;
+
+	tsk = current;
+	set_task_state(tsk,TASK_UNINTERRUPTIBLE);
+
+	/* add to the waitqueue */
+	waiter.task = tsk;
+	waiter.flags = MM_WAITING_FOR_READ;
+
+	list_add_tail(&waiter.list,&mm->mmsem_waiters);
+
+	/* we don't need to touch the mm_struct anymore */
+	spin_unlock(&mm->mmsem_lock);
+
+	/* wait to be given the lock */
+	for (;;) {
+		if (!waiter.flags)
+			break;
+		schedule();
+		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+	}
+
+	tsk->state = TASK_RUNNING;
 }
diff -uNr linux-2.4.10-pre12/mm/mprotect.c linux-mmsem/mm/mprotect.c
--- linux-2.4.10-pre12/mm/mprotect.c	Wed Sep 19 10:39:24 2001
+++ linux-mmsem/mm/mprotect.c	Wed Sep 19 11:36:18 2001
@@ -281,7 +281,7 @@
 	if (end == start)
 		return 0;
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 
 	vma = find_vma_prev(current->mm, start, &prev);
 	error = -EFAULT;
@@ -332,6 +332,6 @@
 		prev->vm_mm->map_count--;
 	}
 out:
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	return error;
 }
diff -uNr linux-2.4.10-pre12/mm/mremap.c linux-mmsem/mm/mremap.c
--- linux-2.4.10-pre12/mm/mremap.c	Wed Sep 19 10:39:24 2001
+++ linux-mmsem/mm/mremap.c	Wed Sep 19 11:36:35 2001
@@ -346,8 +346,8 @@
 {
 	unsigned long ret;
 
-	down_write(&current->mm->mmap_sem);
+	mm_lock_exclusive(current->mm);
 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
-	up_write(&current->mm->mmap_sem);
+	mm_unlock_exclusive(current->mm);
 	return ret;
 }

  parent reply	other threads:[~2001-09-19 14:51 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-09-17 21:50 Deadlock on the mm->mmap_sem Manfred Spraul
2001-09-17 23:39 ` Linus Torvalds
     [not found] ` <200109172339.f8HNd5W13244@penguin.transmeta.com>
2001-09-18  0:01   ` Andrea Arcangeli
2001-09-18  7:31     ` Manfred Spraul
2001-09-18  7:55       ` Andrea Arcangeli
2001-09-18  8:18         ` David Howells
2001-09-18  9:32         ` David Howells
2001-09-18  9:37         ` Manfred Spraul
2001-09-18  9:49         ` Arjan van de Ven
2001-09-18 12:53         ` Manfred Spraul
2001-09-18 14:13           ` David Howells
2001-09-18 14:49             ` Alan Cox
2001-09-18 15:26               ` David Howells
2001-09-18 15:46                 ` Alan Cox
2001-09-18 15:11             ` David Howells
2001-09-18 16:49             ` Linus Torvalds
2001-09-19  9:51               ` David Howells
2001-09-19 12:49                 ` Andrea Arcangeli
2001-09-19 14:08               ` Manfred Spraul
2001-09-19 14:51               ` David Howells [this message]
2001-09-19 15:18                 ` Manfred Spraul
2001-09-19 14:53               ` David Howells
2001-09-19 18:03                 ` Andrea Arcangeli
2001-09-19 18:16                   ` Benjamin LaHaise
2001-09-19 18:27                     ` David Howells
2001-09-19 18:48                       ` Andrea Arcangeli
2001-09-19 18:45                     ` Andrea Arcangeli
2001-09-19 21:14                       ` Benjamin LaHaise
2001-09-19 22:07                         ` Andrea Arcangeli
2001-09-19 18:19                   ` Manfred Spraul
2001-09-20  2:07                     ` Andrea Arcangeli
2001-09-20  4:37                       ` Andrea Arcangeli
2001-09-20  7:05                       ` David Howells
2001-09-20  7:19                         ` Andrea Arcangeli
2001-09-20  8:01                           ` David Howells
2001-09-20  8:09                             ` Andrea Arcangeli
2001-09-19 18:26                   ` David Howells
2001-09-19 18:47                     ` Andrea Arcangeli
2001-09-19 23:25                       ` David Howells
2001-09-19 23:34                         ` Andrea Arcangeli
2001-09-19 23:46                           ` Andrea Arcangeli
2001-09-19 23:24                 ` [PATCH] attempt #2 (Re: Deadlock on the mm->mmap_sem) David Howells
2001-09-19 14:58               ` Deadlock on the mm->mmap_sem David Howells
     [not found] <masp0008@stud.uni-sb.de>
2001-09-20 10:57 ` Studierende der Universitaet des Saarlandes
2001-09-20 12:40   ` David Howells
2001-09-20 18:24   ` Andrea Arcangeli
2001-09-20 21:43     ` Manfred Spraul
2001-09-22 21:06     ` Manfred Spraul
  -- strict thread matches above, loose matches on Subject: below --
2001-09-18 13:22 Ulrich Weigand
2001-09-17 20:57 Ulrich Weigand

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5063.1000911094@warthog.cambridge.redhat.com \
    --to=dhowells@redhat.com \
    --cc=Ulrich.Weigand@de.ibm.com \
    --cc=andrea@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=manfred@colorfullife.com \
    --cc=torvalds@transmeta.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).