patch-2.4.21 linux-2.4.21/include/asm-ia64/pgalloc.h

Next file: linux-2.4.21/include/asm-ia64/pgtable.h
Previous file: linux-2.4.21/include/asm-ia64/perfmon.h
Back to the patch index
Back to the overall index

diff -urN linux-2.4.20/include/asm-ia64/pgalloc.h linux-2.4.21/include/asm-ia64/pgalloc.h
@@ -157,29 +157,44 @@
  * Flush everything (kernel mapping may also have changed due to
  * vmalloc/vfree).
  */
-extern void __flush_tlb_all (void);
+extern void local_flush_tlb_all (void);
 
 #ifdef CONFIG_SMP
   extern void smp_flush_tlb_all (void);
+  extern void smp_flush_tlb_mm (struct mm_struct *mm);
 # define flush_tlb_all()	smp_flush_tlb_all()
 #else
-# define flush_tlb_all()	__flush_tlb_all()
+# define flush_tlb_all()	local_flush_tlb_all()
 #endif
 
+static inline void
+local_flush_tlb_mm (struct mm_struct *mm)
+{
+	if (mm == current->active_mm)
+		activate_context(mm);
+}
+
 /*
- * Flush a specified user mapping
+ * Flush a specified user mapping.  This is called, e.g., as a result of fork() and
+ * exit().  fork() ends up here because the copy-on-write mechanism needs to write-protect
+ * the PTEs of the parent task.
  */
 static inline void
 flush_tlb_mm (struct mm_struct *mm)
 {
-	if (mm) {
-		mm->context = 0;
-		if (mm == current->active_mm) {
-			/* This is called, e.g., as a result of exec().  */
-			get_new_mmu_context(mm);
-			reload_context(mm);
-		}
-	}
+	if (!mm)
+		return;
+
+	mm->context = 0;
+
+	if (atomic_read(&mm->mm_users) == 0)
+		return;		/* happens as a result of exit_mmap() */
+
+#ifdef CONFIG_SMP
+	smp_flush_tlb_mm(mm);
+#else
+	local_flush_tlb_mm(mm);
+#endif
 }
 
 extern void flush_tlb_range (struct mm_struct *mm, unsigned long start, unsigned long end);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)