patch-2.3.40 linux/arch/sparc/mm/sun4c.c

Next file: linux/arch/sparc/mm/viking.S
Previous file: linux/arch/sparc/mm/srmmu.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.39/linux/arch/sparc/mm/sun4c.c linux/arch/sparc/mm/sun4c.c
@@ -1,4 +1,4 @@
-/* $Id: sun4c.c,v 1.183 2000/01/08 16:38:20 anton Exp $
+/* $Id: sun4c.c,v 1.185 2000/01/15 00:51:32 anton Exp $
  * sun4c.c: Doing in software what should be done in hardware.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -1148,21 +1148,23 @@
 	unsigned long pages = BUCKET_PTE_PAGE(sun4c_get_pte(tsaddr));
 	int entry = BUCKET_NUM(tsaddr);
 
-	/* We are deleting a mapping, so the flush here is mandatory. */
-	sun4c_flush_page_hw(tsaddr);
+	if (atomic_dec_and_test(&(tsk)->thread.refcount)) {
+		/* We are deleting a mapping, so the flush here is mandatory. */
+		sun4c_flush_page_hw(tsaddr);
 #ifndef CONFIG_SUN4	
-	sun4c_flush_page_hw(tsaddr + PAGE_SIZE);
+		sun4c_flush_page_hw(tsaddr + PAGE_SIZE);
 #endif
-	sun4c_put_pte(tsaddr, 0);
+		sun4c_put_pte(tsaddr, 0);
 #ifndef CONFIG_SUN4	
-	sun4c_put_pte(tsaddr + PAGE_SIZE, 0);
+		sun4c_put_pte(tsaddr + PAGE_SIZE, 0);
 #endif
-	sun4c_bucket[entry] = BUCKET_EMPTY;
-	if (entry < sun4c_lowbucket_avail)
-		sun4c_lowbucket_avail = entry;
+		sun4c_bucket[entry] = BUCKET_EMPTY;
+		if (entry < sun4c_lowbucket_avail)
+			sun4c_lowbucket_avail = entry;
 
-	free_pages(pages, TASK_STRUCT_ORDER);
-	garbage_collect(entry);
+		free_pages(pages, TASK_STRUCT_ORDER);
+		garbage_collect(entry);
+	}
 }
 
 static void sun4c_free_task_struct_sw(struct task_struct *tsk)
@@ -1171,21 +1173,28 @@
 	unsigned long pages = BUCKET_PTE_PAGE(sun4c_get_pte(tsaddr));
 	int entry = BUCKET_NUM(tsaddr);
 
-	/* We are deleting a mapping, so the flush here is mandatory. */
-	sun4c_flush_page_sw(tsaddr);
+	if (atomic_dec_and_test(&(tsk)->thread.refcount)) {
+		/* We are deleting a mapping, so the flush here is mandatory. */
+		sun4c_flush_page_sw(tsaddr);
 #ifndef CONFIG_SUN4	
-	sun4c_flush_page_sw(tsaddr + PAGE_SIZE);
+		sun4c_flush_page_sw(tsaddr + PAGE_SIZE);
 #endif
-	sun4c_put_pte(tsaddr, 0);
+		sun4c_put_pte(tsaddr, 0);
 #ifndef CONFIG_SUN4	
-	sun4c_put_pte(tsaddr + PAGE_SIZE, 0);
+		sun4c_put_pte(tsaddr + PAGE_SIZE, 0);
 #endif
-	sun4c_bucket[entry] = BUCKET_EMPTY;
-	if (entry < sun4c_lowbucket_avail)
-		sun4c_lowbucket_avail = entry;
+		sun4c_bucket[entry] = BUCKET_EMPTY;
+		if (entry < sun4c_lowbucket_avail)
+			sun4c_lowbucket_avail = entry;
 
-	free_pages(pages, TASK_STRUCT_ORDER);
-	garbage_collect(entry);
+		free_pages(pages, TASK_STRUCT_ORDER);
+		garbage_collect(entry);
+	}
+}
+
+static void sun4c_get_task_struct(struct task_struct *tsk)
+{
+		atomic_inc(&(tsk)->thread.refcount);
 }
 
 static void __init sun4c_init_buckets(void)
@@ -1554,13 +1563,12 @@
 	}
 }
 
-static void sun4c_flush_page_to_ram_hw(struct page *page)
+static void sun4c_flush_page_to_ram_hw(unsigned long page)
 {
 	unsigned long flags;
-	unsigned long addr = page_address(page);
 
 	save_and_cli(flags);
-	sun4c_flush_page_hw(addr);
+	sun4c_flush_page_hw(page);
 	restore_flags(flags);
 }
 
@@ -1677,13 +1685,12 @@
 	}
 }
 
-static void sun4c_flush_page_to_ram_sw(struct page *page)
+static void sun4c_flush_page_to_ram_sw(unsigned long page)
 {
 	unsigned long flags;
-	unsigned long addr = page_address(page);
 
 	save_and_cli(flags);
-	sun4c_flush_page_sw(addr);
+	sun4c_flush_page_sw(page);
 	restore_flags(flags);
 }
 
@@ -2629,7 +2636,7 @@
 		BTFIXUPSET_CALL(flush_cache_mm, sun4c_flush_cache_mm_hw, BTFIXUPCALL_NORM);
 		BTFIXUPSET_CALL(flush_cache_range, sun4c_flush_cache_range_hw, BTFIXUPCALL_NORM);
 		BTFIXUPSET_CALL(flush_cache_page, sun4c_flush_cache_page_hw, BTFIXUPCALL_NORM);
-		BTFIXUPSET_CALL(flush_page_to_ram, sun4c_flush_page_to_ram_hw, BTFIXUPCALL_NORM);
+		BTFIXUPSET_CALL(__flush_page_to_ram, sun4c_flush_page_to_ram_hw, BTFIXUPCALL_NORM);
 		BTFIXUPSET_CALL(flush_tlb_mm, sun4c_flush_tlb_mm_hw, BTFIXUPCALL_NORM);
 		BTFIXUPSET_CALL(flush_tlb_range, sun4c_flush_tlb_range_hw, BTFIXUPCALL_NORM);
 		BTFIXUPSET_CALL(flush_tlb_page, sun4c_flush_tlb_page_hw, BTFIXUPCALL_NORM);
@@ -2640,7 +2647,7 @@
 		BTFIXUPSET_CALL(flush_cache_mm, sun4c_flush_cache_mm_sw, BTFIXUPCALL_NORM);
 		BTFIXUPSET_CALL(flush_cache_range, sun4c_flush_cache_range_sw, BTFIXUPCALL_NORM);
 		BTFIXUPSET_CALL(flush_cache_page, sun4c_flush_cache_page_sw, BTFIXUPCALL_NORM);
-		BTFIXUPSET_CALL(flush_page_to_ram, sun4c_flush_page_to_ram_sw, BTFIXUPCALL_NORM);
+		BTFIXUPSET_CALL(__flush_page_to_ram, sun4c_flush_page_to_ram_sw, BTFIXUPCALL_NORM);
 		BTFIXUPSET_CALL(flush_tlb_mm, sun4c_flush_tlb_mm_sw, BTFIXUPCALL_NORM);
 		BTFIXUPSET_CALL(flush_tlb_range, sun4c_flush_tlb_range_sw, BTFIXUPCALL_NORM);
 		BTFIXUPSET_CALL(flush_tlb_page, sun4c_flush_tlb_page_sw, BTFIXUPCALL_NORM);
@@ -2719,6 +2726,7 @@
 
 	/* Task struct and kernel stack allocating/freeing. */
 	BTFIXUPSET_CALL(alloc_task_struct, sun4c_alloc_task_struct, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(get_task_struct, sun4c_get_task_struct, BTFIXUPCALL_NORM);
 
 	BTFIXUPSET_CALL(quick_kernel_fault, sun4c_quick_kernel_fault, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(mmu_info, sun4c_mmu_info, BTFIXUPCALL_NORM);

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