Fix the false IPIs on smp when using LAZY_SWITCH caused by pmap_activate()

not releasing the pm_active bit in the old pmap.
This commit is contained in:
peter 2003-06-27 21:50:52 +00:00
parent 546c8585af
commit 88fbf8d0cf
4 changed files with 18 additions and 9 deletions

View File

@ -201,6 +201,7 @@ ASSYM(PC_COMMON_TSSD, offsetof(struct pcpu, pc_common_tssd));
ASSYM(PC_TSS_GDT, offsetof(struct pcpu, pc_tss_gdt));
ASSYM(PC_CURRENTLDT, offsetof(struct pcpu, pc_currentldt));
ASSYM(PC_CPUID, offsetof(struct pcpu, pc_cpuid));
ASSYM(PC_CURPMAP, offsetof(struct pcpu, pc_curpmap));
#ifdef SMP
ASSYM(LA_VER, offsetof(struct LAPIC, version));

View File

@ -1073,6 +1073,7 @@ pmap_pinit0(pmap)
pmap->pm_pdpt = (pdpt_entry_t *)(KERNBASE + (vm_offset_t)IdlePDPT);
#endif
pmap->pm_active = 0;
PCPU_SET(curpmap, pmap);
TAILQ_INIT(&pmap->pm_pvlist);
bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
mtx_lock_spin(&allpmaps_lock);
@ -3240,14 +3241,17 @@ void
pmap_activate(struct thread *td)
{
struct proc *p = td->td_proc;
pmap_t pmap;
pmap_t pmap, oldpmap;
u_int32_t cr3;
critical_enter();
pmap = vmspace_pmap(td->td_proc->p_vmspace);
oldpmap = PCPU_GET(curpmap);
#if defined(SMP)
atomic_clear_int(&oldpmap->pm_active, PCPU_GET(cpumask));
atomic_set_int(&pmap->pm_active, PCPU_GET(cpumask));
#else
oldpmap->pm_active &= ~1;
pmap->pm_active |= 1;
#endif
#ifdef PAE
@ -3271,6 +3275,7 @@ pmap_activate(struct thread *td)
#ifdef SWTCH_OPTIM_STATS
tlb_flush_count++;
#endif
PCPU_SET(curpmap, pmap);
critical_exit();
}

View File

@ -67,12 +67,11 @@ ENTRY(cpu_throw)
testl %ecx,%ecx /* no thread? */
jz 1f
/* release bit from old pm_active */
movl TD_PROC(%ecx), %eax /* thread->td_proc */
movl P_VMSPACE(%eax), %ebx /* proc->p_vmspace */
movl PCPU(CURPMAP), %ebx
#ifdef SMP
lock
#endif
btrl %esi, VM_PMAP+PM_ACTIVE(%ebx) /* clear old */
btrl %esi, PM_ACTIVE(%ebx) /* clear old */
1:
movl 8(%esp),%ecx /* New thread */
movl TD_PCB(%ecx),%edx
@ -84,10 +83,12 @@ ENTRY(cpu_throw)
/* set bit in new pm_active */
movl TD_PROC(%ecx),%eax
movl P_VMSPACE(%eax), %ebx
addl $VM_PMAP, %ebx
movl %ebx, PCPU(CURPMAP)
#ifdef SMP
lock
#endif
btsl %esi, VM_PMAP+PM_ACTIVE(%ebx) /* set new */
btsl %esi, PM_ACTIVE(%ebx) /* set new */
jmp sw1
/*
@ -188,20 +189,21 @@ ENTRY(cpu_switch)
movl %eax,%cr3 /* new address space */
/* Release bit from old pmap->pm_active */
movl TD_PROC(%edi), %eax /* oldproc */
movl P_VMSPACE(%eax), %ebx
movl PCPU(CURPMAP), %ebx
#ifdef SMP
lock
#endif
btrl %esi, VM_PMAP+PM_ACTIVE(%ebx) /* clear old */
btrl %esi, PM_ACTIVE(%ebx) /* clear old */
/* Set bit in new pmap->pm_active */
movl TD_PROC(%ecx),%eax /* newproc */
movl P_VMSPACE(%eax), %ebx
addl $VM_PMAP, %ebx
movl %ebx, PCPU(CURPMAP)
#ifdef SMP
lock
#endif
btsl %esi, VM_PMAP+PM_ACTIVE(%ebx) /* set new */
btsl %esi, PM_ACTIVE(%ebx) /* set new */
#ifdef LAZY_SWITCH
#ifdef SWTCH_OPTIM_STATS

View File

@ -43,6 +43,7 @@
*/
#define PCPU_MD_FIELDS \
struct pcpu *pc_prvspace; /* Self-reference */ \
struct pmap *pc_curpmap; \
struct i386tss pc_common_tss; \
struct segment_descriptor pc_common_tssd; \
struct segment_descriptor *pc_tss_gdt; \