From 87a59250b5573d770a785f8e915982d304f20172 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Fri, 9 Sep 2005 19:18:36 +0000 Subject: [PATCH] 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. --- sys/ia64/ia64/interrupt.c | 4 ++-- sys/ia64/ia64/machdep.c | 14 +++++++------- sys/ia64/ia64/trap.c | 12 ++++++------ sys/ia64/ia64/vm_machdep.c | 2 +- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/sys/ia64/ia64/interrupt.c b/sys/ia64/ia64/interrupt.c index 3e1a12ad4808..0c83d97117f2 100644 --- a/sys/ia64/ia64/interrupt.c +++ b/sys/ia64/ia64/interrupt.c @@ -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)]++; diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index 9aa6045d0a48..2baf57dd006c 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -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")); diff --git a/sys/ia64/ia64/trap.c b/sys/ia64/ia64/trap.c index fbb8e13785c1..d68482413912 100644 --- a/sys/ia64/ia64/trap.c +++ b/sys/ia64/ia64/trap.c @@ -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; } diff --git a/sys/ia64/ia64/vm_machdep.c b/sys/ia64/ia64/vm_machdep.c index 8ce6641a9950..c29e9d73fa3f 100644 --- a/sys/ia64/ia64/vm_machdep.c +++ b/sys/ia64/ia64/vm_machdep.c @@ -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