Change the High FP lock from a sleep lock to a spin lock. We can

take the lock from interrupt context, which causes an implicit
lock order reversal. We've been using the lock carefully enough
that making it a spin lock should not be harmful.
This commit is contained in:
Marcel Moolenaar 2005-09-09 19:18:36 +00:00
parent 628bcb899b
commit 87a59250b5
4 changed files with 16 additions and 16 deletions

View File

@ -209,11 +209,11 @@ interrupt(u_int64_t vector, struct trapframe *tf)
} else if (vector == ipi_vector[IPI_HIGH_FP]) {
struct thread *thr = PCPU_GET(fpcurthread);
if (thr != NULL) {
mtx_lock(&thr->td_md.md_highfp_mtx);
mtx_lock_spin(&thr->td_md.md_highfp_mtx);
save_high_fp(&thr->td_pcb->pcb_high_fp);
thr->td_pcb->pcb_fpcpu = NULL;
PCPU_SET(fpcurthread, NULL);
mtx_unlock(&thr->td_md.md_highfp_mtx);
mtx_unlock_spin(&thr->td_md.md_highfp_mtx);
}
} else if (vector == ipi_vector[IPI_RENDEZVOUS]) {
rdvs[PCPU_GET(cpuid)]++;

View File

@ -1437,17 +1437,17 @@ ia64_highfp_drop(struct thread *td)
struct pcpu *cpu;
struct thread *thr;
mtx_lock(&td->td_md.md_highfp_mtx);
mtx_lock_spin(&td->td_md.md_highfp_mtx);
pcb = td->td_pcb;
cpu = pcb->pcb_fpcpu;
if (cpu == NULL) {
mtx_unlock(&td->td_md.md_highfp_mtx);
mtx_unlock_spin(&td->td_md.md_highfp_mtx);
return (0);
}
pcb->pcb_fpcpu = NULL;
thr = cpu->pc_fpcurthread;
cpu->pc_fpcurthread = NULL;
mtx_unlock(&td->td_md.md_highfp_mtx);
mtx_unlock_spin(&td->td_md.md_highfp_mtx);
/* Post-mortem sanity checking. */
KASSERT(thr == td, ("Inconsistent high FP state"));
@ -1465,18 +1465,18 @@ ia64_highfp_save(struct thread *td)
if ((td->td_frame->tf_special.psr & IA64_PSR_MFH) == 0)
return (ia64_highfp_drop(td));
mtx_lock(&td->td_md.md_highfp_mtx);
mtx_lock_spin(&td->td_md.md_highfp_mtx);
pcb = td->td_pcb;
cpu = pcb->pcb_fpcpu;
if (cpu == NULL) {
mtx_unlock(&td->td_md.md_highfp_mtx);
mtx_unlock_spin(&td->td_md.md_highfp_mtx);
return (0);
}
#ifdef SMP
if (td == curthread)
sched_pin();
if (cpu != pcpup) {
mtx_unlock(&td->td_md.md_highfp_mtx);
mtx_unlock_spin(&td->td_md.md_highfp_mtx);
ipi_send(cpu, IPI_HIGH_FP);
if (td == curthread)
sched_unpin();
@ -1494,7 +1494,7 @@ ia64_highfp_save(struct thread *td)
pcb->pcb_fpcpu = NULL;
thr = cpu->pc_fpcurthread;
cpu->pc_fpcurthread = NULL;
mtx_unlock(&td->td_md.md_highfp_mtx);
mtx_unlock_spin(&td->td_md.md_highfp_mtx);
/* Post-mortem sanity cxhecking. */
KASSERT(thr == td, ("Inconsistent high FP state"));

View File

@ -647,26 +647,26 @@ trap(int vector, struct trapframe *tf)
sched_unpin();
goto out;
} else if (thr != NULL) {
mtx_lock(&thr->td_md.md_highfp_mtx);
mtx_lock_spin(&thr->td_md.md_highfp_mtx);
pcb = thr->td_pcb;
save_high_fp(&pcb->pcb_high_fp);
pcb->pcb_fpcpu = NULL;
PCPU_SET(fpcurthread, NULL);
mtx_unlock(&thr->td_md.md_highfp_mtx);
mtx_unlock_spin(&thr->td_md.md_highfp_mtx);
thr = NULL;
}
mtx_lock(&td->td_md.md_highfp_mtx);
mtx_lock_spin(&td->td_md.md_highfp_mtx);
pcb = td->td_pcb;
pcpu = pcb->pcb_fpcpu;
#ifdef SMP
if (pcpu != NULL) {
mtx_unlock(&td->td_md.md_highfp_mtx);
mtx_unlock_spin(&td->td_md.md_highfp_mtx);
ipi_send(pcpu, IPI_HIGH_FP);
while (pcb->pcb_fpcpu == pcpu)
DELAY(100);
mtx_lock(&td->td_md.md_highfp_mtx);
mtx_lock_spin(&td->td_md.md_highfp_mtx);
pcpu = pcb->pcb_fpcpu;
thr = PCPU_GET(fpcurthread);
}
@ -680,7 +680,7 @@ trap(int vector, struct trapframe *tf)
tf->tf_special.psr &= ~IA64_PSR_DFH;
}
mtx_unlock(&td->td_md.md_highfp_mtx);
mtx_unlock_spin(&td->td_md.md_highfp_mtx);
sched_unpin();
goto out;
}

View File

@ -118,7 +118,7 @@ cpu_thread_setup(struct thread *td)
sp -= sizeof(struct trapframe);
td->td_frame = (struct trapframe *)sp;
td->td_frame->tf_length = sizeof(struct trapframe);
mtx_init(&td->td_md.md_highfp_mtx, "High FP lock", NULL, MTX_DEF);
mtx_init(&td->td_md.md_highfp_mtx, "High FP lock", NULL, MTX_SPIN);
}
void