patch-2.4.21 linux-2.4.21/arch/ppc64/kernel/pmc.c

Next file: linux-2.4.21/arch/ppc64/kernel/ppc_ksyms.c
Previous file: linux-2.4.21/arch/ppc64/kernel/perfmon.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.20/arch/ppc64/kernel/pmc.c linux-2.4.21/arch/ppc64/kernel/pmc.c
@@ -73,7 +73,8 @@
 struct mm_struct btmalloc_mm = {pgd             : bolted_dir,
                                 page_table_lock : SPIN_LOCK_UNLOCKED};
 
-extern spinlock_t hash_table_lock;
+extern spinlock_t hash_table_lock[];
+extern inline unsigned long get_lock_slot(unsigned long vpn);
 
 char *
 ppc64_pmc_stab(int file)
@@ -211,15 +212,14 @@
 	pgd_t *pgdp;
 	pmd_t *pmdp;
 	pte_t *ptep, pte;
-	unsigned long ea_base, ea, hpteflags;
+	unsigned long ea_base, ea, hpteflags, lock_slot;
 	struct vm_struct *area;
-	unsigned long pa, pg_count, page, vsid, slot, va, arpn, vpn;
+	unsigned long pa, pg_count, page, vsid, slot, va, rpn, vpn;
   
 	size = PAGE_ALIGN(size);
 	if (!size || (size >> PAGE_SHIFT) > num_physpages) return NULL;
 
 	spin_lock(&btmalloc_mm.page_table_lock);
-	spin_lock(&hash_table_lock);
 
 	/* Get a virtual address region in the bolted space */
 	area = get_btm_area(size, 0);
@@ -236,10 +236,12 @@
 		pa = get_free_page(GFP_KERNEL) - PAGE_OFFSET; 
 		ea = ea_base + (page * PAGE_SIZE);
 		vsid = get_kernel_vsid(ea);
-		va = ( vsid << 28 ) | ( pa & 0xfffffff );
+		va = ( vsid << 28 ) | ( ea & 0xfffffff );
 		vpn = va >> PAGE_SHIFT;
-		arpn = ((unsigned long)__v2a(ea)) >> PAGE_SHIFT;
+		lock_slot = get_lock_slot(vpn); 
+		rpn = pa >> PAGE_SHIFT;
 
+		spin_lock(&hash_table_lock[lock_slot].lock);
 		/* Get a pointer to the linux page table entry for this page
 		 * allocating pmd or pte pages along the way as needed.  Note
 		 * that the pmd & pte pages are not themselfs bolted.
@@ -257,13 +259,16 @@
 		pte_val(pte) &= ~_PAGE_HPTEFLAGS;
 		pte_val(pte) |= _PAGE_HASHPTE;
 
-		slot = ppc_md.hpte_insert(vpn, arpn, hpteflags, 1, 0);  
+		slot = ppc_md.hpte_insert(vpn, rpn, hpteflags, 1, 0);  
 
 		pte_val(pte) |= ((slot<<12) & 
 				 (_PAGE_GROUP_IX | _PAGE_SECONDARY));
+
+		*ptep = pte;
+
+		spin_unlock(&hash_table_lock[lock_slot].lock);
 	}
 
-	spin_unlock(&hash_table_lock);
 	spin_unlock(&btmalloc_mm.page_table_lock);
 	return (void*)ea_base;
 }

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