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:
parent
628bcb899b
commit
87a59250b5
@ -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)]++;
|
||||
|
@ -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"));
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user