diff -Nurd linux-2.4.28/include/linux/mm.h linux-2.4.28-CAN-2005-0001/include/linux/mm.h
--- linux-2.4.28/include/linux/mm.h	2005-01-13 07:16:01.554468556 +0100
+++ linux-2.4.28-CAN-2005-0001/include/linux/mm.h	2005-01-13 07:18:49.042584561 +0100
@@ -695,12 +695,19 @@
 #endif
 
 	/*
-	 * vma->vm_start/vm_end cannot change under us because the caller is required
-	 * to hold the mmap_sem in write mode. We need to get the spinlock only
-	 * before relocating the vma range ourself.
+	 * vma->vm_start/vm_end cannot change under us because the caller
+	 * is required to hold the mmap_sem in read mode.  We need the
+	 * page_table_lock lock to serialize against concurrent expand_stacks.
 	 */
 	address &= PAGE_MASK;
  	spin_lock(&vma->vm_mm->page_table_lock);
+ 	
+ 	/* already expanded while we were spinning? */
+ 	if (vma->vm_start <= address) {
+ 		spin_unlock(&vma->vm_mm->page_table_lock);
+ 		return 0;
+	}
+	
 	grow = (vma->vm_start - address) >> PAGE_SHIFT;
 
 	gr_learn_resource(current, RLIMIT_STACK, vma->vm_end - address, 1);
