Port-powerpc archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

powerpc/booke MULTIPROCESSOR



Hi,

TWR-P1025 works with multi-processor now.

However, the attached patch is still necessary.
The patch will resolve the conflict of PTE update and TLB miss walk.
If do not apply it, check fails that PTE and TLB are matched.
-----
panic: kernel diagnostic assertion "pte == xpte" failed: file
"/usr/src/sys/arch/powerpc/booke/booke_pmap.c", line 423 pm=0x1fd9ce00
va=0xefc34000 asid=22: TLB pte (0x1f878144) != real pte
(0x1f878044/0x1f878044)
-----

If there is no objection, I'll commit it at next week.

Regards,
-- 
NONAKA Kimihiro
Index: sys/arch/powerpc/booke/booke_pmap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/booke/booke_pmap.c,v
retrieving revision 1.21
diff -u -r1.21 booke_pmap.c
--- sys/arch/powerpc/booke/booke_pmap.c	23 Jan 2015 06:39:41 -0000	1.21
+++ sys/arch/powerpc/booke/booke_pmap.c	23 Jan 2015 09:08:03 -0000
@@ -43,11 +43,16 @@
 #include <sys/param.h>
 #include <sys/kcore.h>
 #include <sys/buf.h>
+#include <sys/mutex.h>
 
 #include <uvm/uvm.h>
 
 #include <machine/pmap.h>
 
+#if defined(MULTIPROCESSOR)
+kmutex_t pmap_tlb_miss_lock;
+#endif
+
 /*
  * Initialize the kernel pmap.
  */
@@ -166,6 +171,10 @@
 	/* init the lock */
 	pmap_tlb_info_init(&pmap_tlb0_info);
 
+#if defined(MULTIPROCESSOR)
+	mutex_init(&pmap_tlb_miss_lock, MUTEX_SPIN, IPL_HIGH);
+#endif
+
 	/*
 	 * Compute the number of pages kmem_arena will have.
 	 */
@@ -427,4 +436,18 @@
 {
 	/* nothing */
 }
+
+void
+pmap_md_tlb_miss_lock_enter(void)
+{
+
+	mutex_spin_enter(&pmap_tlb_miss_lock);
+}
+
+void
+pmap_md_tlb_miss_lock_exit(void)
+{
+
+	mutex_spin_exit(&pmap_tlb_miss_lock);
+}
 #endif /* MULTIPROCESSOR */
Index: sys/arch/powerpc/booke/genassym.cf
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/booke/genassym.cf,v
retrieving revision 1.10
diff -u -r1.10 genassym.cf
--- sys/arch/powerpc/booke/genassym.cf	27 Nov 2012 19:24:46 -0000	1.10
+++ sys/arch/powerpc/booke/genassym.cf	23 Jan 2015 09:08:03 -0000
@@ -111,4 +111,7 @@
 define	HATCH_TBU		offsetof(struct cpu_hatch_data, hatch_tbu)
 define	HATCH_TBL		offsetof(struct cpu_hatch_data, hatch_tbl)
 define	HATCH_TLBIDX		offsetof(struct cpu_hatch_data, hatch_tlbidx)
+
+define	__SIMPLELOCK_LOCKED	__SIMPLELOCK_LOCKED
+define	__SIMPLELOCK_UNLOCKED	__SIMPLELOCK_UNLOCKED
 endif
Index: sys/arch/powerpc/booke/trap_subr.S
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/booke/trap_subr.S,v
retrieving revision 1.11
diff -u -r1.11 trap_subr.S
--- sys/arch/powerpc/booke/trap_subr.S	18 Sep 2014 23:37:51 -0000	1.11
+++ sys/arch/powerpc/booke/trap_subr.S	23 Jan 2015 09:08:03 -0000
@@ -346,6 +346,50 @@
 	RESTORE_SPRG1(%r6);	\
 	FRAME_INTR_XEXIT(rfci, CSRR)
 
+#if defined(MULTIPROCESSOR)
+#define	FRAME_TLBMISSLOCK						\
+	GET_CPUINFO(%r23);						\
+	ldint	%r22, CI_MTX_COUNT(%r23);				\
+	subi	%r22, %r22, 1;						\
+	stint	%r22, CI_MTX_COUNT(%r23);				\
+	isync;								\
+	cmpwi	%r22, 0;						\
+	bne	1f;							\
+	ldint	%r22, CI_CPL(%r23);					\
+	stint	%r22, CI_MTX_OLDSPL(%r23);				\
+1:	lis	%r23, _C_LABEL(pmap_tlb_miss_lock)@h;			\
+	ori	%r23, %r23, _C_LABEL(pmap_tlb_miss_lock)@l;		\
+	li	%r20, MTX_LOCK;						\
+2:	lwarx	%r22, %r20, %r23;					\
+	cmpwi	%r22, __SIMPLELOCK_UNLOCKED;				\
+	beq+	4f;							\
+3:	lwzx	%r22, %r20, %r23;					\
+	cmpwi	%r22, __SIMPLELOCK_UNLOCKED;				\
+	beq+	2b;							\
+	b	3b;							\
+4:	li	%r21, __SIMPLELOCK_LOCKED;				\
+	stwcx.	%r21, %r20, %r23;					\
+	bne-	2b;							\
+	isync;								\
+	msync;
+#define	FRAME_TLBMISSUNLOCK						\
+	sync;								\
+	lis	%r23, _C_LABEL(pmap_tlb_miss_lock)@h;			\
+	ori	%r23, %r23, _C_LABEL(pmap_tlb_miss_lock)@l;		\
+	li	%r22, __SIMPLELOCK_UNLOCKED;				\
+	stw	%r22, MTX_LOCK(%r23);					\
+	isync;								\
+	msync;								\
+	GET_CPUINFO(%r23);						\
+	ldint	%r22, CI_MTX_COUNT(%r23);				\
+	addi	%r22, %r22, 1;						\
+	stint	%r22, CI_MTX_COUNT(%r23);				\
+	isync;
+#else	/* !MULTIPROCESSOR */
+#define	FRAME_TLBMISSLOCK
+#define	FRAME_TLBMISSUNLOCK
+#endif	/* MULTIPROCESSOR */
+
 	.text
 	.p2align 4
 _C_LABEL(critical_input_vector):
@@ -535,6 +579,7 @@
 _C_LABEL(data_tlb_error_vector):
 	/* MSR[CE], MSR[ME], MSR[DE] are unchanged, all others cleared */
 	FRAME_TLBPROLOGUE
+	FRAME_TLBMISSLOCK
 	/*
 	 * Registers as this point:
 	 *
@@ -577,6 +622,7 @@
 		31-PTR_SCALESHIFT, \
 		31-PTR_SCALESHIFT		/* move PSL_DS[27] to bit 29 */
 	bl	pte_load
+	FRAME_TLBMISSUNLOCK
 	mtlr	%r29				/* restore LR */
 	/*
 	 * If we returned, pte load failed so let trap deal with it but
@@ -590,6 +636,7 @@
 _C_LABEL(instruction_tlb_error_vector):
 	/* MSR[CE], MSR[ME], MSR[DE] are unchanged, all others cleared */
 	FRAME_TLBPROLOGUE
+	FRAME_TLBMISSLOCK
 	/*
 	 * Attempt to update the TLB from the page table.
 	 */
@@ -600,6 +647,7 @@
 		31-PTR_SCALESHIFT, \
 		31-PTR_SCALESHIFT		/* move PSL_IS[26] to bit 29 */
 	bl	pte_load
+	FRAME_TLBMISSUNLOCK
 	mtlr	%r29				/* restore LR */
 	/*
 	 * If we returned, pte load failed so let trap deal with it but
@@ -764,6 +812,9 @@
 	addic	%r31, %r31, 1
 	addze	%r30, %r30
 	stmw	%r30, CI_EV_TLBMISS_SOFT(%r2)
+
+	FRAME_TLBMISSUNLOCK
+
 	/*
 	 * Cleanup and leave.  We know any higher priority exception will
 	 * save and restore SPRG1 and %r2 thereby preserving their values.
Index: sys/arch/powerpc/include/booke/pmap.h
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/include/booke/pmap.h,v
retrieving revision 1.14
diff -u -r1.14 pmap.h
--- sys/arch/powerpc/include/booke/pmap.h	3 Apr 2014 13:55:34 -0000	1.14
+++ sys/arch/powerpc/include/booke/pmap.h	23 Jan 2015 09:08:03 -0000
@@ -92,6 +92,12 @@
 
 bool	pmap_md_tlb_check_entry(void *, vaddr_t, tlb_asid_t, pt_entry_t);
 
+#ifdef MULTIPROCESSOR
+#define	PMAP_MD_NEED_TLB_MISS_LOCK
+void	pmap_md_tlb_miss_lock_enter(void);
+void	pmap_md_tlb_miss_lock_exit(void);
+#endif	/* MULTIPROCESSOR */
+
 #ifdef PMAP_MINIMALTLB
 vaddr_t	pmap_kvptefill(vaddr_t, vaddr_t, pt_entry_t);
 #endif
Index: sys/uvm/pmap/pmap.c
===================================================================
RCS file: /cvsroot/src/sys/uvm/pmap/pmap.c,v
retrieving revision 1.9
diff -u -r1.9 pmap.c
--- sys/uvm/pmap/pmap.c	5 Jan 2015 05:35:18 -0000	1.9
+++ sys/uvm/pmap/pmap.c	23 Jan 2015 09:08:03 -0000
@@ -263,6 +263,11 @@
 #define	pmap_pv_alloc()		pool_get(&pmap_pv_pool, PR_NOWAIT)
 #define	pmap_pv_free(pv)	pool_put(&pmap_pv_pool, (pv))
 
+#if !defined(MULTIPROCESSOR) || !defined(PMAP_MD_NEED_TLB_MISS_LOCK)
+#define	pmap_md_tlb_miss_lock_enter()	do { } while(/*CONSTCOND*/0)
+#define	pmap_md_tlb_miss_lock_exit()	do { } while(/*CONSTCOND*/0)
+#endif	/* !MULTIPROCESSOR || !PMAP_MD_NEED_TLB_MISS_LOCK */
+
 /*
  * Misc. functions.
  */
@@ -541,8 +546,10 @@
 	KASSERT(pmap->pm_count == 0);
 	PMAP_COUNT(destroy);
 	kpreempt_disable();
+	pmap_md_tlb_miss_lock_enter();
 	pmap_tlb_asid_release_all(pmap);
 	pmap_segtab_destroy(pmap, NULL, 0);
+	pmap_md_tlb_miss_lock_exit();
 
 #ifdef MULTIPROCESSOR
 	kcpuset_destroy(pmap->pm_active);
@@ -586,10 +593,12 @@
 	PMAP_COUNT(activate);
 
 	kpreempt_disable();
+	pmap_md_tlb_miss_lock_enter();
 	pmap_tlb_asid_acquire(pmap, l);
 	if (l == curlwp) {
 		pmap_segtab_activate(pmap, l);
 	}
+	pmap_md_tlb_miss_lock_exit();
 	kpreempt_enable();
 
 	UVMHIST_LOG(pmaphist, "<- done", 0,0,0,0);
@@ -608,8 +617,10 @@
 	PMAP_COUNT(deactivate);
 
 	kpreempt_disable();
+	pmap_md_tlb_miss_lock_enter();
 	curcpu()->ci_pmap_user_segtab = PMAP_INVALID_SEGTAB_ADDRESS;
 	pmap_tlb_asid_deactivate(pmap);
+	pmap_md_tlb_miss_lock_exit();
 	kpreempt_enable();
 
 	UVMHIST_LOG(pmaphist, "<- done", 0,0,0,0);
@@ -629,6 +640,7 @@
 	if (pending && pmap_tlb_shootdown_bystanders(pmap))
 		PMAP_COUNT(shootdown_ipis);
 #endif
+	pmap_md_tlb_miss_lock_enter();
 #ifdef DEBUG
 	pmap_tlb_check(pmap, pmap_md_tlb_check_entry);
 #endif /* DEBUG */
@@ -642,6 +654,7 @@
 		pmap_tlb_asid_acquire(pmap, curlwp);
 		pmap_segtab_activate(pmap, curlwp);
 	}
+	pmap_md_tlb_miss_lock_exit();
 	kpreempt_enable();
 
 	UVMHIST_LOG(pmaphist, "<- done", 0,0,0,0);
@@ -685,11 +698,13 @@
 			pmap_remove_pv(pmap, sva, pg,
 			   pte_modified_p(pt_entry));
 		}
+		pmap_md_tlb_miss_lock_enter();
 		*ptep = npte;
 		/*
 		 * Flush the TLB for the given address.
 		 */
 		pmap_tlb_invalidate_addr(pmap, sva);
+		pmap_md_tlb_miss_lock_exit();
 	}
 	return false;
 }
@@ -843,12 +858,14 @@
 		}
 		pt_entry = pte_prot_downgrade(pt_entry, prot);
 		if (*ptep != pt_entry) {
+			pmap_md_tlb_miss_lock_enter();
 			*ptep = pt_entry;
 			/*
 			 * Update the TLB if needed.
 			 */
 			pmap_tlb_update_addr(pmap, sva, pt_entry,
 			    PMAP_TLB_NEED_IPI);
+			pmap_md_tlb_miss_lock_exit();
 		}
 	}
 	return false;
@@ -937,9 +954,11 @@
 		pt_entry_t pt_entry = *ptep;
 		if (pte_valid_p(pt_entry)) {
 			pt_entry = pte_cached_change(pt_entry, cached);
+			pmap_md_tlb_miss_lock_enter();
 			*ptep = pt_entry;
 			pmap_tlb_update_addr(pmap, va, pt_entry,
 			    PMAP_TLB_NEED_IPI);
+			pmap_md_tlb_miss_lock_exit();
 		}
 	}
 	UVMHIST_LOG(pmaphist, "<- done", 0,0,0,0);
@@ -1060,11 +1079,13 @@
 	bool resident = pte_valid_p(opte);
 	if (!resident)
 		pmap->pm_stats.resident_count++;
+	pmap_md_tlb_miss_lock_enter();
 	*ptep = npte;
 
 	pmap_tlb_update_addr(pmap, va, npte,
 	    ((flags & VM_PROT_ALL) ? PMAP_TLB_INSERT : 0)
 	    | (resident ? PMAP_TLB_NEED_IPI : 0));
+	pmap_md_tlb_miss_lock_exit();
 	kpreempt_enable();
 
 	if (pg != NULL && (prot == (VM_PROT_READ | VM_PROT_EXECUTE))) {
@@ -1138,12 +1159,14 @@
 	pt_entry_t * const ptep = pmap_pte_reserve(pmap_kernel(), va, 0);
 	KASSERT(ptep != NULL);
 	KASSERT(!pte_valid_p(*ptep));
+	pmap_md_tlb_miss_lock_enter();
 	*ptep = npte;
 	/*
 	 * We have the option to force this mapping into the TLB but we
 	 * don't.  Instead let the next reference to the page do it.
 	 */
 	pmap_tlb_update_addr(pmap_kernel(), va, npte, 0);
+	pmap_md_tlb_miss_lock_exit();
 	kpreempt_enable();
 #if DEBUG > 1
 	for (u_int i = 0; i < PAGE_SIZE / sizeof(long); i++) {
@@ -1179,8 +1202,10 @@
 		if (pg != NULL)
 			pmap_md_vca_clean(pg, sva, PMAP_WBINV);
 
+		pmap_md_tlb_miss_lock_enter();
 		*ptep = new_pt_entry;
 		pmap_tlb_invalidate_addr(pmap_kernel(), sva);
+		pmap_md_tlb_miss_lock_exit();
 	}
 
 	return false;
@@ -1213,8 +1238,10 @@
 	 * Free all of our ASIDs which means we can skip doing all the
 	 * tlb_invalidate_addrs().
 	 */
+	pmap_md_tlb_miss_lock_enter();
 	pmap_tlb_asid_deactivate(pmap);
 	pmap_tlb_asid_release_all(pmap);
+	pmap_md_tlb_miss_lock_exit();
 	pmap->pm_flags |= PMAP_DEFERRED_ACTIVATE;
 
 	kpreempt_enable();
@@ -1258,7 +1285,9 @@
 #endif
 
 	if (pte_wired_p(pt_entry)) {
+		pmap_md_tlb_miss_lock_enter();
 		*ptep = pte_unwire_entry(*ptep);
+		pmap_md_tlb_miss_lock_exit();
 		pmap->pm_stats.wired_count--;
 	}
 #ifdef DIAGNOSTIC
@@ -1421,9 +1450,11 @@
 			continue;
 		}
 		pmap_md_vca_clean(pg, va, PMAP_WBINV);
+		pmap_md_tlb_miss_lock_enter();
 		*ptep = pt_entry;
 		VM_PAGEMD_PVLIST_UNLOCK(mdpg);
 		pmap_tlb_invalidate_addr(pmap, va);
+		pmap_md_tlb_miss_lock_exit();
 		pmap_update(pmap);
 		if (__predict_false(gen != VM_PAGEMD_PVLIST_LOCK(mdpg, false))) {
 			/*

Attachment: TWR-P1025.MP-boot.log
Description: Binary data



Home | Main Index | Thread Index | Old Index